This is what I have so far, please correct me if I'm wrong:

The data parameter of a transaction is where we tell a deployed smart contract how we want to interact with it. It contains a hexed JSON containing all the input for all the functions of the contract we want to interact with. This JSON is coded using the contract's ABI, which is kind of a manual on what formats the contract can take and will return. To fit in the data parameter, the JSON we want to send must be turned into hex.

Assuming all this is right, I'm looking for examples of non-hexed data JSONs to get a grasp on what I'm suposed to write using the ABI.

  • Please rephrase the questions, in my opinion in can mean 2 things. Just to be more clear so we can help Aug 19, 2021 at 5:22
  • I'm sorry, I'm not a programmer. Basically I wanna know how to writte data input using a contract's ABI (if it makes sense to do such a thing).
    – FranLegon
    Aug 19, 2021 at 12:45

2 Answers 2


The data is not a hexadecimal representation of JSON data. Solidity has a custom format, described in the Contract ABI Specification. Essentially there are two different types of types, static and dynamic. Static types are types that always fit in 32 bytes (= 256 bits) of data, like uint256, address, etc. Dynamic types are types that don't fint in this 32 bytes of data, like bytes, string and arrays (including things like uint256[]).

Static types are encoded in the same order as your Solidity function. So let's say we have a function like this:

function foo(uint256 bar, address baz) external

The transaction data field starts with the function selector, specifying which function to call. In this case that's a68b44f8 (the first four bytes of the Keccak hash of foo(uint256,address). After that we put the values of bar in baz in that order, where each value is 32 bytes long. If we want to encode 12345 for bar and 0x4bbeeb066ed09b7aed07bf39eee0460dfa261520 for baz, the data becomes:

0xa68b44f8 (function selector)
0000000000000000000000000000000000000000000000000000000000003039 (bar)
0000000000000000000000004bbeeb066ed09b7aed07bf39eee0460dfa261520 (baz)

In the case of dynamic types, we encode a pointer to dynamic value instead. The value is appended to the end of the data, starting with the length of the value (32 bytes). So if we have a function like this:

function foo(uint256[] bar, address baz) external

And we want to encode [12345, 67890] for bar and the same address for baz, the data becomes:

0000000000000000000000000000000000000000000000000000000000000040 (pointer to bar)
0000000000000000000000004bbeeb066ed09b7aed07bf39eee0460dfa261520 (baz)
0000000000000000000000000000000000000000000000000000000000000002 (length of bar)
0000000000000000000000000000000000000000000000000000000000003039 (bar[0])
0000000000000000000000000000000000000000000000000000000000010932 (bar[1])

The Contract ABI Specification describes how different types in Solidity should be encoded. I wrote a more detailed explanation of transaction data which you can find here.

  • Thank you very much, you've cleared most of my doubts.
    – FranLegon
    Aug 23, 2021 at 14:18
var sample_contract_instance = await new web3.eth.Contract(<CONTRACT_ABI>, <CONTRACT_ADDRESS>);
var sample_contract_method = await sample_contract_instance.methods.testMethod(<SAMPLE_PARAM_1>, <SAMPLE_PARAM_2>).encodeABI();

var transaction_object = {
    gasLimit: <SAMPLE_GAS_LIMIT>,
    from: <SAMPLE_ADDRESS>,
    nonce: <SAMPLE_NONCE>,
    chainId: 1,
    data: sample_contract_method,

This is how you attach transaction data to transaction object, by encoding the contract method you wish to execute with encodeABI().

Your Answer

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

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