[SON ETH] Create a document about Ethereum smart contract function call encoding #376

Closed
opened 2022-05-27 13:44:08 +00:00 by serkixenos · 9 comments
serkixenos commented 2022-05-27 13:44:08 +00:00 (Migrated from gitlab.com)

The output of this task should be a document that describes how function calls and parameters are encoded when executing smart contract function.

Example call from ticket #359:

curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeE52b70e8D7AB5Fe661311D47e81228EAD6B06B9", "to": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", "data": "0x1688f0b9000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee70955200000000000000000000000000000000000000000000000000000000000000604fa262bd05cdef2e3d5261787ee66d9447a4036324990e04380339bec83b4c7a0000000000000000000000000000000000000000000000000000000000000264b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC1200000000000000000000000076ce31BD03f601c3fC13732deF921c5Bac28267600000000000000000000000009EE460834498a4ee361beB819470061B7381B490000000000000000000000006AEFbd09209e1eE2e0a589d31e732F69B77713D2000000000000000000000000631e128b16f9aDCF1bB6385112B1519C917D77a7000000000000000000000000cD5C788e84220E8b8934Ea4F1dC6a12009bCc91D0000000000000000000000003627C1B31525887CB9441130C831e3588765030500000000000000000000000003A13a989AF30C92AD7ABD1E6210308A6c96f3730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}], "id": 8}' localhost:8545 -v

Document should provide answer on how to build string added to the request as a value of data parameter.

  • How function names are encoded
  • How basic datatypes are encoded/decoded (integer, string, etc...)
  • How more complex types are encoded/decded, eg maps...
The output of this task should be a document that describes how function calls and parameters are encoded when executing smart contract function. Example call from ticket #359: ``` curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeE52b70e8D7AB5Fe661311D47e81228EAD6B06B9", "to": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", "data": "0x1688f0b9000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee70955200000000000000000000000000000000000000000000000000000000000000604fa262bd05cdef2e3d5261787ee66d9447a4036324990e04380339bec83b4c7a0000000000000000000000000000000000000000000000000000000000000264b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC1200000000000000000000000076ce31BD03f601c3fC13732deF921c5Bac28267600000000000000000000000009EE460834498a4ee361beB819470061B7381B490000000000000000000000006AEFbd09209e1eE2e0a589d31e732F69B77713D2000000000000000000000000631e128b16f9aDCF1bB6385112B1519C917D77a7000000000000000000000000cD5C788e84220E8b8934Ea4F1dC6a12009bCc91D0000000000000000000000003627C1B31525887CB9441130C831e3588765030500000000000000000000000003A13a989AF30C92AD7ABD1E6210308A6c96f3730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}], "id": 8}' localhost:8545 -v ``` Document should provide answer on how to build string added to the request as a value of data parameter. - How function names are encoded - How basic datatypes are encoded/decoded (integer, string, etc...) - How more complex types are encoded/decded, eg maps...
serkixenos commented 2022-05-27 13:44:08 +00:00 (Migrated from gitlab.com)

assigned to @pavel.baykov

assigned to @pavel.baykov
pavel.baykov commented 2022-05-30 10:25:34 +00:00 (Migrated from gitlab.com)
Specification of ABI https://docs.soliditylang.org/en/v0.8.14/abi-spec.html
pavel.baykov commented 2022-05-30 10:26:24 +00:00 (Migrated from gitlab.com)
To install: https://docs.soliditylang.org/en/latest/installing-solidity.html#building-from-source
pavel.baykov commented 2022-05-30 10:33:54 +00:00 (Migrated from gitlab.com)

from ABI spec , we need to have Keccak-256 function,

https://en.wikipedia.org/wiki/SHA-3

there is available online tool deployed:
https://emn178.github.io/online-tools/keccak_256.html

or there is implementation in Solidity repo, libsolutil library
https://github.com/ethereum/solidity/blob/develop/libsolutil/Keccak256.h

from ABI spec , we need to have Keccak-256 function, https://en.wikipedia.org/wiki/SHA-3 there is available online tool deployed: https://emn178.github.io/online-tools/keccak_256.html or there is implementation in Solidity repo, libsolutil library https://github.com/ethereum/solidity/blob/develop/libsolutil/Keccak256.h
pavel.baykov commented 2022-05-30 12:13:25 +00:00 (Migrated from gitlab.com)

