Your first citizen: the greeter

Now that you’ve mastered the basics of Ethereum, let’s move into your first serious contract. The Frontier is a big open territory and sometimes you might feel lonely, so our first order of business will be to create a little automatic companion to greet you whenever you feel lonely. We’ll call him the “Greeter”.

The Greeter is an intelligent digital entity that lives on the blockchain and is able to have conversations with anyone who interacts with it, based on its input. It might not be a talker, but it’s a great listener. Here is its code:

contract mortal {
    /* Define variable owner of the type address*/
    address owner;

    /* this function is executed at initialization and sets the owner of the contract */
    function mortal() { owner = msg.sender; }

    /* Function to recover the funds on the contract */
    function kill() { if (msg.sender == owner) suicide(owner); }
}

contract greeter is mortal {
    /* define variable greeting of the type string */
    string greeting;

    /* this runs when the contract is executed */
    function greeter(string _greeting) public {
        greeting = _greeting;
    }

    /* main function */
    function greet() constant returns (string) {
        return greeting;
    }
}

You'll notice that there are two different contracts in this code: "mortal" and "greeter". This is because Solidity (the high level contract language we are using) has inheritance, meaning that one contract can inherit characteristics of another. This is very useful to simplify coding as common traits of contracts don't need to be rewritten every time, and all contracts can be written in smaller, more readable chunks. So by just declaring that greeter is mortal you inherited all characteristics from the "mortal" contract and kept the greeter code simple and easy to read.

The inherited characteristic "mortal" simply means that the greeter contract can be killed by its owner, to clean up the blockchain and recover funds locked into it when the contract is no longer needed. Contracts in ethereum are, by default, immortal and have no owner, meaning that once deployed the author has no special privileges anymore. Consider this before deploying.

Installing a compiler

Before you are able to Deploy it though, you'll need two things: the compiled code, and the Application Binary Interface, which is a sort of reference template that defines how to interact with the contract.

The first you can get by using a compiler. You should have a solidity compiler built in on your geth console. To test it, use this command:

eth.getCompilers()

If you have it installed, it should output something like this:

['Solidity' ]

If instead the command returns an error, then you need to install it.

Using an online compiler

If you don't have solC installed, we have a online solidity compiler available. But be aware that if the compiler is compromised, your contract is not safe. For this reason, if you want to use the online compiler we encourage you to host your own.

Install SolC on Ubuntu

Press control+c to exit the console (or type exit) and go back to the command line. Open the terminal and execute these commands:

sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
which solc

Take note of the path given by the last line, you'll need it soon.

Install SolC on Mac OSX

You need brew in order to install on your mac

brew install cpp-ethereum
brew linkapps cpp-ethereum
which solc

Take note of the path given by the last line, you'll need it soon.

Install SolC on Windows

You need chocolatey in order to install solc.

cinst -pre solC-stable

Windows is more complicated than that, you'll need to wait a bit more.

If you have the SolC Solidity Compiler installed, you need now reformat by removing spaces so it fits into a string variable (there are some online tools that will do this):

Compile from source

git clone https://github.com/ethereum/cpp-ethereum.git
mkdir cpp-ethereum/build
cd cpp-ethereum/build
cmake -DJSONRPC=OFF -DMINER=OFF -DETHKEY=OFF -DSERPENT=OFF -DGUI=OFF -DTESTS=OFF -DJSCONSOLE=OFF ..
make -j4 
make install
which solc

Linking your compiler in Geth

Now go back to the console and type this command to install solC, replacing path/to/solc to the path that you got on the last command you did:

admin.setSolc("path/to/solc")

Now type again:

eth.getCompilers()

If you now have solC installed, then congratulations, you can keep reading. If you don't, then go to our forums or subreddit and berate us on failing to make the process easier.

Compiling your contract

If you have the compiler installed, you need now reformat your contract by removing line-breaks so it fits into a string variable (there are some online tools that will do this):

var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'

var greeterCompiled = web3.eth.compile.solidity(greeterSource)

You have now compiled your code. Now you need to get it ready for deployment, this includes setting some variables up, like what is your greeting. Edit the first line below to something more interesting than 'Hello World!" and execute these commands:

