Mar 12, 2018 - James Watts

Ethereum: Blockchain Contracts 101

New to Ethereum and blockchain contracts? This post will take you through the basics.

Open Primary Tabs Configuration Options

One of the most interesting features of the Ethereum blockchain implementation is the ability to upload executable code as data transactions on the mined blocks, which are referred to as contracts. Ethereum clients and miners all contain a virtual machine capable of interpreting and interacting with these data transactions in a defined manner, and Ethereum includes a programming language known as Solidity to define contracts. Once a contract has been written, it is compiled via one of several available compilers into bytecode (as hex), which can be sent as transactions to create a contract on the blockchain. In addition to the bytecode, the compiler can also output an abi definition, which is helpful for applications that interact with the contracts (the abi includes the contract methods, parameters and other information encoded as JSON).

Creating a Contract

Ethereum contracts are defined via a statically-typed language with C-like syntax known as Solidity. It offers several useful features, including inheritance, complex and custom types, and blockchain-logged events. In addition to easily handling and controlling the transfer of Ether (the Ethereum cryptocurrency), contracts can be used for other applications, including proof of authority and authentication. Contracts include storage of typed data and functions for interacting with that data, and can also generate events that log data to the blockchain and can be easily searched and filtered. Those familiar with C-type syntax will recognize most parts of a Solidity contract already, and they are fairly simple to put together. A very basic custody / ownership contract could be implemented as:

pragma solidity ^0.4.19;

contract Owned {

address internal origin;

address internal owner;

event Given(address indexed _from, address indexed _to);

modifier onlyOwner { require(msg.sender == owner); _; }

modifier onlyOrigin { require(msg.sender == origin); _; }

function Owned() public { origin = msg.sender; owner = msg.sender; }

function give(address _to) public onlyOwner { Given(owner, _to); owner = _to; }

function takeback() public onlyOrigin { Given(owner, origin); owner = origin; }

function mine() public view returns (bool) { return(msg.sender == owner); } }


Contract Structure

The contract above is a simple example representing something owned by someone, and some basic control over how it can be transferred to others. It has some state variables, an event to log, some function modifiers (usually used to control the conditions under which functions may be called), and a couple of simple functions. This particular contract allows whoever currently owns it to give it to someone else, but the original owner can always take it back, no matter who owns it (because of the takeback method).

Contract Compile

Solidity contracts are compiled into bytecode (encoded as hex) for use on the blockchain. The solc compiler (among others) can be used for this task:

solc -o ./compile --optimize --asm --bin --abi --hashes --gas Owned.sol

The compiler will generate several useful files, including a .bin file containing the contract bytecode as hex.


Pushing to the Blockchain

With the contract binary, a new instance of the contract can be created on the blockchain with a new transaction (here using the geth command line client):

> eth.sendTransaction({ "from": account, "data": binary }); INFO [] Submitted contract creation fullhash=0x351240d5eb1da621203973435f551ac7759ff6cb26a7c417eaa1d8bbc11acd3b contract=0xC124740DB63D7370dd4f96E050e988d6F5e512B3

Once a miner picks up your transaction and builds it into a block, your contract is on the blockchain!

You can view the result of your transaction once it's been mined, which will provide the resulting contract address for further contract interactions:

> eth.getTransactionReceipt("0x351240d5eb1da621203973435f551ac7759ff6cb26a7c417eaa1d8bbc11acd3b"); { ... contractAddress: "0xc124740db63d7370dd4f96e050e988d6f5e512b3", ... }


Gas Fees

One thing to understand about Ethereum transactions is that they require the sender to pay a gas fee (in ether) for each transaction. This gas fee is paid to the miner that mines the transaction into a block on the blockchain, and the gas fee of any given transaction is dependent on the complexity of the data and processing required.

Keeping contracts simple with fairly constrained states helps keep gas costs low . Also, be aware that using any dynamic length variables in contracts (notably strings) can  make gas fees effectively infinite. It’s crucial to be careful when using these data types.