From the example of Ticket 359
curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeE52b70e8D7AB5Fe661311D47e81228EAD6B06B9", "to": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", "data": "0x1688f0b9000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee70955200000000000000000000000000000000000000000000000000000000000000604fa262bd05cdef2e3d5261787ee66d9447a4036324990e04380339bec83b4c7a0000000000000000000000000000000000000000000000000000000000000264b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC1200000000000000000000000076ce31BD03f601c3fC13732deF921c5Bac28267600000000000000000000000009EE460834498a4ee361beB819470061B7381B490000000000000000000000006AEFbd09209e1eE2e0a589d31e732F69B77713D2000000000000000000000000631e128b16f9aDCF1bB6385112B1519C917D77a7000000000000000000000000cD5C788e84220E8b8934Ea4F1dC6a12009bCc91D0000000000000000000000003627C1B31525887CB9441130C831e3588765030500000000000000000000000003A13a989AF30C92AD7ABD1E6210308A6c96f3730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}], "id": 8}' localhost:8545 -v

That’s invoke method (contracts/proxies/GnosisSafeProxyFactory.sol)

function createProxyWithNonce(
        address _singleton,
        bytes memory initializer,
        uint256 saltNonce
    )

signature of this method is:

createProxyWithNonce(address,bytes,uint256)

First 4 bytes of Keccak-256 is 1688f0b9
this is the Method ID

next we should encode parameters of that contract:
address is uint160 (160 bits) 32 bytes aligned:
000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee709552

initializer is hex bytes of transaction built for invocation of setup method from
GnosisSafe.sol

/// @dev Setup function sets initial storage of contract.
/// @param _owners List of Safe owners.
/// @param _threshold Number of required confirmations for a Safe transaction.
/// @param to Contract address for optional delegate call.
/// @param data Data payload for optional delegate call.
/// @param fallbackHandler Handler for fallback calls to this contract
/// @param paymentToken Token that should be used for the payment (0 is ETH)
/// @param payment Value that should be paid
/// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)
function setup(
        address[] calldata _owners,
        uint256 _threshold,
        address to,
        bytes calldata data,
        address fallbackHandler,
        address paymentToken,
        uint256 payment,
        address payable paymentReceiver
    )
From the example of Ticket 359 `curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeE52b70e8D7AB5Fe661311D47e81228EAD6B06B9", "to": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", "data": "0x1688f0b9000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee70955200000000000000000000000000000000000000000000000000000000000000604fa262bd05cdef2e3d5261787ee66d9447a4036324990e04380339bec83b4c7a0000000000000000000000000000000000000000000000000000000000000264b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC1200000000000000000000000076ce31BD03f601c3fC13732deF921c5Bac28267600000000000000000000000009EE460834498a4ee361beB819470061B7381B490000000000000000000000006AEFbd09209e1eE2e0a589d31e732F69B77713D2000000000000000000000000631e128b16f9aDCF1bB6385112B1519C917D77a7000000000000000000000000cD5C788e84220E8b8934Ea4F1dC6a12009bCc91D0000000000000000000000003627C1B31525887CB9441130C831e3588765030500000000000000000000000003A13a989AF30C92AD7ABD1E6210308A6c96f3730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}], "id": 8}' localhost:8545 -v` That’s invoke method (contracts/proxies/GnosisSafeProxyFactory.sol) ``` function createProxyWithNonce( address _singleton, bytes memory initializer, uint256 saltNonce ) ``` signature of this method is: ``` createProxyWithNonce(address,bytes,uint256) ``` First 4 bytes of Keccak-256 is 1688f0b9 this is the Method ID next we should encode parameters of that contract: address is uint160 (160 bits) 32 bytes aligned: 000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee709552 initializer is hex bytes of transaction built for invocation of setup method from GnosisSafe.sol ``` /// @dev Setup function sets initial storage of contract. /// @param _owners List of Safe owners. /// @param _threshold Number of required confirmations for a Safe transaction. /// @param to Contract address for optional delegate call. /// @param data Data payload for optional delegate call. /// @param fallbackHandler Handler for fallback calls to this contract /// @param paymentToken Token that should be used for the payment (0 is ETH) /// @param payment Value that should be paid /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin) function setup( address[] calldata _owners, uint256 _threshold, address to, bytes calldata data, address fallbackHandler, address paymentToken, uint256 payment, address payable paymentReceiver ) ```
pavel.baykov commented 2022-05-31 11:21:59 +00:00 (Migrated from gitlab.com)

b63e800d0x0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005fbbb31be52608d2f52247e8400b7fcaa9e0bc1200000000000000000000000076ce31bd03f601c3fc13732def921c5bac28267600000000000000000000000009ee460834498a4ee361beb819470061b7381b490000000000000000000000006aefbd09209e1ee2e0a589d31e732f69b77713d2000000000000000000000000631e128b16f9adcf1bb6385112b1519c917d77a7000000000000000000000000cd5c788e84220e8b8934ea4f1dc6a12009bcc91d0000000000000000000000003627c1b31525887cb9441130c831e3588765030500000000000000000000000003a13a989af30c92ad7abd1e6210308a6c96f37300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

