Giả sử ta có hàm sau:

function transfer(address someAddress, uint256 amount) public {
	// Some code
	s_someAddress = someAddress;
	s_amount = amount;
}

Một số cách để lấy function selector:

  1. Sử dụng bytes4(keccak256(bytes("transfer(address,uint256)")))

  2. Lấy từ 4 bytes đầu của calldata:

    function getSelectorTwo() public view returns (bytes4 selector) {
        bytes memory functionCallData = abi.encodeWithSignature(
            "transfer(address,uint256)",
            address(this),
            123
        );
        selector = bytes4(
            bytes.concat(
                functionCallData[0],
                functionCallData[1],
                functionCallData[2],
                functionCallData[3]
            )
        );
    }
  3. Sử dụng hàm calldataload của Yul - ngôn ngữ lập trình cấp thấp của Ethereum:

    function getSelectorThree(bytes calldata functionCallData) public pure returns (bytes4 selector) {
    	// offset is a special attribute of calldata
    	assembly {
    		selector := calldataload(functionCallData.offset)
    	}
    }
  4. Sử dụng từ khóa this và property selector:

    function getSelectorFour() public pure returns (bytes4 selector) {
    	return this.transfer.selector;
    }

Resources