Creating the input data for an Ethereum contract function call

In todays blog post I will show you how to create the input data of a complex function call.

This example is based on the example contained within the Ethereum Wiki. I am simply going to explain it further to (hopefully) add more clarity.

To demonstrate this in a clear and concise manner we will use the following tools:

0x8be65246
0000000000000000000000000000000000000000000000000000000000000123
0000000000000000000000000000000000000000000000000000000000000080
3132333435363738393000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000e0
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000456
0000000000000000000000000000000000000000000000000000000000000789
000000000000000000000000000000000000000000000000000000000000000d
48656c6c6f2c20776f726c642100000000000000000000000000000000000000

Above you can see the full input data for the described function call. The lines are as follows:

  1. The Keccak encoded function signature
  2. The first input value
  3. The position of the second input value
  4. The third input value
  5. The position of the fourth input value
  6. The number of values in the second input (an array)
  7. The value of the second input (position 1)
  8. The value of the second input (position 2)
  9. The length of input 4
  10. Input 4

To get these values

  1. We take the first 4 bytes of the Keccak (SHA3) hash of the function signature.

Each hexadecimal character (nibble) is 4 bits. 2 characters is a byte. 8 characters is 4 bytes.

So we get 0x8be65246

  1. The first input is not of a dynamic type. It is already encoded so we simply pad it to 32 bytes per the specification.

32 bytes = 64 characters = 0000000000000000000000000000000000000000000000000000000000000123

  1. The second input is a dynamic type (an array). It can be of any length so we simply encode where in the input data we are going to describe this input.

We are going to describe it after the 'headers' for each input. Each header is 32 bytes. 4 headers = 128 bytes. So we will describe this input after 128 bytes which encoded as hexadecimal is 0000000000000000000000000000000000000000000000000000000000000080

  1. The third input is not a dynamic type. It is just a string. The string "1234567890" encoded as hex is 3132333435363738393. The specification tells us that strings should be right padded, so we get 3132333435363738393000000000000000000000000000000000000000000000.

  2. The fourth input is a dynamic type again - a string of any length. Again we use the 'header' to define where the information about this input will actually be found.

It will be found 224 bytes in. After the 4 headers, and the data for the second argument (which is also dynamic).

224 hex econded is 0xe0 which left padded to 32 bytes gives 00000000000000000000000000000000000000000000000000000000000000e0

  1. The length of the second input (the array), 2, hex encoded and left padded to 32 bytes. 0000000000000000000000000000000000000000000000000000000000000002

  2. The first array value of the input hex encoded and left padded to 32 bytes. 0000000000000000000000000000000000000000000000000000000000000456

  3. The first array value of the input hex encoded and left padded to 32 bytes. 0000000000000000000000000000000000000000000000000000000000000789

  4. The length of the dynamic bytes string (4th input), 13 hex encoded and left padded to 32 bytes. 000000000000000000000000000000000000000000000000000000000000000d

  5. The hex encoded string, right padded to 32 bytes. 48656c6c6f2c20776f726c642100000000000000000000000000000000000000

Another example

Lets now take a look at another example and transfer our new knowledge over to that.

This transaction is a call to the ENS Registrar contract on the main network.

The user in question is starting an auction for craftedge.eth as well as two other unknown names.

The input data is as follows:

0xfebefd61
0000000000000000000000000000000000000000000000000000000000000040
67202d74c1e5fe0efb7dd63637fb76d73ead20d00d56842c13637549992bebc7
0000000000000000000000000000000000000000000000000000000000000003
75b369a667e89d4e554bc227fe5810f9a7ef2b5b90395c1b06ce8da1676bcd6a
46bb95ca9552081fee9584b523c69cd1c375580df1b279126beac762d26fe098
df589f54d987fb75a5f1411caddd1f822d1006bc89baa09a34f4e8a5eb3b8141

If we look at the Registrars source code we can see that the signature for startAuctionsAndBid is function startAuctionsAndBid(bytes32[] hashes, bytes32 sealedBid) payable {

  1. We can discern the function signature the same way.

  2. The first input is dynamic so this line will describe where the data is to be found. It will be found 64 bytes in which hex encoded is 0x40. It is left padded to 32 bytes.

  3. The second input is not dynamic. This value is a 32 byte hashed bid. 67202d74c1e5fe0efb7dd63637fb76d73ead20d00d56842c13637549992bebc7

  4. The fourth line details the number of hashes in the array - 3. It is left padded to 32 bytes.

  5. A sha3 encoded domain name - unknown

  6. A sha3 encoded domain name - preconveyance.eth

  7. A sha3 encoded domain name - hardwarecanucks.eth

So there you have it. How to encode function call input data.