is encoded representation of setup methods with params below

{
  "0": [
    "0x5FbBb31BE52608D2F52247E8400B7fCaA9E0bC12",
    "0x76ce31BD03f601c3fC13732deF921c5Bac282676",
    "0x09EE460834498a4ee361beB819470061B7381B49",
    "0x6AEFbd09209e1eE2e0a589d31e732F69B77713D2",
    "0x631e128b16f9aDCF1bB6385112B1519C917D77a7",
    "0xcD5C788e84220E8b8934Ea4F1dC6a12009bCc91D",
    "0x3627C1B31525887CB9441130C831e35887650305",
    "0x03A13a989AF30C92AD7ABD1E6210308A6c96f373"
  ],
  "1": {
    "_hex": "0x05"
  },
  "2": "0x0000000000000000000000000000000000000000",
  "3": null,
  "4": "0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4",
  "5": "0x0000000000000000000000000000000000000000",
  "6": {
    "_hex": "0x00"
  },
  "7": "0x0000000000000000000000000000000000000000"
}
b63e800d0x0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005fbbb31be52608d2f52247e8400b7fcaa9e0bc1200000000000000000000000076ce31bd03f601c3fc13732def921c5bac28267600000000000000000000000009ee460834498a4ee361beb819470061b7381b490000000000000000000000006aefbd09209e1ee2e0a589d31e732f69b77713d2000000000000000000000000631e128b16f9adcf1bb6385112b1519c917d77a7000000000000000000000000cd5c788e84220e8b8934ea4f1dc6a12009bcc91d0000000000000000000000003627c1b31525887cb9441130c831e3588765030500000000000000000000000003a13a989af30c92ad7abd1e6210308a6c96f37300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 is encoded representation of setup methods with params below ``` { "0": [ "0x5FbBb31BE52608D2F52247E8400B7fCaA9E0bC12", "0x76ce31BD03f601c3fC13732deF921c5Bac282676", "0x09EE460834498a4ee361beB819470061B7381B49", "0x6AEFbd09209e1eE2e0a589d31e732F69B77713D2", "0x631e128b16f9aDCF1bB6385112B1519C917D77a7", "0xcD5C788e84220E8b8934Ea4F1dC6a12009bCc91D", "0x3627C1B31525887CB9441130C831e35887650305", "0x03A13a989AF30C92AD7ABD1E6210308A6c96f373" ], "1": { "_hex": "0x05" }, "2": "0x0000000000000000000000000000000000000000", "3": null, "4": "0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4", "5": "0x0000000000000000000000000000000000000000", "6": { "_hex": "0x00" }, "7": "0x0000000000000000000000000000000000000000" } ```
pavel.baykov commented 2022-05-31 11:26:43 +00:00 (Migrated from gitlab.com)

there are several tools available for encoding:

https://abi.hashex.org/ - online tool
https://github.com/rust-ethereum/ethabi - Rust based CLI tool

to decode the easiest is:

https://www.moesif.com/solidity-abi-hex-decoder/decode
there are several tools available for encoding: ``` https://abi.hashex.org/ - online tool https://github.com/rust-ethereum/ethabi - Rust based CLI tool ``` to decode the easiest is: ``` https://www.moesif.com/solidity-abi-hex-decoder/decode ```
pavel.baykov commented 2022-05-31 11:49:05 +00:00 (Migrated from gitlab.com)
sample of usage Keccak-256 in C++
#include <libsolutil/Keccak256.h>

...

    std::stringstream f;
    std::string et = "createProxyWithNonce(address _singleton, bytes initializer, uint256 saltNonce)";
    std::string hex = solidity::util::keccak256(et).hex();
    std::cout << hex << std::endl;
    std::string ettag(hex);
    ettag = ettag.substr(0, 8);
    f << "0x" << ettag;
    std::cout << f.str() << std::endl;
sample of usage Keccak-256 in C++ ``` #include <libsolutil/Keccak256.h> ... std::stringstream f; std::string et = "createProxyWithNonce(address _singleton, bytes initializer, uint256 saltNonce)"; std::string hex = solidity::util::keccak256(et).hex(); std::cout << hex << std::endl; std::string ettag(hex); ettag = ettag.substr(0, 8); f << "0x" << ettag; std::cout << f.str() << std::endl; ```
pavel.baykov (Migrated from gitlab.com) closed this issue 2022-06-01 12:59:40 +00:00
pavel.baykov commented 2022-06-01 13:00:25 +00:00 (Migrated from gitlab.com)
aggregated all info in https://docs.google.com/document/d/105kavm8_PXElOg0Ck2DRQt9ovtNf8PdZGu6X1l_lDV4/edit#
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Peerplays_Blockchain/peerplays_migrated#376
No description provided.