How to send EGLD value to smart contract endpoint? - smartcontracts

I have a smart contract method that looks like this:
#[payable("EGLD")]
#[endpoint(myEndpoint)]
fn my_endpoint(&self, #[payment_amount] payment: BigUint, some_value: u64) { ... }
And I call it with 5 EGLD value in transaction along with tx data
myEndpoint#05#aa
but tx result returns me wrong number of arguments.
What am I doing wrong?

Payment args in EGLD are auto-filled from the call value you've already specified in the transaction, so you do not need to pass them as argument.
Therefore, your call data in this case would be myEndpoint#aa, without the payment arg.
As a side note, if this would've been an endpoint accepting another token than EGLD, you would've had to specify the token and amount in the data field, like:
ESDTNFTTransfer#TokenIdentifier_in_hex#TokenNonce_in_hex#TokenValue_in_hex#Contract_address_in_hex#myEndpoint_in_hex#aa.
The ESDTNFTTransfer function sends any type of ESDT token, with or without nonce. If the token doesn't have a nonce (fungible), you can either pass 00 as nonce or leave the nonce space empty, like #TokenName_in_hex##TokenValue_in_hex.
Mind the fact that in order to use this function, you would have to compose a transaction with the destination set as yourself. The actual address of the destination would be contained in the data field in place ofContract_address_in_hex, making it a parameter of the ESDTNFTTransfer function.
If the endpoint accepted two tokens for example, then you could've used MultiESDTNFTTransfer#Contract_address_in_hex#02#Token1Identifier_in_hex#Token1Nonce_in_hex#Token1Value_in_hex#Token2Identifier_in_hex#Token2Nonce_in_hex#Token2Value_in_hex#myEndpoint_in_hex.
And yeah, you can always check the Elrond docs on ESDT Tokens / NFT Tokens for more details.

Related

References to IDs in APIs responses, null or 0?

I consider myself that 0 is not a good thing to do when returning information from an API
e.g.
{
userId: int|null
}
I have a colleague that insists in that userId should be 0 or -1, but that forces a system to know that the 0 means "not set", instead of null which is universally known as not set.
The same happens with string params, like logoUrl. However, in this case I think it is acceptable to have an empty string instead of null if the variable is not set or was unset.
Is there bibliography, standards, etc, that I can refer to?
I'm not aware of any standard around that, but the way I take those kind of decisions is by thinking about the way consumer services would read this response, the goal being to provide a very smooth and clean consuming workflow. This exercise can even be transformed into a documentation for your API consumers.
In your case, instead of returning a null/0 field, I would simply remove that field altogether when it's empty and let the consumers explicitly mark that field as optional in the model they use to deserialize this response.
In that way, they'll explicitly have to deal with those optional fields, than relying on the API to always provide a value for them.

Where to validate parameters sent to an API?

In which place is best practice to validate parameters sent by the user in an API design? By parameter validation I refer to: checking required params are sent, ensure they have correct format and so... Here are a couple of simple examples that validate an id has been sent. It is Python using Flask to illustrate:
A) Add validation logic in the route definition, within the controller.
#api.route('/job', methods=['GET'])
def get_jobs():
try:
if params["id"] is None:
raise Exception("Invalid param ID parameters.")
job = job_manager.get_job(params["id"])
return jsonify(job)
B) In the core of the app. This is the business layer, where logic is applied to transform data.
class JobManager:
def get_job(self, job_id) -> None:
if job_id is None:
raise Exception("Invalid param ID parameters.")
In more complex scenarios a validator service or decorators could be used, but the question would be the same: At which point of the code is best practice to validate a user's input.
If the answer is none of the scenarios above (or both), please provide more details on your answer. If possible, try to be language agnostic as I'm looking for a best practice that can be applied anywhere.
Parsing, as a rule, should happen at the point where information enters your system, or as close to that point as is practical.
Therefore certainly "application layer" rather than "domain layer/business layer": either invoked by the controller itself, or very close to it. (Not typically "in" the controller, because you should be able to test the parser without being coupled to a bunch of HTTP ceremony.)
#api.route('/job', methods=['GET'])
def get_jobs():
try:
job_id = parse_job_id(params["id"])
job = job_manager.get_job(job_id)
return jsonify(job)
In typed languages, this can make your life a lot easier, because you greatly reduce the number of places you have to ask "does this general purpose data structure have the information I expect?"
Checks against business policy, on the other hand, normally belong in the domain layer.
For example: if your API requires a date, the checks that the date is actually present, and that the date is represented in the appropriate ISO-8601 format, and so on... these kinds of checks all happen as part of the parsing of the input by the controller.
On the other hand, checking that the date is "in the future", or that the date is within warranty, or ... these are checks that belong in your domain code.
Generally, I split validation into phases:
Immediate syntax validation of input data in the REST controller
Business-logic validation in the services
The first validation should only flag things that are definitely wrong; e.g. missing required fields, type mismatch, unparsable strings, any attempts of code injection and the presence (or lack of) of security tokens.
When this validation passes, the input data is at least syntactically correct and may be passed on to the services, where a more strict validation occurs; i.e. does the input data make sense business-wise, does the resource with that ID exist - and so on.
Short version: The first validation looks for things that are obviously wrong, while the following validation ensures input data is correct and meaningful business-wise.

