How to create a private Ethereum network

By:  Omar Metwally, MD

Objectives:

  1. To create a private Ethereum network
  2. To deploy a simple contract to your private Ethereum network
  3. To interact with a contract on your private Ethereum network

Target audience:  

Ethereum developers.

Necessity: 

The need for this tutorial arises from outdated Ethereum documentation, resulting in hair-pulling, heartburn, and insomnia.

Precautions:

Isolate your development environment, and your private Ethereum network, from any real Ether you might have. It’s easy to compromise your machine and lose real money if you slip up.

Step 1: Set up a virtual server and install Ethereum command-line tools

Many tutorials guide you through deploying contracts using the Ethereum wallet GUI. I’m using the Go Ethereum client (geth) and encourage others to learn how to use the command line interface (CLI). The better you understand the Ethereum client’s internal workings and the anatomy of a blockchain, the more power to you. It doesn’t matter which hosting service you use,  but these instructions assume you’re running an Ubuntu server. [Geth Installation instructions for Ubuntu] 

My private network is called “UCSFnet” at this (fake) IP address 101.102.103.104

Very important: make sure you set aside at least 2GB RAM on your virtual server in order for mining to work. If you skimp on RAM, mining may not work.

Now open a new terminal window, log into your Ubuntu server via SSH and create your working directory called “ucsfnet”

ssh root@101.102.103.104
mkdir ucsfnet
cd ucsfnet
mkdir data
mkdir source

Step 2: Create genesis block

The genesis block is the first block of any blockchain and its parameters are specified in “genesis.json”, which I saved under /root/ucsfnet/genesis.json. My genesis block looks something like this:

{
"config": {
        "chainId": 15,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },

  "alloc"      : {
  "0x0000000000000000000000000000000000000001": {"balance": "111111111"},
  "0x0000000000000000000000000000000000000002": {"balance": "222222222"}
    },

  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x00001",
  "extraData"  : "",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x0000000000000107",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00"
}

Note that chainId=1 refers to the main Ethereum network, so it’s important to create a unique chainId for your network so your client doesn’t confuse your private blockchain with the main network. For the sake of illustration and testing, set mining difficulty to a low value. Also make sure you specify a unique nonce to start out with. The alloc field allows you to pre-populate accounts with Ether.

Now navigate to the directory where you created your genesis.json file and initialize the bootnode, a node through which your Ethereum client can join your private network and interact with other nodes connected to your private network.

cd /root/ucsfnet/data
geth --datadir=/root/ucsfnet/data init /root/ucsfnet/genesis.json
bootnode --genkey=boot.key
bootnode --nodekey=boot.key

Pay attention to the enode address that the previous commands results. You’ll need this for the next step.

Step 3: Connect to your externally reachable bootnode

The bootnode you created in the previous step is externally reachable, and in this step we’re going to connect to that node to create a one-node network. As you go through this tutorial and expand your knowledge of Ethereum networking, you’ll be able to add infinitely many nodes to your private network. The following commands create the geth.ipc file you’ll need to interact with your network in the subsequent steps. However after completing this tutorial, you’ll be able to skip this step the next time you connect to your network if you’re developing/testing and not using any networking protocols.

Open a new terminal window:

ssh root@101.102.103.104

geth --datadir=/root/ucsfnet/data --bootnodes=enode://148f3....@101.102.103.104:3031

Replace 148f3…. above with the enode address from Step 2. Make sure to include the enode://  prefix.

Step 4: Create a new account and check your balance

Start by opening a new terminal window and connecting to your virtual server via SSH:

ssh root@101.102.103.104
geth attach /root/ucsfnet/data/geth.ipc 
> eth.accounts

You’ll notice that there are no account addresses yet. Now you’ll create your first account. Be sure to replace “mypassword” with a strong password. Remember it and keep it safe; Ethereum is unforgiving in that there is no way to unlock your account if you forget your password!

> personal.newAccount("mypassword")
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")

Remember your account’s address, which is prefixed by “0x”. Notice that your account has zero Ether, but don’t be discouraged. I’ll soon turn you into an Ethereum billionaire (but alas, the Ether you collect on your private network is only good on your private network).

Step 5: Mine on your private network

The purpose of mining here is two-fold. First you create Ether which you’ll need to power your transaction through gas (an Ethereum sub-unit). Second, mining incorporates your transactions into the blockchain. Open a new terminal window and connect to your private server:

