Third & GroveThird & Grove
Mar 19, 2018 - James Watts

Ethereum, Part II: Blockchain Contract Methods and Encoding

The first post in this series examined how Ethereum contracts are written and can be compiled and sent to the blockchain as a transaction. Once contracts have been created, you can interact with them in a couple of different ways, including calling contract methods (the public functions the contract ABI exposes) and examining generated contract events (to be covered in more detail in a later post).

Open Primary Tabs Configuration Options

The first post in this series examined how Ethereum contracts are written and can be compiled and sent to the blockchain as a transaction. Once contracts have been created, you can interact with them in a couple of different ways, including calling contract methods (the public functions the contract ABI exposes) and examining generated contract events (to be covered in more detail in a later post). In order to call a method on an Ethereum blockchain contract, a couple of pieces of information are required: the contract address on the blockchain (an address hash) and the signature and parameters of the method to be called, encoded properly for the Ethereum VM to interpret.

Contract Method Signatures

Each contract written in Solidity can provide public methods, and the Ethereum VM identifies a method call by using a hash of the method signature. Using a portion of the simple contract from the previous blog post:

function give(address _to) public onlyOwner {

Given(owner, _to);

owner = _to;

}

The function signature for hashing of this method is combination of the name and the parameter types: give(address), which when hashed via the Ethereum hashing algorithm (currently Keccak-256) results in bdf86a66. Fortunately, one handy feature of the solc compiler is that it will compute all the available method hashes when compiling a contract (using either the --hashes or --combined options), so these are typically already available when you interact with contracts.

Method Arguments

When calling a method that requires arguments, the argument data is appended to the first four bytes of data from the contract method signature. These arguments must be encoded properly based on the type of argument required into a hex encoded binary data packet. Encoding them properly can be rather complex, especially when using dynamic types (like arrays, strings or unsized byte types). The formal encoding spec can be somewhat daunting, but luckily there are some additional tools that can be helpful. The Ethereum Web3 js API has methods for parameter encoding built in, and there are several other language and command line tools that can handle this process.

Assuming we wanted to call the give method with a parameter of address 0x02B831775e3D48b2bc107c8431d15Aa4E0F8FD41:

$ ethabi encode function Owned.abi give -p 02B831775e3D48b2bc107c8431d15Aa4E0F8FD41

bdf86a6600000000000000000000000002b831775e3d48b2bc107c8431d15aa4e0f8fd41

Here the ethabi command line encoding tool has taken the four bytes of the method signature (bdf86a66) and appended the address parameter left padded to 32 bytes. This encoded method signature and parameter may now be used to make a call to a contract instance on the blockchain as a transaction.

Pushing to the Blockchain

The encoded method data—along with an existing contract address—can now be sent as a transaction. The transaction needs to come from an account (in this case, the contract code specifies that only the current owner of the contract may give it to someone else), so the address of the user who created the contract is used as the from field:

> eth.sendTransaction({ "from": "0x498F0c603Cf19Cb5bEf5461D7D9CF0acAA2f65B0", "to": "0xc124740db63d7370dd4f96e050e988d6f5e512b3", "data": "0xbdf86a6600000000000000000000000002b831775e3d48b2bc107c8431d15aa4e0f8fd41" });

INFO [] Submitted transaction fullhash=0xa80a395bf3741a549a943d3badb7a8a9631f89c734c4131e6c7d501b05fd93e0 recipient=0xC124740DB63D7370dd4f96E050e988d6F5e512B3

 

Contract Constructor Arguments

Contracts may include a constructor method (a function named the same as the contract name), which is called when the contract is created to set up whatever internal state the contract might require. These constructor methods may also take arguments. In this case, the arguments are encoded in the same manner as described above for function calls, but the resulting encoded data is appended to the contract binary when the transaction is sent to create the contract.