Skip to content

Latest commit

 

History

History
321 lines (198 loc) · 24.9 KB

intro.asciidoc

File metadata and controls

321 lines (198 loc) · 24.9 KB

Ethereum Basics

Control and responsibility

Open blockchains like Ethereum are secure because they are decentralized. That means that each user of Ethereum should control their own keys which control access to their funds and contracts. Some users choose to give up control over their keys by using a third party custodian, such as an exchange wallet. In this book, we will teach you how to take control and manage your own keys.

With that control comes a big responsibility. If you lose your keys, you lose access to funds and contracts. No one can help you regain access - your funds will be locked forever. Here are a few tips to help you manage this responsibility:

  • When you are prompted to choose a password: make it strong, back it up and don’t share it. If you don’t have a password manager, write it down and store it in a locked drawer or safe.

  • When you are prompted to back up a key or mnemonic words, use pen and paper to make a physical backup. Do not leave that task for "later", you will forget

  • Do not store key material (encrypted or not) in digital documents, digital photos, online drives, encrypted PDFs, etc. Don’t improvise security. Use a password manager or pen and paper.

  • Before transferring any large amounts, first do a small test transaction (eg. $1 value). Once you receive the test transaction, try sending it from that wallet. This is a good time to find out you forgot the password.

  • Do not send money to any of the addresses shown in this book. The private keys are listed in the book and someone will immediately take that money.

Ether currency units

Ethereum’s currency unit is called ether, identified also as ETH or with the symbols Ξ (from the Greek letter "Xi" that looks like a stylized capital E) or (more rarely) ♦, for example 1 ether, or 1 ETH, or Ξ1, or ♦1

Tip

Use the HTML code & Xi; and & diams; for the symbols Ξ and ♦ respectively (without a space after the &)

Ether is subdivided into smaller units, down to the smallest unit possible which is named wei. One ether is 1 quintilion wei (1 x 1018 or 1,000,000,000,000,000,000). You may hear people refer to the currency "Ethereum" too but this is a common beginner mistake.

The value of ether is always represented internally in Ethereum as integer multiples of wei. When you transact 1 ether, the transaction encodes 1018 wei as the value.

Ether’s various denominations have a both a scientific name using the International System of units (SI), and a colloquial name that pays homage to many of the great minds of cryptography and computer science.

Table Ether Denominations and Unit Names shows the various units, their colloquial (common) name and their SI name. In keeping with the internal representation of value, the table shows all denominations in wei (first row), with ether shown as 1018 wei in the 7th row:

Table 1. Ether Denominations and Unit Names
Value (in wei) Exponent Common Name SI Name

1

1

wei

wei

1,000

103

babbage

kilowei or femtoether

1,000,000

106

lovelace

megawei or picoether

1,000,000,000

109

shannon

gigawei or nanoether

1,000,000,000,000

1012

szabo

microether or micro

1,000,000,000,000,000

1015

finney

milliether or milli

1,000,000,000,000,000,000

1018

ether

ether

1,000,000,000,000,000,000,000

1021

grand

kiloether

1,000,000,000,000,000,000,000,000

1024

megaether

Choosing an Ethereum wallet

An Ethereum wallet is your gateway to the Ethereum system. It holds your keys and can create and broadcast transactions on your behalf. Choosing an Ethereum wallet is difficult. There are many different options, with different features and designs. Some are more suitable for beginners and some are more suitable for experts. Even if you choose well now, you might decide to change your choice a year from now. Ethereum itself is constantly changing and the "best" wallets change as some manage to keep up and others don’t.

Don’t worry! If you choose a wallet and don’t like how it works, you can change wallets quite easily. All you have to do is make a transaction that sends your funds from the old wallet to the new wallet. In Ethereum (as in all open blockchains), a transaction between your own wallets is indistinguishable from and just as easy as any other transaction.

To get us started, we will choose three different wallets that we will be using throughout in many of the examples: one mobile wallet, one desktop wallet and one web-based wallet. These three wallets are good choices for the readers of this book, as they represent a broad range of complexity and features. The choice of these wallets is not an endorsement of their quality or security. They are good enough for demonstration and testing and we have to start somewhere.

