14

I am reading an article, it says:

To enable deployment on the Ethereum platform, the contract functions are compiled into EVM bytecode and a piece of code called function selector is added, which serves as an entry point into the contract code.

Can some body please tell me what is a function selector?

I tried google and found:

The first four bytes of the call data for a function call specifies the function to be called. It is the first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype without data location specifier, i.e. the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used.

I can't understand what is call data?

Some body please guide me.

Zulfi.

2
  • I can't understand what is call data? - there is no mentioning of "call data" in the description that you've pasted here! Jun 29, 2019 at 5:11
  • "The first four bytes of the 'call data' for a function call specifies the function to be called.", second quotation talks about call data.
    – zak100
    Jun 29, 2019 at 12:53

2 Answers 2

9

A function selector allows you to perform dynamic invocation of a function, based on the name of the function and the type of each one of the input arguments.

For example, suppose you have:

contract Contract1 {
    function func(uint256 x, uint8 y) public returns (uint32, uint32) {...}
}

contract Contract2 {
    Contract1 public contract1 = new Contract1();
    function func() public returns (uint32, uint32) {...}
}

Then you can call Contract1.func from Contract2.func as follows:

function func() public returns (uint32, uint32) {
    uint32[2] memory ret;

    address dest = address(contract1);

    bytes4 selector = contract1.func.selector;
    // Or bytes4 selector = bytes4(uint256(keccak256("func(uint256,uint8)") >> 224));

    bytes memory data = abi.encodeWithSelector(selector, uint256(789), uint8(123));

    assembly {
        let success := call(
            gas,           // pass the remaining gas to the function
            dest,          // the address of the contract1 instance
            0,             // pass 0 wei to the function
            add(data, 32), // the actual data starts after the length of 'data'
            mload(data),   // the length of 'data' appears at the first 32 bytes
            ret,           // the address of the output
            8              // the size of the output
        )
        if iszero(success) {
            revert(0, 0)
        }
    }

    return (ret[0], ret[1]);
}

If the invoked function is constant (either pure or view), then you can also use staticcall.

The example above is in assembly, but you can also use call directly in solidity.

I think that staticcall should be available starting from solidity v0.5.0.

7
  • "To enable deployment on the Ethereum platform, the contract functions are compiled into EVM bytecode and a piece of code called function selector is added, ", I thought we would add function selector in the contract which we are deploying.
    – zak100
    Jun 29, 2019 at 12:50
  • Which part of 'call' deals with passing of two arguments: one of size uint256 and the other of size uint8?
    – zak100
    Jun 29, 2019 at 13:01
  • @zak100: They are encoded in data and passed to call in add(data, 32), which is an offset of 32 bytes from the address of data. Jun 29, 2019 at 14:10
  • Contract1.func is returning two values but we are using a single argument 'success' to store the values in the assembly code? Is this not an error?
    – zak100
    Jun 30, 2019 at 22:22
  • 2
    @zak100: In the coding example that I gave you, change function func() to function func(bytes4 selector). Do you understand now why I call this "dynamic invocation"? You can pass any selector to func, and it will execute different functions in the assembly code. The function to be executed is determined at runtime rather than at compilation time - when func is compiled, the compiler has no knowledge of which function it will invoke. Hence the term "dynamic invocation". Jul 3, 2019 at 4:25
2

A function selector is the first four bytes of the calldata that specifies which function to call during a function call. For example, contract.call(abi.encodeWithSignature("transfer(address,uint256)", 0xtheAddressArgument, number/amount)) During execution, the first 4 bytes from the abi.encodeWithSignature(....) in the above example represents the funtion's selector.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.