Skip to content

Latest commit

 

History

History
64 lines (49 loc) · 2.98 KB

contracts.md

File metadata and controls

64 lines (49 loc) · 2.98 KB

Ethereum smart contracts

This article explains how we write, deploy, and invoke Ethereum smart contracts used in the benchmark.

Writing smart contracts

Use Solidity to. For example, the key-value smart contract is written as follows:

pragma solidity ^0.4.0;
contract KVstore {
 mapping(string=>string) store;
 function get(string key) constant returns(string) {
  return store[key];
 }
 function set(string key, string value) {
   store[key] = value;
 }
}

Deploying the contract

The contract must first be compiled into EVM bytecode and send to the blockchain as data of a transaction. At the end, a unique contractAddress is generated, which is a hash of the following:

  • The uploading address, i.e. address of the account that invoke the transaction.
  • The contract bytecode.

Thus, the same contract (bytecode) uploaded from two different addresses results in two distinct contractAddress. In other words, two independent contracts are deployed. This is an important distinction to Hyperledger: in this example, only one Hyperledger will be deployed.

  1. Compilation: use the online Solidity browser https://ethereum.github.io/browser-solidity

    • Copy and paste the code
    • See the compiled bytecode
  2. Upload to the blockchain using eth_sendTransaction RPC

    curl -X POST <endpoint> -d {"jsonrpc": "2.0", "method": "eth_sendTransaction", "params": [{"gas": <gas>, "from": "<from address>", "data": "<bytecode>"}], "id": 1}

Invoking contract methods

Once the contract is deploy at contractAddress, its method is invoked by sending transactions to it. Content of the transaction, its data field contains encoded input: a string of the following format:

`<method singature><padded param>..`

For instance, the encoding for the method call set("hello", "world") is as follows:

  • Method signature, generated by the same Solidity browser during compilation, i.e. 0x0xe942b516
  • Off-set to the encoded first parameter (excluding the signature), padded to 32 bytes. Say this is X
  • Off-set to the encoded second parameter (excluding the signature), padded to 32 bytes. Say this is Y
  • Encoded first parameter, padded to 32-byte units. In this case, the encoding is 64 bytes (32 byte for length, and 32 bytes for "hello")
  • Encoded second parameter, padded to 32-byte units. In this case, the encoding is 64 bytes (32 bytes for length, and 32 bytes for "world")

Thus, X=00..040 because the encoded first parameter starts at byte 64 after the signature. Y=00..80 because the encoded second parameter starts at byte 128 after the signature. Suppose the first string is longer than 32 bytes, say it's 48 bytes (padded to 64), then Y=00..a0 because the encoded second parameter now starts at byte 160.

Finally, the transaction is sent via RPC curl -X POST <endpoint> {"jsonrpc": "2.0", "method": "eth_sendTransaction", "params": [{"gas": <gas>, "from": "<from_address>", "to": "<contractAddress>", "data": "<encodedMethod>"}], "id": 1}