Starter wallets:

MetaMask

MetaMask is a Chrome browser extension wallet that runs in your Chrome browser. It is easy to use and convenient for testing, as it is able to connect to a variety of Ethereum nodes and test blockchains (see [testnets]).

Jaxx

Jaxx is a multi-platform and multi-currency wallet that runs on a variety of operating systems including Android, iOS, Windows, Mac and Linux. It is often a good choice for new users as it is designed for simplicity and ease of use.

MyEtherWallet (MEW)

MyEtherWallet is a web-page based wallet that runs in any browser. It has many sophisticated features that we will explore in many of our examples.

We’ll start by installing MetaMask on our desktop.

Installing MetaMask

Open the Google Chrome browser and navigate to:

Search for "MetaMask" and click on the result showing the logo of a fox. You should see the extension’s detail page like this:

MetaMask Detail Page
Figure 1. The detail page of the MetaMask Chrome Extension

It’s important that you download the real MetaMask extension, as sometimes people are able to sneak malicious extensions past Google’s filters. The real one:

  • Shows the ID nkbihfbeogaeaoehlefnkodbefgpgknn in the address bar

  • Is offered by https://metamask.io

  • Has more than 500 reviews

  • Has more than 800,000 users

Once you confirm you are looking at the correct extension, click "Add to Chrome", to install it.

Using MetaMask for the first time

Once MetaMask is installed you should see a new icon (the head of a fox) in your browser’s toolbar. Click on it to get started. You will be asked to accept the terms and conditions and then you will be asked to create your new Ethereum wallet by entering a password:

MetaMask Password Page
Figure 2. The password page of the MetaMask Chrome Extension
Tip

The password controls access to MetaMask so that it can’t be used by anyone with access to your browser.

Once you’ve set a password, MetaMask will generate a wallet for you and show you a mnemonic backup, consisting of 12 English words. This backup can be used in any compatible wallet to recover access to your funds should something happen to MetaMask or your computer. You do not need the password for this recovery, the 12 words are sufficient.

MetaMask Mnemonic Page
Figure 3. The mnemonic backup of your wallet, created by MetaMask
Tip

Backup your mnemonic (12 words) on paper, twice. Store the two paper backups in two distant secure locations, such as a fire resistant safe, a locked drawer or a safe deposit box. Treat the paper backups like cash of equivalent value as what you store in your Ethereum wallet. Anyone with access to these words gets your money.

Once you have confirmed that you have stored the mnemonic securely, MetaMask shows you your Ethereum account details:

MetaMask Account Page
Figure 4. Your Ethereum account in MetaMask

Your account page shows the name of your account ("Account 1" by default), an Ethereum address (0x9E713…​ in the example) and a colorful icon to help you visually distinguish this account from other accounts. At the top of the account page you can see which Ethereum network you are currently working on ("Main Network" in the example).

Congratulations! You have set up your first Ethereum wallet!

Switching Networks

As you can see on the MetaMask account page, you can choose between multiple Ethereum networks. By default, MetaMask starts on the "Main Network". The other choices are public testnets, any Ethereum node of your choice, or nodes running private blockchains on your own computer (localhost):

Main Test Network

The main, public, Ethereum blockchains. Real ETH, real value, real consequences.

Ropsten Test Network

Ethereum public test blockchain and network, using Proof-of-Work consensus (mining). ETH on this network has no value.

Kovan Test Network

Ethereum public test blockchain and network, using Proof-of-Authority consensus (federated signing). ETH on this network has no value.

Rinkeby Test Network

Ethereum public test blockchain and network, using Proof-of-Authority consensus (federated signing). ETH on this network has no value.

Localhost 8545

Connect to a node running on the same computer as the browser. The node can be part of any public blockchain (main or testnet), or a private testnet (see [ganache]).

Custom RPC

Allows you to connect MetaMask to any node with a geth-compatible Remote Procedure Call (RPC) interface. The node can be part of any public or private blockchain.

For more information about the various Ethereum testnets and how to choose between them, see [testnets].

Tip

Your MetaMask wallet uses the same private key and Ethereum address on all the networks it can connect to. Your Ethereum address balance on each Ethereum network will be different. Your keys may control ether and contracts on Ropsten, for example, but not on the Main Network.

Getting some test ether

Our first task is to get our wallet funded. We won’t be doing that on the Main Network, because real ether costs money and handling it requires a bit more experience. For now, we will load our wallet with some testnet ether.

Switch MetaMask to the Ropsten Test Network. The click "Buy", and click "Ropsten Test Faucet". MetaMask will open a new web page:

MetaMask Ropsten Test Faucet
Figure 5. MetaMask Ropsten Test Faucet

You may notice that the web page already contains your MetaMask wallet’s Ethereum address. MetaMask integrates Ethereum enabled web pages (see [dapps]) with your MetaMask wallet. MetaMask can "see" Ethereum addresses in the web page, allowing you for example to send a payment to an online shop displaying an Ethereum address. Metamask can also populate the web page with your own wallet’s address as a recipient address if the web page requests an address. In this page, the faucet application is asking MetaMask for a wallet address to sent test-ether.

Press the green "request 1 ether from faucet" button. You will see a transaction ID appear in the lower part of the page. The faucet app has created transaction - a payment to you. The transaction ID looks like this:

0x7c7ad5aaea6474adccf6f5c5d6abed11b70a350fbc6f9590109e099568090c57

In a few seconds the new transaction will be mined by the Ropsten miners and your MetaMask wallet will show a balance of 1 ETH. Click on the transaction ID and your browser will take you to a block explorer, which is a web site that allows you to visualize and explore blocks, addresses and transactions. MetaMask uses the etherscan.io block explorer, one of the more popular Ethereum block explorers. The transaction containing our payment from the Ropsten Test Faucet is shown in Etherscan Ropsten Block Explorer

Etherscan Ropsten Block Explorer
Figure 6. Etherscan Ropsten Block Explorer

The transaction has been recorded on the Ropsten blockchain and can be viewed at anytime by anyone, simply by searching for the transaction ID, or visiting the link:

Try visiting that link, or entering the transaction hash into the ropsten.etherscan.io website, to see it for yourself.

Sending ether from MetaMask

Once we’ve received our first test ETH from the Ropsten Test Faucet, we will experiment with sending ether, by trying to send some back to the faucet. As you can see on the Ropsten Test Faucet page, there is an option to "donate" 1 ETH to the faucet. This option is available so that once you’re done testing, you can return the remainder of your test ether, so that somemone else can use it next. Even though test ether has no value, some people hoard it, making it difficult for everyone else to use the test networks. Hoarding test ether is frowned upon!

Fortunately, we are not test ether hoarders and we want practice sending ether anyway.

Click on the orange "1 ether" button to tell MetaMask to create a transaction paying the faucet 1 ether. MetaMask will prepare a transaction and pop-up a window for you to confirm:

Sending 1 ether to the faucet
Figure 7. Sending 1 ether to the faucet

Oops! You probably noticed you can’t complete the transaction. MetaMask says "Insufficient balance for transaction". At first this will seem confusing: we have 1 ETH, we want to send 1 ETH, why is MetaMask saying we have insufficient funds?

The answer is because of the cost of gas. Every Ethereum transaction requires payment of a fee, which is collected by the miners to validate the transaction. The fees in Ethereum are charged in a virtual currency called gas. You pay the gas with ether, as part of the transaction.

Tip

Fees are required on the test networks too. Without fees, a test network would behave differently from the main network, making it an inadequate testing platform.

MetaMask calculates that this transaction will consume 3 GWEI, which stands for 3 gigawei. Wei is the smallest subdivision of the ether currency, as we will discuss in Ether currency units.

All this to say: to make a 1 ETH transaction costs 1.000063 ETH. MetaMask confusingly rounds that down to 1 ETH when showing the total, but the actual amount you need is 1.000063 ETH and you only have 1 ETH. Click "Reject" to cancel this transaction.

Let’s get some more test ether! Click on the green "request 1 ether from the faucet" button again and wait a few seconds. Don’t worry, the faucet should have plenty of ether and will give you more if you ask.

Once you have a balance of 2 ETH, you can again try sending some back. This time, when you click on the orange "1 ether" donation button, you have sufficient balance to complete the transaction. Click "Submit" when MetaMask pops-up the payment window. After all this, you should see a balance of 0.999947 ETH, accounting for the 1 ETH you sent to the faucet and the 0.000063 in gas costs.

Exploring the transaction history of an address

By now you have become an expert in using MetaMask to send and receive test ether. Your wallet has received at least two payments and sent at least one. Let’s see all these transactions, using the ropsten.etherscan.io block explorer. You can either copy your wallet address and paste it into the block explorer’s search box, or you can have MetaMask open the page for you. Next to your account icon in MetaMask, you will see a button showing three dots. Click on it to show a menu of account-related options:

MetaMask Account Context Menu
Figure 8. MetaMask Account Context Menu

Select "View Account on Etherscan", to open a web page in the block explorer, showing your account’s transaction history:

Address Transaction History on Etherscan
Figure 9. Address Transaction History on Etherscan

Here you can see all the transaction history of your Ethereum address. It shows all transactions recorded on the Ropsten blockchain, where your address is the sender or recipient in the transaction. Click on a few of these transactions to look at the details.

You can explore the transaction history of any address. See if you can explore the transaction history of the Ropsten Test Faucet address (Hint, it is the "sender" address listed in the oldest payment to your address). You can see all the test ether sent from the faucet to you and to other addresses. Every transaction you see can lead you to more addresses and more transactions. Before long you will be lost in the maze of interconnected data. Public blockchains contain an enormous wealth of information, all of which can be explored programmaticaly, as we will see in subsequent examples.

Introducing the world computer

We’ve got a wallet and we’ve sent and received ether. So far, we’ve treated Ethereum as a cryptocurrency. But Ethereum is much, much more. The cryptocurrency function is, in fact, subservient to Ethereum’s function as a world computer, a decentralized smart contract platform. Ether is meant to be used to pay for running smart contracts, which are computer programs that run inside an emulated computer called the Ethereum Virtual Machine (EVM).

The EVM is a global singleton, meaning that it operates as if it is a global single-instance computer running everywhere. Each node on the Ethereum network runs a local copy of the EVM to validate contract execution and the Ethereum blockchain records the changing state of this world computer as it processes transactions and smart contracts.

Externally Owned Accounts (EOAs) and Contracts

The type of account we created in the MetaMask wallet is called an Externally Owned Account (EOA). Externally owned accounts are those that have a private key, which controls access to funds or contracts. Now, you’re probably guessing there is another type of account. The other type of account is a contract account. A contract account is owned (and controlled) by the logic of a software program recorded on the Ethereum blockchain and executed by the EVM.

In the future, all Ethereum wallets might be running as Ethereum contracts, blurring the distinction between Externally Owned Accounts and contracts. The important distinction that will always remain is this: A human making decisions (EOA), or a piece of software making decisions (contract).

Contracts have an address, just like EOAs (wallets). Contracts can send and receive ether, just like wallets. When a transaction destination is a contract address, it causes that contract to run in the EVM, using the transaction as its input.

In addition to ether, transactions can contain data indicating which specific function in the contract to run and what parameters to pass to that function. This way, transactions call functions within contracts. Finally, contracts can generate transactions calling other contracts, building complex execution paths.

In the next few sections we will write our first contract. We will then create, fund, and use that contract with our MetaMask wallet and test ether, on the Ropsten test network.

A simple contract

Ethereum has many different high-level languages, all of which can be used to write a contract and produce EVM bytecode. You can read about many of th emost prominent and interesting ones in [high_level_languages]. One high-level language is by far the dominant language for smart contract programming: Solidity. Solidity was created by Gavin Wood, the co-author of this book and has become the most widely used language in Ethereum and beyond. We’ll use Solidity to write our first contract.