var _greeting = "Hello World!"
var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);

var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[0], data: greeterCompiled.greeter.code, gas: 1000000}, function(e, contract){
  if(!e) {

    if(!contract.address) {
      console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");

    } else {
      console.log("Contract mined! Address: " + contract.address);
      console.log(contract);
    }

  }
})

Using the online compiler

If you don't have solC installed, you can simply use the online compiler. Copy the source code above to the online solidity compiler and then your compiled code should appear on the left pane. Copy the code on the box labeled Geth deploy to a text file. Now change the first line to your greeting:

var _greeting = "Hello World!"

Now you can paste the resulting text on your geth window. Wait up to thirty seconds and you'll see a message like this:

Contract mined! address: 0xdaa24d02bad7e9d6a80106db164bad9399a0423e 

You will probably be asked for the password you picked in the beginning, because you need to pay for the gas costs to deploying your contract. This contract is estimated to need 172 thousand gas to deploy (according to the online solidity compiler), at the time of writing, gas on the test net is priced at 1 to 10 microethers per unit of gas (nicknamed "szabo" = 1 followed by 12 zeroes in wei). To know the latest price in ether all you can see the latest gas prices at the network stats page and multiply both terms.

Notice that the cost is not paid to the ethereum developers, instead it goes to the Miners, people who are running computers who keep the network running. Gas price is set by the market of the current supply and demand of computation. If the gas prices are too high, you can be a miner and lower your asking price.

After less than a minute, you should have a log with the contract address, this means you've sucessfully deployed your contract. You can verify the deployed code (compiled) by using this command:

eth.getCode(greeter.address)

If it returns anything other than "0x" then congratulations! Your little Greeter is live! If the contract is created again (by performing another eth.sendTransaction), it will be published to a new address.

Run the Greeter

In order to call your bot, just type the following command in your terminal:

greeter.greet();

Since this call changes nothing on the blockchain, it returns instantly and without any gas cost. You should see it return your greeting:

'Hello World!'

Getting other people to interact with your code

In order to other people to run your contract they need two things: the address where the contract is located and the ABI (Application Binary Interface) which is a sort of user manual, describing the name of its functions and how to call them. In order to get each of them run these commands:

greeterCompiled.greeter.info.abiDefinition;
greeter.address;

Then you can instantiate a javascript object which can be used to call the contract on any machine connected to the network. Replace 'ABI' and 'address' to create a contract object in javascript:

var greeter = eth.contract(ABI).at(Address);

This particular example can be instantiated by anyone by simply calling:

var greeter2 = eth.contract([{constant:false,inputs:[],name:'kill',outputs:[],type:'function'},{constant:true,inputs:[],name:'greet',outputs:[{name:'',type:'string'}],type:'function'},{inputs:[{name:'_greeting',type:'string'}],type:'constructor'}]).at('greeterAddress');

Replace greeterAddress with your contract's address.

Tip: if the solidity compiler isn't properly installed in your machine, you can get the ABI from the online compiler. To do so, use the code below carefully replacing greeterCompiled.greeter.info.abiDefinition with the abi from your compiler.

Cleaning up after yourself:

You must be very excited to have your first contract live, but this excitement wears off sometimes, when the owners go on to write further contracts, leading to the unpleasant sight of abandoned contracts on the blockchain. In the future, blockchain rent might be implemented in order to increase the scalability of the blockchain but for now, be a good citizen and humanely put down your abandoned bots.

Unlike last time we will not be making a call as we wish to change something on the blockchain. This requires a transaction be sent to the network and a fee to be paid for the changes made. The suicide is subsidized by the network so it will cost much less than a usual transaction.

greeter.kill.sendTransaction({from:eth.accounts[0]})

You can verify that the deed is done simply seeing if this returns 0:

eth.getCode(greeter.contractAddress)

Notice that every contract has to implement its own kill clause. In this particular case only the account that created the contract can kill it.

If you don't add any kill clause it could potentially live forever (or at least until the frontier contracts are all wiped) independently of you and any earthly borders, so before you put it live check what your local laws say about it, including any possible limitation on technology export, restrictions on speech and maybe any legislation on the civil rights of sentient digital beings. Treat your bots humanely.