DEV Community

Mister Singh
Mister Singh

Posted on • Updated on

Let's dive a little in to function selectors in solidity

Function selector is how we tell them smart contract which function to run. It is the first 4 bytes which we get from the functions name and it is used when calling low level functions like call on a contract and asking it to run a function.

For example function foo(){ } has selector 0xc2985578

Side Note: The function selector is most probably unique for a contract. It is just 4 bytes and that is not a lot of data and thus there can exist another function which has a totally different name but same selector. But that is neither here nor there, so let's move on.

To build a selector in solidity:

  1. convert the function name to bytes
  2. then get its keccak256. this gives us a 1 way hash which has fixed size
  3. now take the first 4 bytes of that hash.
bytes4(keccak256(bytes("foo()")))
Enter fullscreen mode Exit fullscreen mode

bytes4(keccak256(bytes()))

Now, this is good, but most likely the function also takes input params and the values of the input also need to be encoded in to bytes and added to the selector.

So let's say we have a function like foo(uint256) which we want to call with value of 1. then we can get the encoded value like this

bytes4 prefix = bytes4(keccak256(bytes("foo(uint256)")))
uint a = 1;
bytes32 suffix = bytes32(a);
bytes memory ans = abi.encodePacked(prefix, suffix);
Enter fullscreen mode Exit fullscreen mode

and this gives us 0x2fbebd380000000000000000000000000000000000000000000000000000000000000001

So this worked, but there is abi.encodeWithSignature which is an easier way to get the selector with values all encoded in bytes for us to use.

abi.encodeWithSignature

And there is another helper function abi.encodeWithSelector which takes the selector from us and just encodes and appends the inputs for us.

abi.encodeWithSelector

And finally the same can be done in javascript using ethers.js. We can build an interface with just the function whose selector we want and call getSigHash to get the selector

getSigHash

Ethers also supports encoding input values as well

encodeFunctionData

So thats it. now you know how to encode & build function selectors with & without inputs, from solidity & from the frontend.

Top comments (0)