ssh root@101.102.103.104
geth --datadir=/root/ucsfnet/data --mine --minerthreads=1 --etherbase=0x...

The etherbase parameter specifies the address which should receive the Ether you generate by mining. This should contain your wallet address from Step 4. If you check your account balance again (Step 4), you’ll find that you quickly became a billionaire. Congratulations! Again, the Ether you generate on your private network is only good on your private network, but that’s OK. Your newfound knowledge of how to develop for Ethereum is more valuable than all the Ether in the world.

Step 6: Compile a simple contract

Unfortunately, the official Ethereum documentation has not been updated to reflect the fact that compiling using the solC compiler is no longer possible via RPC. This means that you will end up in a rabbit hole if you try to follow the instructions on the official Ethereum documentation and many other tutorials based on official documentation. There are 2 ways to compile contracts, and I encourage you do try both so you understand what’s going on under the hood.

First install the command-line compiler, solC:

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

Now open a new terminal window, connect to your server via SSH, and navigate to the directory where your source code will live:

cd /root/ucsfnet/source

And save this demo “greeter” contract in /root/ucsfnet/greeter.sol:

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) selfdestruct(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 = "Hello, World!";
 }

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

Now compile this contract using solC:

solc --bin --abi  -o /root/ucsfnet/source /root/ucsfnet/source/greeter.sol 

In the above command, the bin and abi flags tell the solC compiler to generate Ethereum Virtual Machine (EVM) bytecode and an Application Binary Inferface (ABI) file, respectively. The o flag defines an output directory where these files will be created, and the last argument is the location of the contract (*.sol file) you want to compile.

Compiling a contract this way generates two files:

EVM file, indicated by the *.bin extension. This corresponds to the contract bytecode generated by the web-based compiler, which is easier to use and will be described below.

ABI file, indicated by an *.abi extension. An application binary interface is like an outline or template of your contract and helps you and others interact with the contract when it’s live on the blockchain.

Open both files using vim or your text editor of choice to see what they contain. Understanding what these files contain will make deploying and interacting with your contracts much clearer.

Alternatively, you can use the online compiler. This is easier because you can just copy-paste your Solidity code. However both methods are equivalent, and I’ll elaborate on this below. Copy and paste the code in greeter.sol (above) into the online compiler. Give it a second, and then click on the “Contract details…” link. Notice that the contents of the Bytecode field are equivalent to the greeter.bin file that you created using solC. Also notice that the Interface field is equivalent to the contents of the greeter.abi file you created when you compiled using the command-line solC compiler.

Step 7: Deploy a “Greeter” contract to your private network

Copy the contents of the Web3 deploy field in the online compiler. Paste them into a text editor on your computer and note the bolded changes I made:

var _greeting = 'UCSFnet lives!';

var browser_ballot_sol_greeterContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"type":"constructor"}]);

var browser_ballot_sol_greeter = browser_ballot_sol_greeterContract.new(

  _greeting,

  {

    from: web3.eth.accounts[0],

    data: '0x6060604052341561000f57600080fd5b6040516103dd3803806103dd833981016040528080518201919050505b5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6040805190810160405280600d81526020017f48656c6c6f2c20576f726c642100000000000000000000000000000000000000815250600190805190602001906100b99291906100c1565b505b50610166565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010257805160ff1916838001178555610130565b82800160010185558215610130579182015b8281111561012f578251825591602001919060010190610114565b5b50905061013d9190610141565b5090565b61016391905b8082111561015f576000816000905550600101610147565b5090565b90565b610268806101756000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610049578063cfae32171461005e575b600080fd5b341561005457600080fd5b61005c6100ed565b005b341561006957600080fd5b61007161017f565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b25780820151818401525b602081019050610096565b50505050905090810190601f1680156100df5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561017c576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b610187610228565b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561021d5780601f106101f25761010080835404028352916020019161021d565b820191906000526020600020905b81548152906001019060200180831161020057829003601f168201915b505050505090505b90565b6020604051908101604052806000815250905600a165627a7a7230582069d50e4318daa30d3f74bb817c3b0cb732c4ec6a493eb108266c548906c8b6d70029',

    gas: '1000000'

  }, function (e, contract){

   console.log(e, contract);

   if (typeof contract.address !== 'undefined') {

        console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);

   }

})

Save the above as myContract.js.

Before we proceed, make sure your account balance is non-zero and that your account is unlocked. If your balance is too low, or if your account is locked, you won’t be able to deploy your contract. Follow the above steps to make sure you generate Ether by mining, and unlock your account as follows (replacing mypassword with the password you invented while creating your account):

Open new terminal window:

ssh root@101.102.103.104 
geth attach /root/ucsfnet/data/geth.ipc 
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
> personal.unlockAccount(eth.accounts[0], "mypassword")

If I’ve lost you, pay attention here because this is important. This is where the Ethereum documentation hasn’t been updated yet, creating confusion regarding how contracts are compiled. Note that the web3.eth.contract() function takes as an argument an ABI. This is the same as the greeter.abi file you created using the solC compiler! Also note that the data field is equivalent to the greeter.bin EVM bytecode, with the exception that it’s prefixed by “0x”. 

Time to deploy your contract:

loadScript(myContract.js)

You should see something like:

Contract mined! address: 0x4000737c8bd7bbe3dee190b6342ba1245f5452d1 transactionHash: 0x0a4c798467f9b40f2c4ec766657d0ec07c324659ea76fcc9c8ad28fc0a192319

Congratulations! Your contract lives at the following address on your private blockchain:

0x4000737c8bd7bbe3dee190b6342ba1245f5452d1

Make a note of this. You’ll need your contract’s address to interact with it (and allow others to do the same).

If this didn’t work, make sure you’re actively mining in another window so that your transaction is incorporated into the blockchain.

Step 8: Interacting with a contract

Again, this is another place where the Ethereum documentation hasn’t yet been updated and refers to deprecated functions. With your geth client fired up, try the following:

> var abi = '[{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"type":"constructor"}]'
> var abi = JSON.parse(abi)
> var contract = web3.eth.contract(abi)
> var c = contract.at("0x4000737c8bd7bbe3dee190b6342ba1245f5452d1")
> c.greet()

The first 3 inputs above define what the contract looks like via its ABI. The contract.at() method takes as an argument the address where your contract lives.

You should see the following output:

UCSFnet lives! 

Big caveat: geth chokes if any of your inputs contain illegal characters. Id est:

“ (illegal) is not equal to  " (legal) 

        and

‘ (illegal) is not equal to ' (legal) 

Conclusion

We covered a lot of ground here, from setting up your own Ethereum network to compiling your contract (and avoiding rabbit holes created by outdated documentation) to deploying the contract and interacting with it. Whew! If you ever get stuck and need to start over, just reboot your server and delete your blockchain (understanding the implications of what this means…):

rm -R /root/ucsfnet/data/geth/chaindata

“Wir werden von so manchen Despoten – etwa Institutionen, Überzeugungen oder auch Neurosen – beherrscht, die wir aus dem Weg räumen können, wenn wir sie analysieren und verstehen.”

We are ruled by so many despots — institutions, convictions, and neuroses — which we can clear away, if we analyze and understand them

— Isaiah Berlin

Portland smoke

Support my research!

If you find this information helpful, please consider supporting my research by donating Ether or Bitcoin. Equitable, transparent, high-quality healthcare for all!

ETH donations:  0x1b4Ba9c1811233805dC4f12Ca32F22cfD85DB212

BTC donations:  1Ef7oYi1zVpA4bw7hUcD8841wbdtCw4Xen

Suggested reading:

  • Nice low-level description of networking in Ethereum (uses the Python-based client):

https://ocalog.com/post/10/ 

  • Setting up private network or local cluster

https://github.com/ethereum/go-ethereum/wiki/Setting-up-private-network-or-local-cluster

  • Connecting to the network

https://github.com/ethereum/go-ethereum/wiki/Connecting-to-the-network

  • The Go Ethereum client

https://github.com/ethereum/go-ethereum

  • Official Ethereum command line tool documentation

https://ethereum.org/cli

Learn Ethereum the hard way

Clear Paper

 

Note: In the spirit of open collaboration, I’m  keeping a public lab notebook of my work as a Clinical Informatics Fella at UCSF. Whether you cite or steal this, remember to build cool things that help people live healthier lives.

 

Educational objectives

