A technical primer on using encoded function calls

A developer’s guide to encoding and executing encoded functions.

Veronica Coutts
Jan 21, 2019 · 7 min read

Encoded function calls are powerful tools, used by having a bytes parameter, like those found in the ERC721 and ERC223 standards. These bytes parameters allow you to nest function calls within other functions. This has many benefits such as expanding the utility of a token contract or creating generic public functions with validation.

Bytes parameters are usually included as a forward compatible measure, which allows the function to send through any additional data that is required, provided that it has been encoded into bytes first. This provides you with nifty upgradability patterns and you can even embed one into a QR code.

Image by Kevin Ku from Unsplash

Let this article serve as a guide, covering everything you need to know about encoding in both Solidity and JavaScript, as well as how to execute an encoded function call in Solidity.

What does it mean to encode a function anyway?

From a developer’s point of view, an encoded function is a function that has been transformed into (EVM’s) bytecode. Before you start encoding a function call, I almost insist that you go and read the docs. They will give you some important warnings and valuable advice. Disclaimer! All the code snippets are in . There are breaking changes in!!

What parts of a function can you encode?

A function can be broken up into components, mainly the function name, the function parameters, and the function signature.

The components of a function

The function signature is the function name with the parameter types, as shown below:

createLime(string,uint8,uint8,uint8);

A function call is the function name with the parameter values:

createLime(“string”, 1234, 4321, 1234);

Below is a simple example of encoding the function's signature.

The encoded function signature is: 0xe0b6fcfc and is a .

Important to note

You can only execute public or external encoded functions. (Please see ‘executing an encoded function call’ further on in this article).

The examples shown here are written in . If you want it to be brought up to please leave a comment. This point has previously been mentioned, but it is incredibly important to highlight once again.

Encoding your function

To encode your function in Solidity, we will use the hashing function with a conversion to , which is explained later.

What you’ll need to encode your function

Before getting started, you’ll need a decent understanding of JavaScript and Solidity. You will need Truffle , or your testing framework of choice, and the library. It should be noted that this is only available with web3 1.0.0 beta).

Encoding and executing an encoded function call in Solidity

To encode a function signature in Solidity:

Notice how there are no spaces between the parameters? You’re hashing the function name with , a hashing function and returns hex, which is then converted into . This converts it from hex to an array of 4, 8 byte numbers. This is actually how Solidity creates function signatures for the EVM.

In , you can target the interface, followed by the function, which calls the selector property as shown below:

//So this bytes4(keccak256(“onERC721Received(address,address,uint256,bytes)”))
// is equal to this
IERC721Receiver(0).onERC721Received.selector

To encode a function call in Solidity:

You don’t need to encode the entire function call in Solidity. If you have the parameters, you can execute it. See below.

To execute an encoded function call in Solidity:

Be warned: your should always be encapsulated in a ALWAYS! The will return a boolean for its success. If you don’t put it in a and it fails, you will not know.

A side note, in returns a boolean and some data about the call, which will break your ’s. By using the you pretty much hand over control of your contract, but you’d already know this if you’ve read the docs. Executing can be done in a couple of ways, the first being with un-encoded parameters and an encoded function signature as shown below:

The is a low-level call and Solidity will warn you that low-level calls should be avoided. The reason for this is that if you don’t validate the encoded call you are receiving, this call could wreak havoc. You are mildly protected by the fact that in the makes the call seem like it’s coming from an external source, meaning that only public and external functions can be called. Expect this call to be irrational, and not what you initially planned it to be used for, and you should be fine.

Another possibility for running an encoded function call is if the entire function call is encoded. This is the same as when you would use the again.

Be warned: executing an encoded function like this could have some serious negative consequences. For example, if you want to verify the function signature you now need to extract it. Trust me when I say that it is not trivial and will involve assembly.

Finally, you can make an encoded function call in Solidity by encoding it directly in the and then adding in the parameters.

If you think about it in terms of security, you know with 100% certainty what function this will call irrespective of the parameters received. See how the function signature is encoded in the same way as before, but this time we have instead encoded it directly at the time of calling it in the . You could also call the function directly, but I included this so you would know it’s in the realm of possibility.

You can even pass in the encoded function signature and encoded parameters separately. This makes it easier to verify the function signature as shown below:

Encoding in JavaScript

There are many ways to ‘skin this cat’ when encoding a function in JS. You can encode a function with its ABI array by using the . Note that all the examples that are given here are written as Truffle tests with the actual testing parts excluded. If you would like a link to the repo so that you can fiddle around with it yourself, just drop a comment at the end of this article.

To implement the web3-eth-abi library simply add to the top of your JS.

To encode a function signature in JavaScript:

There are multiple ways to encode a function signature. You can use the functions ABI array as shown below. Notice how we are using the ‘s function to do the encoding for us.

To find the ABI array of the function, go into your build directory to the specific contract and to search for your function name. A heads up, if you change your function’s parameters you are going to have to get the new ABI, so this isn’t recommended for a function that might change. Instead, use the method provided below.

You can also encode the string of the function like in Solidity. Notice how we use the same encodeFunctionSignature function.

Much like the Solidity encoding of a function signature, there are no spaces between parameters.

To encode function parameters in JavaScript:

Each parameter has to be encoded by itself and you would have to feed them into the function call separately. There may be the ability to encode multiple parameters at once in a newer version of the , or in a newer version of Truffle.

To encode a function call in JavaScript:

Here, we use the ‘s to encode the entire function call. To add the parameters, , simply list them after the closing curly bracket of the function’s ABI array inside single quotes in the order that the function states. Make sure your parameters are still within the function call bracket.

To execute an encoded function call in JavaScript:

Obviously, this isn’t possible when you are trying to execute the call in the contracts, but I thought I would still leave this here to assure you that: it’s not possible.

In conclusion

No matter what you are using your encoded function call for, ensure that you do proper validation to prevent attack opportunities. You should also read all the assorted documentation and be sure to keep up with breaking changes involving in newer versions of Solidity, as most versions have different implementation details and nuances ( has breaking changes). Good luck with your encoding function call journey. May it be secure and bug-free!

Linum Labs Blog

At Linum Labs, we are a global team of developers…

Thanks to Linum Labs

Veronica Coutts

Written by

A blockchain believer & Ethereum developer. Trying to spread knowledge, peace and critical thinking.

Linum Labs Blog

At Linum Labs, we are a global team of developers, entrepreneurs, and change-makers, building decentralized systems in healthcare and identity.

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade