Professional Documents
Culture Documents
CONTENTS
GETTING STARTED WITH Introduction
Summary
BY SEBASTIAN L.K. MA
• Events
The following text of this Refcard highlights fundamental
information on the Ethereum Blockchain and the basic steps to get
FURTHER READING:
a private blockchain up and running. At the end of this Refcard, you
• solidity.readthedocs.io/en/develop/contracts.html?highlight=c
should be able to set up two running nodes on one local machine.
onstructor#creating-contracts
Smart Contracts are compiled to bytecodes. These bytecodes are • Functions that change the state(s) of a contract will trigger
deployed as instances of Smart Contracts in the Ethereum Virtual a Transaction.
Machine (EVM). E.g.
> myContract.setTimeIn(“08:45”)
• The Transaction has to be mined to take effect. For example,
later sections will show that you can check pending
transactions using the API eth.pendingTransactions().
• Mining is “competitively performed” by peer nodes. For
example, later sections will show this by using the API
miner.start().
• The creation process triggers a Transaction. • The new block will be validated, verified, and its transaction
executed locally by peer nodes to be become an official
• The Transaction has to be mined to take effect. For example,
block in their local blockchains.
later sections will show that you can check pending
transactions using the API eth.pendingTransactions().
GETH
• Mining is “competitively performed” by peer nodes. For
Geth is an implementation of a full Ethereum node written in the
example, later sections will show this by using the API
Go programming language. It is a command line process.
miner.start().
• On successful mining by a node, a new Block is created, Automated builds are available for stable releases and the
which contains the Transaction and Contract Address. unstable master branch. Binary archives are published here.
• The mining node will broadcast the new Block to peer nodes. You will be executing geth from the command line. Set your
• The new block will be validated and verified by peer nodes search PATH accordingly. For example, my geth was installed in
to be become an official block in their local blockchains. a sub-directory, geth-alltools-windows-amd64-1.6.5-cf87713d. I
set my path as:
• The new instance of the Smart Contract contains a
unique address. This address must be saved, recorded, or set PATH=%PATH%;C:\dev\ethereum\geth-alltools-
registered. It will be retrieved for subsequent “contract windows-amd64-1.6.5-cf87713d
execution.”
CREATING YOUR PRIVATE BLOCKCHAIN
SMART CONTRACT EXECUTION Assuming our current working folder is C:\dev\ethereum, create
A Smart Contract contains functions that can be executed by an the following 3 sub-folders:
External Account or a Decentralized Application (DAPP). In the case
of a DAPP, the executing node would have a default External Account. • C:\dev\ethereum\geth\data\00 ← This folder contains
the default Genesis block data.
For node 2, the listening port 30304 and the rpc port must be
{
"config":{ explicitly specified.
"homesteadBlock":10
}, geth --datadir "C:\dev\ethereum\geth\data\02" --ipcpath
"nonce": "0x0000000000000042", geth02 --port 30304 --nodiscover --networkid 1234 --rpc
"timestamp": "0x00", --rpcport 8546 --rpccorsdomain "*" console 2> "C:\dev\
"parentHash": "0x000000000000000000000000000000000000 ethereum\geth\data\02\console.log"
0000000000000000000000000000",
"extraData": "0x00",
"gasLimit": "0x8000000",
ATTACHING TO GETH NODE INSTANCES
"difficulty": "0x400",
"mixhash": "0x000000000000000000000000000000000000000 With both nodes started up, they are running as a server
0000000000000000000000000",
process, waiting for events and commands to be executed. You
"coinbase": "0x3333333333333333333333333333333333333
333", should not interrupt the server process by entering commands
"alloc": {} in its console window. Instead, you should send commands to it
}
from another client process.
DATA DIRECTORIES This is achieved by starting another geth process as a client and
If your data directories are not yet created, create a data connecting it to the geth server process.
directory for each node in your private blockchain.
Once attached, you can then send interactive commands to
For instance, below are two data directories for two running the server process. You can do this by first attaching your geth
nodes in one machine. client to a geth server process.
C:\dev\ethereum\geth\data\01 ← This is the folder for the This command line attaches to geth node 1 via namepipe:
first geth node.
geth attach ipc:\\.\pipe\geth01
C:\dev\ethereum\geth\data\02 ← This is the folder for the
second geth node. Attaching to geth node 2 via namepipe:
Each data directory will therefore store an individual node’s geth attach ipc:\\.\pipe\geth02
blockchain data.
Below are four screenshots, where the top two console windows
INITIALIZING THE DATA DIRECTORY
are geth server processes and the bottom two console windows
Before starting up the geth nodes, their data directories must
are the geth clients.
be initialized.
Below are the command lines to initialize the nodes with the
default genesis data.
To initialize node 1:
To initialize node 2:
geth --datadir "C:\dev\ethereum\geth\data\02" init "C:\
dev\ethereum\geth\data\00\ DefaultGenesis.json"
EVENTUAL CONSISTENCY
> admin.nodeInfo
{ Below is a demonstration of eventual consistency between the
enode: "enode://b71b3f6e23f33a07d30b862dd53f3364e46057b two nodes.
85183b4d0d856a4f7…831ab@[::]:30303?discport=0",
From node 1: Both nodes will have the same number of blocks in their
> admin.peers
blockchain.
[{
caps: ["eth/63"], From either node, as shown below, you can query the number of
id: "deb200d8ea9c67dd9675b920072145576311d20cb229e8 blocks by using the function eth.blockNumber.
0e….3b9cbbf580ca261f85c3c642fbb7b8eb7a131ee",
From node 2:
> admin.peers
[{
caps: ["eth/63"],
Both nodes will get the same block per block number, e.g. hash
id: "b71b3f6e23f33a07d30b862dd53f3364e46057b85183b4… shown below, being mined by node 1:
db399c0c227ec9158512a5a8e2d883efab7831ab",
> eth.getBlock(30)
{
difficulty: 132864,
ADD A NEW ACCOUNT
extraData:
We have to add our first account to the blockchain of node 1 so "0xd983010605846765746887676f312e382e338777696e646f7773",
that the account can be used for executing transactions. This is gasLimit: 130340787,
gasUsed: 0,
the External account, owned by a person. hash: "0xab2afb75d7082e0f62432ed518e6596643e158343c83a
f4a6b20f60a08480f75",
From node 1, enter the function personal.newAccount and logsBloom: "0x0000000000000000000000000000000000…00000
000000000000000000000000000000000000000000",
provide your password. This function will return the address of
miner: "0x4799c873f6574b299854bfd831ae99ad2e664e30",
the newly created account.
Alternatively, you can pass in the last block number to the eth.
> personal.newAccount(<".....you password here.....">)
"0x4799c873f6574b299854bfd831ae99ad2e664e30" getBlock function and get the miner address directly:
> eth.getBlock(eth.blockNumber).miner
The string of numbers and letters is the address of the new "0x4799c873f6574b299854bfd831ae99ad2e664e30"
account in node 1.
Important: There is no way to restore your account if you For any node to start mining, it requires an external account.
forget your password. Never forget your password. Keep it in a Hence, we now add a new external account in node 2’s client
safe place, and do not store it on your machine. console:
/**
* Constructor
*/
function BillPayment(string _customerId, uint _
contractAmount) public {
customerId = _customerId;
contractAmount = _contractAmount;
balance = _contractAmount; To deploy the smart contract to node 1, change the Execution
} environment drop-down selection to “Web3 Provider” as
/** shown below. Accept the default Web3 Provider endpoint as
* Running node receives payment for this customer localhost:8545
contract instance.
*/
function receivePayment(uint _payment) public {
if (isCompleted()) return;
payment = _payment;
balance -= payment;
if (balance <= 0) {
balance = 0;
completed = true; Once switched, it uses the first account address for transaction
}
execution (see Transaction origin).
}
/**
* Get the customer ID. CREATE YOUR FIRST SMART CONTRACT INSTANCE
*/ Our BillPayment smart contract constructor requires two
function getCustomerId() constant returns (string) {
return customerId; parameters: the _customerId string and _contractAmount
} integer. To create an instance, you can provide these values in
/**
the textbox shown below, then click on the Create button.
* Get the contract amount.
*/
function getContractAmount() constant returns (uint)
{
return contractAmount;
}
/**
*/
function getPayment() constant returns (uint) {
Notice the authentication Error message as displayed below.
return payment; To create a new instance, you will have to provide the account
}
address and its password.
/**
* Indicates if contract is fully received.
*/
function isCompleted() constant returns (bool) {
return completed;
}
} From the node 1 client console, enter eth.accounts. This
function will return a list of accounts, which we created earlier
FURTHER READING: (in this case, we created only one external account).
• solidity.readthedocs.io/en/develop/introduction-to-smart- > eth.accounts
contracts.html ["0x4799c873f6574b299854bfd831ae99ad2e664e30"]
We will unlock this account with its password in quotes " " using > miner.start(1)
the personal.unlockAccount function. null
…
> personal.unlockAccount(eth.accounts[0], <"...your > eth.pendingTransactions
password...">) []
true > miner.stop()
true
An authentication error is displayed again because changing the Transaction,” you copied the address of the contract (e.g. in my
state of a smart contract instance will trigger a new transaction. example, the contract address is “0xf125233002884fd827947d
You can unlock the account using the function personal. 21b1fa377d4b6bbc4d”).
unlockAccount again (refer to the section, “Create Your Smart
First Contract Instance”). In Browser-Solidity, scroll to the section below.
You can verify this transaction hash by looking at the hash value
from the pending transactions.
CREATE A TRANSACTION FROM ANOTHER NODE
> eth.pendingTransactions
This section describes and demonstrates that mining nodes in your [{
private blockchain network is synchronized and that it competes blockHash: null,
blockNumber: null,
for mining transactions. Again, we will show this manually by: from: "0x5be060fa31a851a20a4739dc8d45619f6d292461",
gas: 90000,
• Creating a transaction from node 2.
gasPrice: 18000000000,
hash:
• Mining the transaction from node 1.
"0x42bdf8d4ee6bc3ad7189989c0b266cdea9695a0865b10ecf6348
• Verifying the result from node 2. f3493d5ab69c",
input: "0xe2eab483000000000000000000000000000000000
00000000000000000000000000000c8",
From both the node 1 and node 2 client consoles, which nonce: 1,
are attached to their respective server processes, enter the r: "0x9105c46414ecd30d5008f7e42c3757bbeffa4dfc88c19
cbc41b6fbc93d85f639",
command functions shown in the screenshot below. s: "0x51b9229643e7c39eefaca0fa7d04f4698529239a74c38
a695e215ce4d2a409ee",
to: "0xf125233002884fd827947d21b1fa377d4b6bbc4d",
transactionIndex: 0,
v: "0x1c",
our smart contract functions getPayment() and getBalance() The final screenshot below shows node 1 and node 2 in their entirety.
respectively) are indeed correct.
> eth.pendingTransactions
[{
blockHash: null,
blockNumber: null,
from: "0x5be060fa31a851a20a4739dc8d45619f6d292461",
gas: 90000,
gasPrice: 18000000000,
hash: "0x42bdf8d4ee6bc3ad7189989c0b266cdea9695a0865
b10ecf6348f3493d5ab69c",
input: "0xe2eab48300000000000000000000000000000000
000000000000000000000000000000c8",
nonce: 1,
r: "0x9105c46414ecd30d5008f7e42c3757bbeffa4dfc88c
19cbc41b6fbc93d85f639", SUMMARY
s: "0x51b9229643e7c39eefaca0fa7d04f4698529239a74c
38a695e215ce4d2a409ee", Read-only function calls do not create new Transactions. These
to: "0xf125233002884fd827947d21b1fa377d4b6bbc4d", functions do not change the state(s) of the contract instance.
transactionIndex: 0,
v: "0x1c",
Therefore, as long as nodes have the address of the contract
value: 0 instance, they can call as many times as they want to retrieve
}]
the states.
> eth.pendingTransactions
[]
> myContract.getPayment() Functions that change the state(s) of the contract instance
200 require Transactions. Each invocation will create a new
> myContract.getBalance()
4700
Transaction, waiting to be mined. Once mined, the new Block is
> broadcast. Peer nodes will validate and execute it to update its
local blockchain.
TIP: For any other node to mine a transaction, admin.peers must This is yet another take on "distributed transactions," or in
reflect the nodes are in the same network. If you have re-started our case, a distributed-deferred-transaction with eventual
your system, use admin.addPeer to add your node to the current consistency. All mining nodes will have the same copy of
peer again. distributed ledgers.
A B O U T T H E AU T H O R
SEBASTIAN L .K. MA has been a software craftsman in Singapore and Germany. Having been through the
trenches in software development and designing service oriented architecture for distributed systems in
C++, Java, C#, and Erlang, Sebastian still enjoys hands-on technical roles. Blockchain and Smart Contracts
have added a positive revolution on decentralization and Sebastian now plays multiple roles as Blockchain
researcher, designer and developer at TNO.
Copyright © 2017 DZone, Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise,
without prior written permission of the publisher.