There are a number of excellent technically focused blog posts on Ethereum out there. If you are interested in building Ethereum applications, I recommend making your way through these technical references (see end of article). This article is intended for non-technical readers interested in understanding, on a high level, the real-world implications of Ethereum’s application paradigm. More specifically, you should be able to answer these questions after reading this article:

  • What is Ethereum and how does it work?
  • Should I use Ethereum for my project?
  • What are the pros & cons of Ethereum?

 

Welcome to Hell

Let’s pretend you have a crazy boss (let’s call her Mary) who’s set on making your life difficult. You and Mary meet every month to check in and make sure you’re both on track. Mary takes out her notebook and takes notes while you share with her what’s going well and what’s not going as well. Because you’re an honest (and somewhat naive) person who hasn’t yet encountered someone like Mary, you start using these meetings as opportunities to speak openly, give and receive feedback, finding comfort in the fact that Mary’s faithfully keeping a record — a ledger — of your conversations. A month passes, and then two months, and Mary’s insanity pervades the workplace. With each subsequent meeting with Mary, she seems to glare at you with wider crazy-eyes, clench her teeth until they sound like they’re about to crack, and stabs her pen ever harder into her notebook while she keeps records of your discussions.

Three months into your job, you’re fed up with her madness and decide to resign (fortunately, you’re not a medical resident or other indentured servant and have the freedom to do so). Mary leads you to a quiet corner, throws a death stare at you, and growls: “If you resign, I will personally make sure you never find a job ever again.” By this point, the stench of bodies in Mary’s closet is overwhelming, and you email Mary to give 30-day notice. Then all hell breaks loose.

In following month, Mary copies you on several emails to her bosses. One of the emails accuses you of harassing her assistant (whom you’ve never interacted with). Another email warns you of several missed deadlines (for projects which never existed). Some emails state that no one has been able to reach you by email or phone (you’ve answered every call and email in the most timely fashion). You’re neither the first nor last of Mary’s victims, and you quickly learn that she’s more than a psychopath, she’s also written the book on psychological manipulation, deception, and torture. She’s creating a fictitious paper trail by sending contrived emails and writing a book of alternative facts, which her complicit assistant is co-authoring.

How can you shed light on Mary’s evil tactics and show others that her ledger is as legitimate as an acid trip? Because you’re a clever hacker, you decide to use Ethereum to shed light on a rancid situation.

Magic-Mushrooms-768x443.jpeg

 

A Distributed Ledger 

Pretend the Ethereum “blockchain” is a magic notebook that serves as a ledger. This notebook can appear in anyone’s hands, and every copy of this notebook is identical. This magic notebook is so smart it can understand your commands and write on its own pages. When one of its pages is written on, the other notebooks vote whether to accept the new page. If they do accept the new page, this change is reflected in every magic notebook. These magic notebooks follow you into meetings with Mary and record their own version of “the truth.” Each page in this notebook is analogous to a “block” in a “blockchain.”

So you buy yourself a magic notebook and bring it to your next meeting with Mary. As usual, she’s preparing her own notebook of alternative facts.  Her assistant, Karen, also shows up to the meeting with her own notebook of alternatively alternative facts. So there you are, in Mary’s office with Mary and Karen, everyone clutching their notebooks.

You:  "I quit."  (magic notebook hears this and writes it on page 1)

Mary:  "Good riddance." (magic notebook hears this and writes it on page 2)

You:  "Before I leave, you still owe me a paycheck." (magic notebook hears this and writes it on page 3)

Karen:  "You picked up the paycheck last week. We owe you nothing." (magic notebook hears this and writes it on page 4)

You:  "No you didn't. I've been asking you for that paycheck for weeks."(magic notebook hears this and writes it on page 5)

Realizing this is going no where, you walk out of Mary’s office carrying your magic notebook.

You next see Mary and Karen in court: you’re suing them for unpaid wages, and you bring along your magic notebook to set the facts right. When the judge asks you when you announced that you’re quitting, your magic notebook recites what’s written on page one: your statement (“I quit”) along with a timestamp. Mary and Karen jump to their feet and hold up copies of their own notebooks. However, the judge did her research on this new magic notebook, which is reputed to be the best ledger in the history of mankind because it doesn’t rest in any one person’s or organization’s hands. The truth doesn’t rest in Mary or Karen’s notebooks or email inboxes (or in either of their minds); the truth — the Ethereum ledger — is the account provided by the magic notebook, which is in everyone’s hands and is guaranteed to contain the same text on every page .

