solidity learning process --- abi coding

abi encoding function

What is abi

When calling the interface contracts Application Binary Interface, Ethernet Square described
ABI is the interface between the two program modules, primarily for data encoding or decoding a code represented by the source code.
Ether is mainly used in a function call Square solidity contracts, and the method of reading data encoded reverse

solidityABI encoding function

  • abi.encode (...) returns (bytes): ABI coding calculation parameters.
  • abi.encodePacked (...) returns (bytes): calculation parameters of tightly packed encoding
  • . Abi encodeWithSelector (bytes4 selector, ...) returns (bytes): calculated function selector and parameter coding ABI
  • abi.encodeWithSignature(string signature, …) returns (bytes): 等价于* abi.encodeWithSelector(bytes4(keccak256(signature), …)

encoding function implementation details solidityABI

Function selector, official documents is defined as follows:
a function call first 4 bytes of data, specify the function to be called. This is a function signature Keccak (SHA-3) a hash of the first 4 bytes (upper left in the big-endian) (translation: here the "left high in the big-endian" refers to the maximum bit bytes of storage kind of serial coding of the least significant bit in the address, i.e., high byte on the left). This signature is defined to regulate expression based prototype to the prototype function name that is surrounded by parentheses plus a list of parameter types, parameters separated by a comma-type, with no spaces.

In simple terms, is to identify the function selector function by parameter function name can be used for function calls between different contracts

1. The function call intercepted call contract the first four bytes of data ( 0x later), the function name is to be signed and the process parameter types (Keccak-Sha3),

  • Performing set (21) can function results obtained:
    60fe47b1 SET (uint256) - this is the acquired signature hash function taken to the first four bytes (one byte corresponds to two hexadecimal characters)
  • Its argument is 21 to 15 hexadecimal
  • Function The end result: 0x60fe47b10000000000000000000000000000000000000000000000000000000000000015

Function name and contract function parameters, each parameter will ultimately be to complement the 32 bytes

solidityABI encoding function to achieve:

contract testABI {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function abiEncode() public view returns (bytes memory) {
        abi.encode(1);  // 计算1的ABI编码
        return abi.encodeWithSignature("set(uint256)", 1); //计算函数set(uint256) 及参数1 的ABI 编码
    }
}

remix after deployment contract calls abiEncode () will produce the following output data:

  1. abi.encode(21)

0ksh60fae47bl00000000000000000000000000000000000000000000000000000000000000l5

  1. Wherein 60fe47b1 is corresponding to the set () functions signing process

    [
     {
     	"constant": false,
     	"inputs": [
     		{
     			"internalType": "uint256",
     			"name": "value",
     			"type": "uint256"
     		}
     	],
     	"name": "set",
     	"outputs": [],
     	"payable": false,
     	"stateMutability": "nonpayable",
     	"type": "function"
     }
    

]
``

abiDetail:

  1. constant - If the function block chain state changes to true, and vice versa false;
  2. type: call parameter types: string, function, callback, contsructor
  3. name: parameter name calling
  4. payable: whether to support the ether
  5. stateMutability :( state variability) - pure - view - payable - nonpayable
  6. outputs: call output value
  7. input:{
    • name: parameter name
    • type: Parameter Type
      }

abi.encode 与abi.encodePacked

  1. The function of the packing process, but the process is not the same, for the parameter type is less than 32 bytes , the former will be automatically complete all parameters to 32 bytes, which do not auto-complete

  2. uint The default is uint256, there is no question that complement byte verification

contract TestDifference {
  function testUint(
    uint8 _num1,
    uint32 _num2
    )
    public view returns (bytes memory, bytes memory) {
    return (
      abi.encode(_num1),
      abi.encodePacked(_num2)
      );
  }

  function testBytes() public view returns (bytes memory, bytes memory) {
      bytes memory _bts ="Hello,world!";
    return (abi.encodePacked(_bts),abi.encode(_bts));
  }
}

On the use of abi.encodeWithSignature (string signature, ...) returns (bytes)

The main scenarios: function call

contract Contract {

    MyContract contract1 = new MyContract();

    function getSelector() public view returns (bytes4, bytes4) {
        return (contract1.function1.selector, contract1.getBalance.selector);
    }

    function callGetValue(uint _x) public view returns (uint) {

        bytes4 selector = contract1.getValue.selector;

        bytes memory data = abi.encodeWithSelector(selector, _x);
        (bool success, bytes memory returnedData) = address(contract1).staticcall(data);
        require(success);

        return abi.decode(returnedData, (uint256));
    }
}

contract MyContract {

    function function1() public {}

    function getBalance(address _address) public view returns (uint256){}

    function getValue (uint _value) public pure returns (uint) {
        return _value;
    }

}
Released six original articles · won praise 1 · views 154

Guess you like

Origin blog.csdn.net/qq_35434814/article/details/104682616