For our first example, we will write a contract that controls a faucet. We’ve already used a faucet to get test ether on the Ropsten test network. A faucet is a relatively simple thing: it gives out ether to any address that asks, and can be refilled periodically. You can implement a faucet as a wallet controlled by a human (or a web server), but instead we will write a Solidity contract that implements a faucet:

A Solidity contract implementing a faucet
link:code/Faucet.sol[role=include]

This is a very simple contract, about as simple as we can make it. It is also a flawed contract, demonstrating a number of bad practices and security vulnerabilities. We will learn by examining all its flaws in later sections. For now, however, let’s look at what this contract does and how it works, line by line.

The first line is a comment:

// Version of Solidity compiler this program was written for

Comments are for humans to read and are not included in the EVM bytecode that actually runs. We usually put them on the line before the code we are trying to explain, or sometimes on the same line. Comments start with two forward slashes //. Everything from the slashes and beyond, until the end of that line, is treated the same as a blank line and ignored.

The second line is a version pragma, which declares what compiler version this program was written for:

pragma solidity ^0.4.19;

The Solidity compiler reads it and will produce an error if it is the wrong compiler version. In this case our pragma directive says that this program can be compiled by a Solidity compiler with a minimum version 0.4.19 and minor revisions above that (eg. 0.4.20, but not 0.5.0). Pragma directives are not compiled into EVM bytecode. They are only used by the compiler to check compatibility.

Ok, the next lines are where our actual contract starts:

contract Faucet {

This line declares a contract object, similar to a class declaration in other object-oriented languages like Javascript, Java or C++. The contract definition includes all the lines between the curly braces {} which define a scope, much the same as curly braces are used in many other programming languages.

Next, we declare the first function of the Faucet contract:

function withdraw(uint withdraw_amount) public {

The function is named withdraw, takes one unsigned-integer (uint) parameter named withdraw_amount. It is declared as a public function, meaning it can be called by other contracts. The function definition follows between curly braces:

require(withdraw_amount <= 100000000000000000);

The first part of the withdraw function sets a limit on withdrawals. It uses the built-in Solidity function require to test a precondition, that the witdraw_amount is less than or equal to 100000000000000000 wei, which is the base unit of ether (see Ether Denominations and Unit Names) and equivalent to 0.1 ether. If the withdraw function is called with a withdraw_amount greater than than amount, the require function here will cause contract execution to stop and fail with an exception.

This part of the contract is the main logic of our faucet. It controls the flow of funds out of the contract by placing a limit on withdrawals. It’s a very simple control, but gives you a glimpse of the power of a programmable blockchain: decentralized software controlling money.

Next comes the actual withdrawal:

msg.sender.transfer(withdraw_amount);

A couple of interesting things are happening here. The msg object is one of the inputs that all contracts can access. It represents the transaction that triggered the execution of this contract. The attribute sender is the sender address from the transaction. The function transfer is a built-in function that transfers ether from the contract to the address it is called from. Reading it backwards, this means transfer to the sender of the msg that triggered this contract execution. The transfer function takes an amount as its only parameter. We pass the withdraw_amount value that was the parameter to the withdraw function declared a few lines above.

The very next line is the closing curly brace, indicating the end of the definition of our withdraw function.

Below we declare one more function:

function () public payable {}

This function is a so called "fallback" or default function, which is called if the transaction that triggered the contract didn’t name any of the declared functions in the contract, or any function at all, or didn’t contain data. Contracts can have one such default function (without a name) and it is usually the one that receives ether. That’s why it is defined as a public and payable function, which means it can accept ether into the contract. It doesn’t do anything, other than accept the ether, as indicated by the empty definition in the curly brackets {}. If we make a transaction that sends ether to the contract address, as if it were a wallet, this function will handle it.

Right below our default function is the final closing curly bracket, which closes the definition of the contract Faucet. That’s it!

Compiling the Faucet contract

Creating the contract on the blockchain

Interacting with the contract