It’s worth repeating emphatically here that the Ethereum blockchain is a distributed ledger. 

Realizing the signifiance of this jargon-laden statement, you decide to go further than just shedding light on Mary’s career of lies and deception. You’re going to make Mary pay for all of the people she’s abused and manipulated over the years, and you’re going to do it with Ethereum. As you study this article and read more about how Ethereum works, you realize that the magic notebook is more than just a record of events. The notebook can execute logic (in the form of “contracts”) and store/modify/delete data. This is one big difference between Bitcoin and Ethereum. A Turing-complete system, such as Ethereum, can execute logic; unlike Bitcoin, the Ethereum Virtual Machine (EVM) is a stack machine. You can write contracts that transfer money and include basic logic to allow others to interact with your contract in a transparent manner. Anyone interested in examining a contract can do so.

If you had heard of Ethereum before you started working for Mary, you could have written a contract that states something like:

 

MARY SENDS MAGIC NOTEBOOK $100,000 EVERY MONTH

EVERY 2 WEEKS, MAGIC NOTEBOOK SENDS ALL EMPLOYEES $5,000

IF AN EMPLOYEE RESIGNS:

    MAGIC NOTEBOOK SENDS THEM A FINAL PAYCHECK

    MAGIC NOTEBOOK REMOVES THEM FROM LIST OF EMPLOYEES

 

Unlike a traditional contract, Ethereum contracts:

  • are transparent and can be examined by anyone
  • are trustless, meaning they execute faithfully and automatically
  • do not need lawyers or courts for interpretation

As your knowledge of Ethereum grows, you realize that you would have been better off writing your employment contract on the Ethereum blockchain rather than relying on Mary and her team of corporate attorneys. Had your contract been written on the Ethereum blockchain, you wouldn’t have had to rely on Mary’s sanity or lack thereof to get paid. The codified contract would execute autonomously, can be reviewed by you or anyone else, and does not need middlewomen/middlemen to interpret or execute (Auf Wiedersehen lawyers, HR staff, administrators, etc). In case Mary was still delusional enough to argue with the Ethereum ledger, the magic notebook would quickly provide proof of payment (or lack thereof) and the conditions under which the logic was executed. The logic on the Ethereum blockchain is transparent.

The current paradigm of hosting applications on a private server is analogous to doing business with Mary and Karen. The logic is centralized and opaque. I trust most applications about as much as I trust Mary and Karen. The average application is hosted on one or a cluster of privately owned and operated servers, and most applications are not open source (and even if they are open source, the average user doesn’t have the means to perform checksums and make sure they’re running the code they think they are). If the server crashes or the application behaves in unexpected ways, well, hard luck fella. Why would anyone trust the software equivalent of Mary & Karen when they could trust a decentralized ledger running autonomously executing logic?

Without getting too bogged down in details, I include this simple example of an Ethereum contract that creates a simple voting mechanism.