Why did this txn not transfer balance, I passed the exact same string same hex as response set in question

I called https://etherscan.io/address/0x0c63bf5f9c1b31bd98eb2995e8ab5ba33fe31d22 contract's Try function by passing the same string which was passed in Start function. I checked hex. Can someone help me why Try function call https://etherscan.io/tx/0x096a060d64d833c55fd83b2ea4ec209578dc3316d863de3a3de63692e8476628
did not initiate balance transfer. Is there something, I am missing
The Quiz is a scam contract
The authors usually use a set of similar names ([a-z]{2}_quiz), but most of them contain the same code and act as a honeypot scam.
Read more about it:
https://medium.com/coinmonks/do-not-be-fooled-by-crypto-quiz-games-f38f72a53c78
https://ethereum.stackexchange.com/questions/62815/trying-to-figure-out-this-2-eth-smart-contract-quiz
How the scam works:
The attacker uses internal call from another contract (that doesn't appear on the honeypot "transactions" or "internal calls" lists) to call the New() function and set the hash to some garbage value.
This garbage value is not the hash of the string passed in the Start() function and most probably not even a hash of any string.
Then publicly calls the Start() function (see transaction), so that it looks like they are setting the hash, but it's not set because of this condition:
if(responseHash==0x0){ // it's not 0x0 anymore
responseHash = keccak256(abi.encode(_response));
question = _question;
}

Redigo type of value returned from GET

I'd like to be able to GET a value of a key and immediately know what type it is. I'm using
res, err := conn.Do("GET", key)
This returns an interface{} in res. Depending on the type, I'd like to call one of the helper functions like redigo.String(res) or redigo.Bool(res). I know I can do conn.Do("TYPE", key) to get the type separately, but how can I get the type just from the result of one GET request?
Wait, REDIS TYPE command does not provide you the details of value type it just tells you whether the key's value is a string, list, set, zset, hash, or stream.
So your application code or client code must identify what's it's equivalent for your programming language.
You can try to decode your data using the known key value types.

Passing a default Integer value to a WCF service in Biztalk

I have consumed WCF service in biztalk through "Add generated items". There is a method in WCF which takes an integer parameter. In orchestration I want to pass that method a default value or say I want to hard code input value. How I can achieve this. I have googled this question but didn't get any adequate result.
What I have done is declared an integer variable assign it a value, then I assigned that variable to a message of Integer type.
Now how I can assign this message to WebService Request type message?
or how I can transform integer type message to WebService Request type message?
There are a bunch of ways to do this:
If you are mapping the request from another message, you can hard code it in the map - click on the field in the RHS of the Map Editor and set the hard coded value in the Value in the Property box
After creating a (dummy) request message, you can set the value using xpath() in an expression message assignment shape
xpath(myRequestMessage, "//*[local-name()='NameOfFieldHere']") = 3; // Or set to it your variable
If the field is distinguished in your schema, you can use the distinguished field instead of xpath, viz in an expression message assignment shape:
myRequestMessage.NameOfFieldHere = 3;
(And note if its a multipart message, then it will be myRequestMessage.Part.NameOfFieldHere OFC)
One disclaimer: I've assumed the WCF service request message is trivial, i.e. just a single integer field. If your message is large, using //local-name() ... isn't recommended, since
There may be more than one node with with the name NameOfFieldHere
The XSL parser used by BizTalk is slow and resource intensive when evaluating large xml documents with //
Biztalk Scheduler Adapter is really helpful in this case. It generates desired XML on predefined scheduled set by the user. So fill up your XML with hard coded values and receive them through this adapter.