Ethereum

From Leo's Notes
Last edited on 6 February 2020, at 21:21.

Ethereum is a crypto platform for running smart contracts and exchanging Ether.

My address is 0xd2f887eda1b28c8714dbb2cf63a59f77fb68fb94

Clients

There are a few clients that you can use.

Go-Ethereum (geth)

The Ethereum client written in Go.

Setup

To compile geth, ensure that you have go, gcc, and make installed. Then run:

$ git clone https://github.com/ethereum/go-ethereum
$ cd go-ethereum
$ make geth

geth will be compiled in build/bin/geth.

Usage

When starting geth, it will automatically start downloading the blockchain. It depends on UDP/30303. Ideally, the client should be accessible publicly via that port.

The default cache size used by geth is quite small, so for an initial sync run:

$ geth --datadir /path/to/ethereum-data --cache=1024

Whilst it is syncing, you can check the state of the client by starting and attaching an interactive console:

$ geth attach
> net.listening
true
> admin.peers
> eth.syncing

To create a private net, provide a custom --networkid value or provide a genesis json file with --genesis. While on the private net, you can create a new account and start mining.

Other things you may want to do are:

Task Command
Create an account. Similar to creating a new wallet.
> personal.newAccount("Write here a good, randomly generated, passphrase!")
Show account balance
> web3.fromWei(eth.getBalance(eth.coinbase), "ether")
Transfer Ether
> personal.listAccounts.forEach(function(i) { personal.unlockAccount(i); });
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether") });
"0x03874297610e9eccac49325aea734f9feb98b1e91397302e7574e280068ca993"
Show account address
> eth.coinbase
## or
> eth.accounts[0]
Start CPU mining. Useful on testnets
> miner.setEtherbase(eth.accounts[0]) 
> miner.start()
Show your highest block number
> web3.eth.blockNumber
Show your sync status
> eth.syncing

You can create functions in the console. To make functions persistent, place it in a file and then load it.

> loadScript("/home/username/gethload.js")

A function to print all ethers and sum:

function checkAllBalances() {
    var totalBal = 0;
    for (var acctNum in eth.accounts) {
        var acct = eth.accounts[acctNum];
        var acctBal = web3.fromWei(eth.getBalance(acct), "ether");
        totalBal += parseFloat(acctBal);
        console.log("  eth.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " ether");
    }
    console.log("  Total balance: " + totalBal + " ether");
};


See Also:



Ethereum Basics

Every ethereum node runs the Ethereum Virtual Machine (EVM) and every node runs the same instructions to ensure consensus and fault tolerance.

The Ethereum blockchain stores the state of every account and all state transactions between accounts. Accounts can either be an Externally Owned Account (EOA) or a Contract Account. Both accounts have an ether balance.

Externally Owned Account is controlled by a private key.

Contract Accounts is a piece of code on the block chain that can be activated only by a EOA. Think of these accounts as autonomous agents (a scripted robot) that can be made to do virtually anything when invoked (the operations can be arbitrarily complex and is Turing complete). Contract accounts have access to its own persistent storage and can also invoke other contracts.

Transactions on the blockchain contains:

  • The recipient of the message
  • Signature to identify the sender
  • VALUE - Amount of wei to transfer
  • Optional data field - can be a message (think function calls) to a contract
  • STARTGAS value - the maximum number of computational steps the transaction is allowed to take
  • GASPRICE value - the fee the sender is willing to pay for gas (Question: is this value per unit of gas, or the total amount for STARTGAS?)

Contracts can send 'messages' to other contracts. They can be thought of as function calls. A message contains:

  • Sender (implicit as part of the transaction)
  • recipient
  • VALUE - amount of wei to transfer
  • optional data field -
  • STARTGAS - limits the maximum amount of gas the code execution triggered by the message can incur.

Messages are made when the code calls CALL or DELEGATECALL opcodes.


Miners are nodes that receive, propagate, verify, and execute transactions. Changes to the state of accounts are stored in a block. The target block time is 15 seconds. Mining at the moment requires a memory-hard Proof of Work (PoW) problem in order to be ASIC resistant. The idea behind ASIC resistance is to allow a more decentralized distribution of miners.

The ether balance are denominated in units of wei. 1 ether is 10^18 wei.


A "Smart Contract" refer to the code in a Contract Account.

Other

Backing up your key

Copy the ~/.ethereum/keystore as a backup. It contains your encrypted key. Also, don't forget your passphrase.

Private Test Net

To start your own test network with geth:

$ mkdir /tmp/ethereum-testnet
$ geth account new
WARN [06-29|22:58:44] No etherbase set and no accounts found as default
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {ff8d6e640f66aa4dcfc0248bb0c6b30ff0f2f3ae}

$ vi genesis.json
{
    "config": {
        "chainId": 1,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0,
	"byzantiumBlock": 0,
	"constantinopleBlock": 0,
	"petersburgBlock": 0
    },
    "difficulty": "200000",
    "gasLimit": "2100000",
    "alloc": {
                "ff8d6e640f66aa4dcfc0248bb0c6b30ff0f2f3ae": { "balance": "100000000" }
    }
}

$ geth --datadir /mnt/scratch/ethereum-testnet init genesis.json
INFO [06-29|22:59:03] Allocated cache and file handles         database=/mnt/scratch/ethereum-testnet/geth/chaindata cache=16 handles=16
INFO [06-29|22:59:03] Writing custom genesis block
INFO [06-29|22:59:03] Successfully wrote genesis state         database=chaindata                                    hash=112b5a…506029
INFO [06-29|22:59:03] Allocated cache and file handles         database=/mnt/scratch/ethereum-testnet/geth/lightchaindata cache=16 handles=16
INFO [06-29|22:59:03] Writing custom genesis block
INFO [06-29|22:59:03] Successfully wrote genesis state         database=lightchaindata                                    hash=112b5a…50602

$ geth --datadir /mnt/scratch/ethereum-testnet --networkid 1 console
> eth.coinbase
"0xff8d6e640f66aa4dcfc0248bb0c6b30ff0f2f3ae"

> miner.setEtherbase(eth.accounts[0])
true

> miner.start(1)
null
INFO [06-29|23:21:49] Commit new mining work                   number=1 txs=0 uncles=0 elapsed=317.301µs
INFO [06-29|23:21:49] Successfully sealed new block            number=1 hash=b30264…b9e94d
INFO [06-29|23:21:49] 🔨 mined potential block                  number=1 hash=b30264…b9e94d
INFO [06-29|23:21:49] Commit new mining work                   number=2 txs=0 uncles=0 elapsed=311.3µs
INFO [06-29|23:21:51] Successfully sealed new block            number=2 hash=a9e1ba…136f08
INFO [06-29|23:21:51] 🔨 mined potential block                  number=2 hash=a9e1ba…136f08
INFO [06-29|23:21:51] Commit new mining work                   number=3 txs=0 uncles=0 elapsed=286.197µs
INFO [06-29|23:22:01] Successfully sealed new block            number=3 hash=df146e…b51ba3
INFO [06-29|23:22:01] 🔨 mined potential block                  number=3 hash=df146e…b51ba3

To have multiple nodes on your new blockchain, you will need to use the bootnode utility that is bundled with go-ethereum. If you don't see it, run make all or download their binaries.

On a separate host that will act as the bootnode server:

## Generate a new key
$ bootnode --genkey=boot.key

## Start the service on 10.1.1.9:30301 (your IP:Port)
$ bootnode --nodekey=boot.key -verbosity 9 -addr 10.1.1.9:30301
self=enode://6e297235e51c000b0f5e3f6adb94759e51fee2402da6ce9a4086a98038e70955161583a0d199ccb3b688ef1eb7d10344749bd3dc86af52b6d52fc413ebbd7eb6@10.1.1.9:30301

You may want to define the addr parameter since these binaries for some reason defaults to IPv6 even though it isn't enabled on the server (WTF?). (Side note: I *think* when it binds to [::] it also listens on IPv4.). It's also important to run this bootnode on a separate server because local geth instances won't talk to it properly (another WTF?) even when the specified --bootnodes uses 127.0.0.1 or the local IP address (and it's not because of the firewall or routing either. It's just royally messed up).

With the bootnode set up, you can start the Ethereum nodes with the --bootnodes parameter set to the enode value that was printed by thte bootnode service.

$ geth --datadir /mnt/scratch/ethereum-testnet --bootnodes "enode://6e297235e51c000b0f5e3f6adb94759e51fee2402da6ce9a4086a98038e70955161583a0d199ccb3b688ef1eb7d10344749bd3dc86af52b6d52fc413ebbd7eb6@10.1.1.9:30301" --networkid 139 --rpc   --rpccorsdomain "*"   console

Troubleshooting

If your nodes are not seeing each other:

  1. Check the bootnode service. It should show the nodes pinging.
  2. On the console, run admin.nodeInfo.protocols. Ensure that the genesis and network values are the same.


You can attach using:

$ ./geth --datadir /mnt/scratch/ethereum-testnet --ipcpath ~/ethereum/geth.ipc attach

Dapp Information

Ethereum enables the creation of a decentralized web (web3). A dapp, short for decentralized app, is like a traditional web application built on this decentralized web but with the added ability to interface with contracts on the Ethereum network through the use of libraries that talk to a Ethereum node (via RPC calls).

Ethereum's smart contracts are stored on the block chain as bytecode.

Bytecode is created by compiling code such as Solidity. Other languages are LLL (lisp like) and Serpent (Python)

Getting Started with Dapps

To get started developing contracts with Solidity, get remix.

$ git clone https://github.com/ethereum/browser-solidity
$ cd browser-solidity
$ npm install
$ npm start

To use Remix, navigate to http://localhost:8080/

The environment lets you either test the code in the browser (Javascript VM) or connect to a ethereum node (Web3 Provider).

You may want to unlock your wallet by running on the ethereum console:

$ geth attach
> personal.unlockAccount( personal.listAccounts[0] )

Quick Guide to Solidity

Here is an example contract.

pragma solidity ^0.4.11;

contract Hello {
    string public greeting;
    
    // even that gets logged on block chain...
    event GreetingChanged(string _greeting);
    
    // the constructor
    function Hello(string _greeting) {
        greeting = _greeting;
    }
    
    // sets greeting message
    function setGreeting(string _greeting) {
        greeting = _greeting;
        
        // calls event, this gets logged in block chain?
        GreetingChanged(_greeting);
    }
    
    // gets greeting message
    function greet() constant returns (string _greeting) {
        _greeting = greeting;
    }
}

You can find more contract examples at:

To compile and deploy the contract, click on the 'Create' button. You will see a message 'Waiting for contract to be mined'. Soon afterwards, it should display the transaction cost (gas) and the contract address.

Under the Hood

The code is compiled using solidity. Under geth, this can be accessed using web3.eth.compile.solidity().

The compiled code (bytecode) is deployed to the blockchain and can then be accessed using the ABI definition and the contract address.

The 'Create' button boils down to these sets of operation:

> var compiled = web3.eth.compile.solidity(src)
> var contract = web3.eth.contract(compiled.contract_name.info.abiDefinition)
> var contract_name = contract.new( *any arguments to the constructor*,
    {from: *your account*, 
     data: compiled.contract_name.code,
     gas: *gas limit*
    }, 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);
    }
}
})


Not to be confused with:

Guides:

Examples: https://github.com/pipermerriam/ethereum-alarm-clock http://etheria.world/howto.html

Glossary

Because there are so many foreign terminology kicking around.

Term Definition
web3 A decentralized web. The 'next' iteration of the centralized web as it is (web2).
DAG Directed Acyclic Graph. A ~1GB dataset used by Ethash. Generated for eacah epoch (every 30,000 blocks or 100 hours). The generation of a new DAG takes a long time.
DAO Decentralized Autonomous Organization. Not to be confused with The DAO which was a crowdfunding DAO that got hacked.
Target Block Time The target block time is 15 seconds.
Gas The amount of ether required to compute something on the virtual machine.
Gas limit The limit on how much computation is done for this transaction. Each Opcode uses a specific amount of gas.
Gas Price How much transactions cost.

See Also

To read:

Other Dapps:

Ethereum Disassembly / Bytecode info

Basically a walkthrough, includes info on modifiers

Greeter contract tutorial

Contract Guide

DApp Tutorial

Mining Pool Code