pragma solidity ^0.4.0;
contract Ballot {

struct Voter {
 uint weight;
 bool voted;
 uint8 vote;
 address delegate;
 }
 struct Proposal {
 uint voteCount;
 }

address chairperson;
 mapping(address => Voter) voters;
 Proposal[] proposals;

/// Create a new ballot with $(_numProposals) different proposals.
 function Ballot(uint8 _numProposals) {
 chairperson = msg.sender;
 voters[chairperson].weight = 1;
 proposals.length = _numProposals;
 }

/// Give $(voter) the right to vote on this ballot.
 /// May only be called by $(chairperson).
 function giveRightToVote(address voter) {
 if (msg.sender != chairperson || voters[voter].voted) return;
 voters[voter].weight = 1;
 }

/// Delegate your vote to the voter $(to).
 function delegate(address to) {
 Voter sender = voters[msg.sender]; // assigns reference
 if (sender.voted) return;
 while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
 to = voters[to].delegate;
 if (to == msg.sender) return;
 sender.voted = true;
 sender.delegate = to;
 Voter delegate = voters[to];
 if (delegate.voted)
 proposals[delegate.vote].voteCount += sender.weight;
 else
 delegate.weight += sender.weight;
 }

/// Give a single vote to proposal $(proposal).
 function vote(uint8 proposal) {
 Voter sender = voters[msg.sender];
 if (sender.voted || proposal >= proposals.length) return;
 sender.voted = true;
 sender.vote = proposal;
 proposals[proposal].voteCount += sender.weight;
 }

function winningProposal() constant returns (uint8 winningProposal) {
 uint256 winningVoteCount = 0;
 for (uint8 proposal = 0; proposal < proposals.length; proposal++)
 if (proposals[proposal].voteCount > winningVoteCount) {
 winningVoteCount = proposals[proposal].voteCount;
 winningProposal = proposal;
 }
 }
}
[Source:  https://solidity.readthedocs.io/en/develop/solidity-by-example.html%5D

 

Why develop on Ethereum?

Now that you know how Ethereum works, you have the luxury of living to witness one of the most interesting, exciting, and important developments in computing, and you too can design and develop applications on the Ethereum blockchain. Why not write an employment contract on the Ethereum blockchain that gives you and your peers a democratic way of removing problematic elements in the workplace? Or an employment contract that distributes an organizations profits more equitably and transparently? But before you can decide whether it makes sense to ditch a virtual server running your standard Python/Ruby/NodeJS/PHP/[fill in the blank] stack in favor of Ethereum, you should note a few more pros and cons of Ethereum:

Unlike the Bitcoin protocol, which is a distributed ledger of transactions based on monetary (Bitcoin) inputs and unspent transactional outputs, Ethereum is account-based. This is getting into technical details that may not interest the intended audience of this post, but it should be noted that in Ethereum there are account addresses identify users as well as individual contracts written to the Ethereum blockchain. Like Bitcoin, the Ethereum protocol is based on a cryptocurrency called Ether, which is used to fund all transactions on the Ethereum blockchain (more on this below). And just like an address that you can use to send and receive Bitcoin and Ether payments, your Ethereum contracts also have addresses which function as handles to allow users to interact with your code and identify it on the Ethereum blockchain.

 

Basic anatomy of an Ethereum contract

An Ethereum contract consists of the code you write and the state of the contract (i.e. the data associated with the contract). As described in the Solidity documentation, the magic happens in between the curly brackets, the body of a contract:

contract requestFile {

    // stuff happens here ...

}

The “stuff” consists of state variables, functions, function modifiers, and events, which will look familiar to you if you’re fluent in one of many programming languages that use these paradigms.

State variables are permanently stored in contract storage and include types such as integers (int and uint), booleans (bool), addresses (address, address.balance, address.transfer), fixed and dynamically-sized byte arrays (bytes, string), string literals, enums, structs, and mappings (similar, but not identical to, hash tables). The EVM uses standard logical operators, including comparison operators, bit operators, and index access. See the reference above for more details.

How large is a contract storage area? Vitalik Buterin answers this here. Bottom line: 2^261 bytes. That means that you’ll never really be limited by size, but rather, by the cost of conducting transactions on the Ethereum blockchain (see “Economics of Ethereum contracts” below).

Functions work similarly to other programming languages and take the form of:

function audit() returns (address addr) {
    // stuff happens here...
}

As described in the Solidity documentation, functions can be called internally or externally and have different levels of visibility, like in programming languages such as C++, Java and Python.

Function modifiers “amend the semantics of functions in a declarative way.” I’ll skip the technical details here.

Events are basically functions that use the EVM’s logging mechanism. If you’ve developed Android apps, you’ve probably used something similar.

If you’re itching to deploy a real contract to the Ethereum blockchain, check out my earlier tutorial.

 

Economics of Ethereum contracts

On a macro scale, Ethereum is a giant computer powered by every machine running the full Ethereum client. Just like every step and breath we take costs energy, so too does every computation performed by your computer require a finite amount of electrical energy. The Ethereum network is no different. The energy required to keep adding blocks to the blockchain, transfer Ether, and execute contracts is provided in the form of “gas” (an Ethereum subunit). Unlike a local machine such as your laptop, and unlike a virtual server (which runs on a real machine too), Ethereum contracts are interpreted by the Ethereum Virtual Machine, the stack machine that converts Solidity code into instructions to interact with the Ethereum blockchain.  Unlike the Bitcoin protocol, in which each transaction has a predictable cost to the network, the cost of transactions on the Ethereum blockchain depends on bandwidth consumed, computational power, and the size of data that’s being manipulated. Each transaction specifies how much gas it is willing to consume and a gas price. In the event of unused gas, the sender receives gas_rem * gas_price, and the miner of the block receives a reward of (startgas-gas_rem) * gas_price. Id est, there is a cost of conduction transactions, and miners, are rewarded financially for using their own computational power to create new blocks on the blockchain and keep the ledger going.

The economics of current application development profoundly shape how software is developed and used. Many consumer-facing applications are available for a cost on app stores or can be downloaded for a fee; many other consumer-facing applications are supported by adverts, in-app purchases, and subscription fees. Ethereum’s transactional economics were designed to safeguard against malicious agents, and understanding the Ethereum blockchain economy is important to understanding how applications on the Ethereum blockchain will function. This is illustrated in the “Security considerations” section below.

There are some good websites with details on Ethereum economics, including Ethereum’s Design Rationale and Ethereum Gas Economics.

 

Security considerations

What better way to learn good security practices on the Ethereum blockchain than to confront the most malicious of actors, your former wicked boss? While you’ve been writing Ethereum applications, Mary learned a thing or two about this Ether thingy and wrote their own contract to hinder the Ethereum network and suck your account dry of Ether. Let’s say that Mary tricks her next hapless victim into executing an Ethereum contract that does the following:

contract youGotPunked {

    function newEmployee(address dest, uint employeeId) {
        while(true) { };
    }
}

Mary is tricking her next batch of employees who aren’t savvy enough to study the contract into calling an infinite loop. If you’ve ever written an infinite loop on your machine, you know you can hang your machine by wasting all of your machine’s computing resources on executing a loop that does nothing forever. Mary’s new employees call the contract, which then runs forever, wasting computing resources across the Ethereum network. Because each transaction (such as calling the above contract) costs gas, Mary can’t use this old trick to lock up the Ethereum network.

Mary goes back to the drawing board and comes up with another contract (this example is also provided in the Solidity documentation):

contract TxAttackWallet {
    address owner;

    function TxAttackWallet() {
        owner = msg.sender;
    }

    function() {
        TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
    }
}

When Mary’s hapless new employees call this contract, it empties all of their funds (msg.sender.balance) into Mary’s account (address owner). People have used their understanding of Ethereum’s blockchain and simple tactics such as this account emptying trick to transfer hundreds of millions of dollars worth of Ether in unexpected ways. Bottom line: there is no such thing as a perfectly secure system. The amount of energy expended in securing a system should be proportional to what’s at stake. Ethereum is no more or less inherently secure than Google or Microsoft’s applications.

 

Ethereum in healthcare 

I’m drawn to an Ethereum-based electronic health record for the same reasons I wouldn’t want anything to do with Mary and Karen. The next generation of EHRs on a blockchain should:

  • be secure, with fail-proof access control
  • be infallible, with mechanisms to deter malicious attacks on the network
  • be distributed, so that patients, providers, and researchers can benefit from responsible use data
  • be distributed, so that inter-operability is a given
  • be distributed, so that data is never lost (while preserving consensus)
  • be transparent, so that there’s an audit trail of who is accessing what
  • be transparent, so that there’s an audit trail of all transactions on the blockchain
  • be transparent, allowing health services to be rendered in the most cost-effective way possible
  • be autonomous, allowing health services to be rendered without costly third-parties who currently monopolize health data

 

Now enough White, Yellow, Mauve and Clear Papers. Let’s see some code!

 

Acknowledgements

“It’s only work if you’d rather be doing something else” (JM Barrie). I couldn’t think of a better way to spend my time, thanks to this opportunity to be a Clinical Informatics Fella at UCSF Medical Center. I’m grateful to UCSF’s Department of Hospital Medicine, my mentor, Dr. David Avrin, and my colleagues Dr. Michael Wang and Dr. Steven Chen, for their support and feedback.

 

References

  1. https://solidity.readthedocs.io/en/develop/solidity-by-example.html
  2. https://remix.ethereum.org
  3. http://ethdocs.org/en/latest/
  4. https://github.com/ethereum/wiki/wiki/Design-Rationale
  5. https://en.wikipedia.org/wiki/Bloom_filter
  6. https://ethereum.github.io/yellowpaper/paper.pdf
  7. http://whatthefuckisethereum.com/#nerd