Exploring Ethereum Dapps (Manning, 2019)
Exploring Ethereum Dapps (Manning, 2019)
Exploring Ethereum Dapps (Manning, 2019)
Grokking Bitcoin
by Kalle Rosenbaum
ISBN 9781617294648
480 pages
$31.99
April 2019
Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial caps
or all caps.
Recognizing the importance of preserving what has been written, it is Manning’s policy to have
the books we publish printed on acid-free paper, and we exert our best efforts to that end.
Recognizing also our responsibility to conserve the resources of our planet, Manning books
are printed on paper that is at least 15 percent recycled and processed without the use of
elemental chlorine.
ISBN: 9781617297106
Printed in the United States of America
1 2 3 4 5 6 7 8 9 10 - EBM - 24 23 22 21 20 19
iii
iv
geth, the most popular Ethereum client. I will show you how to launch simple com-
mands, which will allow you to get network and blockchain information and manage
accounts. At the end of each chapter, we will also start building SimpleCoin, a simple
demo cryptocurrency.
I hope you find these chapters interesting and continue your Ethereum learning
journey in the full book!
A first look at
decentralized applications
How many times have you found yourself in the following situation? You were
browsing around to buy the latest gadget and were comparing prices online, when
you came across SmallWebRetailer.com that was offering it 30% cheaper than Well-
Known.com. You quickly put the item in the basket, fearing the price would rise at
any moment, and entered your postal address and credit card details, but sud-
denly…you got cold feet. You started to wonder: Is the price too good to be true?
What if this unknown SmallWebRetailer.com is a scam? Will they run off with my
money? After a few minutes of hesitating on the Buy button, you opened a new
browser tab and went straight to WellKnown.com. You submitted the order, aware
you might have overpaid 30% for your gadget.
Why did you panic? Perhaps you didn’t trust SmallWebRetailer.com. Perhaps
you didn’t want to waste your time contacting the credit card company and possibly
waiting for a refund if the transaction turned sour.
What if you could’ve bought the gadget from the same small, unknown retailer
through an “alternative e-commerce application” that guaranteed the seller couldn’t
access your money until you’d confirmed safe delivery of your order? What if that
guarantee hadn’t been provided by the seller or by a single third party, but by many
independent parties participating in a platform designed to process transactions
according to conditions encoded in software anyone could inspect? Hold on, proba-
bly I’ve said it too fast. I’ll repeat it more slowly:
1 What if the money transfer was held until delivery, not by the retailer or a third
party but by many participants in the platform?
2 What if the rules for escrowing and then releasing the money transfer were
encoded in logic, not subjected to manual interaction?
3 What if, in case you were still unconvinced, you could inspect the code yourself?
I bet you’d click Buy, confident your funds would be safely stored on this platform
until the delivery arrived. Such systems do exist, and they’re called decentralized applica-
tions. Decentralized marketplaces, such as OpenBazaar (https://openbazaar.org/),
work this way. The mechanism by which funds are routed to the seller only when
you’ve confirmed safe delivery of the goods is called a smart contract.
Decentralized applications, also known as decentralized apps or Dapps (generally pro-
nounced dee-apps), are part of a new wave of web applications meant to increase the
transparency around commercial transactions, governmental processes, supply
chains, and all those systems that currently require mutual trust between customer
and supplier, user and provider. The objective of Dapps is to minimize or eliminate
the need for any trust between the participants in a system interaction, with the aim of
empowering users beyond what Web 2.0 has delivered. Some claim Dapps could be
the backbone of Web 3.0.
Assuming you have programming experience—even better if it’s in JavaScript—
and some familiarity with web applications, this book will teach you how to build
Dapps made of one or more smart contracts controlled by a user interface. By the end
of this book, you’ll be able to not only write smart contract code but design, imple-
ment, test, debug, deploy, and secure a full end-to-end decentralized application.
Along the way, you’ll also learn a new language, a new platform, and, most of all, a
new way of thinking about, designing, and running applications.
In this first chapter, I’ll give you a high-level overview of Dapps. I’ll explain in
detail what they are, what they look like, what technology stack they’re built on, and
when it makes sense to build them. Best of all, I’ll help you start building your own!
Let’s start our journey.
applications are implicitly centralized with respect to their users. I can hear you ask-
ing, what does “centralized” mean exactly?
A centralized application or system is controlled by a single or central entity: an indi-
vidual, company, institution, governmental agency, and so on. The entity hosts the sys-
tem directly on its premises or through a service or cloud provider and has full
control of all the components and layers of the system architecture. The user trusts
the good faith of the central entity and decides whether to access its system depending
on the entity’s reputation. From the point of view of the user, the system is either
trusted or not. This is how most web and enterprise applications are designed today.
Figure 1.1 illustrates a typical interaction between a user and a centralized trusted sys-
tem. You shouldn’t find anything surprising about it.
Entity
A centralized application
is strongly associated with
the owning entity.
Internet Centralized
Trust application
Figure 1.1 A centralized application is strongly associated with the single entity controlling
it. Consequently, users decide whether to access it depending on their trust of the entity.
Let’s move on to decentralized applications. If you consider for a moment the alterna-
tive e-commerce application I introduced earlier, you’ll agree it has advantages with
respect to SmallWebRetailer.com:
Favorable transaction conditions —The transaction would be completed and the
money would be fully transferred to the retailer only when the retailer had com-
plied with all the conditions associated with the transaction, such as your confir-
mation of safe delivery. This would remove one of the biggest reservations you
had about SmallWebRetailer.com: uncertainty whether you’d get the delivery
and what would happen to your money if not.
Independent transaction execution and verification —The transaction wouldn’t be
processed by the retailer or a single third party but by one of many participants
in the platform supporting the e-commerce application, and then all the partic-
ipants in the platform would independently verify it. The mechanism that all
parties would use to agree on the verification of a transaction is called consensus
(defined in the callout). The consensus mechanism would reassure you that the
promised transaction conditions would be enforced and verified by many inde-
pendent parties rather than an unknown retailer.
Transparency —You’d be able to check the code processing the transaction and
verify that it was observing the specified conditions before transferring your
money to the retailer. This would give you a further level of reassurance that the
application was executing under the promised terms.
You can deliver all of these requirements by building the alternative e-commerce
application as a network of processing nodes of equal importance and functionality,
each owned by a different party. Each node would
be able to process a transaction the same way other nodes do
verify all transactions in the same way other nodes do
contribute in an equal way to the outcome of a transaction
The consequence of this architecture would be that the processing would be decen-
tralized to a network of independent nodes rather than being centralized to a specific
set of servers that a specific entity owns. Such decentralization would relieve the user
from having to trust a specific entity: the user would have to trust only the design of
the network as a whole.
Applications built on this architecture are known as decentralized applications. I’ll
provide another example to make the concept clearer.
as a Service (SaaS) if the voting system is only leased or rented from an external pro-
vider during the voting session. This architecture might not be ideal from the point of
view of the voter, because of potential worries about trust and security.
TRUST IN CENTRALIZED VOTING
Given all the financial and accounting scandals that have happened at both corporate
and governmental levels in the last few years, it’s understandable if you don’t fully trust
the organizations you’re a shareholder or citizen of. You might wonder whether the
outcome of electronic voting might get manipulated in some way.
It’s easy to imagine, for example, that a malicious developer or administrator of
the voting application, colluding with some party interested in a certain outcome of the
voting, could access key parts of the system and tamper with the way votes are col-
lected, processed, and stored at various levels of the application architecture. Depend-
ing on how the application has been designed, it could be possible for some malicious
database administrators to even modify votes retroactively.
SECURITY IN CENTRALIZED VOTING
When voting through a centralized application, you’d worry about not only the good
faith of the company or institution organizing the election, but also whether the sys-
tem was secured adequately against external manipulation. For example, external par-
ties might be interested in having the voting go a certain way and might try to get their
desired outcome by hacking into the system.
As I explained earlier, a centralized voting system includes only a certain number
of servers located within the same network. Each server generally provides only one
function, and it’s therefore a single point of failure, not only from a processing point
of view but also, and especially, from a security point of view. For example, if a hacker
managed to alter code on the web server so that votes were intercepted and modified
in that layer, the entire system would be compromised. The same outcome could be
achieved by hacking only into the application server or, even better, into the database
server. A breach of security in one part of the system is sufficient to compromise the
security of the entire system.
DECENTRALIZED VOTING APPLICATION
A decentralized application is based on two key technical principles:
Its application logic is present and executed simultaneously and independently
on each server of a peer-to-peer (P2P) network. In theory, a different participant
owns each server, also known as a node. A central node doesn’t control or coor-
dinate the servers; instead, they communicate directly with each other and are
consequently also known as peer nodes. They continuously verify each other’s
output, so a user need only trust the P2P network, not an individual organiza-
tion. The application data and state are stored on a local copy of a database on
each server of the network, as shown at the bottom of figure 1.2.
Its database technology, called blockchain, guarantees that data can’t be modi-
fied retroactively.
Entity
A centralized voting
application contains
various servers. Each
server plays a different
role, but the owning
Internet entity controls all
Web App DB of them.
server server server
Internet
A decentralized voting
application runs simultaneously on
each node of a P2P network.
All nodes are equivalent to each
other: each contains both application
logic and a database. A different entity
controls each node.
Figure 1.2 Comparison of a centralized voting application with a decentralized one. One institution
owns all servers of a centralized application. A decentralized voting application runs simultaneously
on multiple nodes of a network that different entities own.
Candidate1 <Javascript>
Candidate2 Javascript and
Web3.js code
Candidate3 </Javascript>
Candidate4
<HTML>
Vote </HTML>
Figure 1.3 A decentralized voting application is exposed to the voter as a web application,
which contains both HTML and JavaScript and is downloaded from a conventional web server.
The web application, which doesn’t contain any server-side scripts (otherwise, it would be
partially centralized), is generally configured to communicate directly with a specific node of
the network.
Node Node
Node
Node Node
Java
C++ client
client Go
client
Parity
Ruby client
client
Figure 1.5 Each node of the Ethereum network hosts a blockchain database
and a node client capable of executing application code stored in the
blockchain. Nodes communicate through the Wire protocol and expose the
same interface but can be implemented in different languages.
network, as a Bitcoin node does, but also to execute application code hosted on the
blockchain database. From this point of view, platforms such as Ethereum are known
as programmable blockchains. The code of decentralized applications is structured in
smart contracts, which encapsulate logic and state in the same way classes do in most
object-oriented languages. The voting decentralized application, for example, would
be structured on various smart contracts that would be hosted on the Ethereum block-
chain. I’ll explain shortly what a smart contract is, how you deploy it, how you execute
it, and where a smart contract is stored and runs. Bear with me.
THE ROLE OF NETWORK NODES
Although all network nodes communicate seamlessly through the common P2P Wire
protocol, not all nodes perform the same function. Broadly, as shown in figure 1.6,
the two main types of nodes, which are functionally different, are as follows:
Full node —Most nodes have a standard setup that allows them to process trans-
actions passively: they can read from the blockchain database, but they can’t
create new blockchain blocks. But they can append blocks received from peer
nodes to the local blockchain. They do execute transactions, but only to verify
the correctness of the blockchain blocks they receive from peer nodes. In the
Full
node
Mining
node
Full
Mining node
Full node
node
Full Full
node node
case of the voting application, full nodes propagate votes received from their
peers to other peers. They also verify that the blocks received are correct and
contain authentic votes by running the voting Dapp smart contracts. But full
nodes don’t store votes in new blockchain blocks.
Mining node —Some of the nodes are configured to process transactions actively:
they group and store transactions in new blockchain blocks. They’re rewarded
in Ether, the cryptocurrency supported in the Ethereum platform, for perform-
ing such computationally intensive and energy demanding work. They then
propagate these new blocks to the rest of the P2P network. Such nodes are
called mining nodes because the process of consolidating a new block to the
blockchain and being rewarded for it in cryptocurrency tokens is known as min-
ing. In the case of the voting Dapp, mining nodes group votes received from
peer nodes into a new block, append the block to the blockchain, and propa-
gate the block through their peers.
PUTTING EVERYTHING TOGETHER
You’ve examined the structural view of the voting Dapp. Figure 1.7 shows the entire
system, including the client and server sides.
Candidate1 <Javascript>
Candidate2 Javascript and
Web3.js code
Candidate3 </Javascript>
Candidate4
<HTML>
Vote </HTML>
Internet
Full
node
Mining
node
Full
Mining node
Full node
node
Full Full
node node
Figure 1.7 The entire static view of a decentralized voting application, including client and server
sides
1. Vote click
event is
handled by
web page
JavaScript
Candidate1 <Javascript>
Candidate2 Javascript and
Web3.js code
Candidate3 </Javascript>
Candidate4
<HTML>
Vote 8. Vote </HTML>
confirmation
Voting web app is displayed Voting web app code
on web page
Transaction
Event Internet
from:0x6cba
VoteConfirmation
candidate:3
6. Block is validated,
executed, and
propagated to peers
Peer Local
full node full node
Block 566
tran1652b1
tran27655c
5. Transaction is
Block 566 Transaction 3. Voting transaction
placed on new block;
tran1652b1 from:0x6cba is validated and
block is propagated
tran27655c candidate:3 propagated to peers
to peers
Transaction
from:0x6cba
candidate:3
Peer
Mining node full node
4. Voting transaction
is validated and
propagated to
mining node
Figure 1.8 The lifecycle of a voting transaction. A voting transaction is created when a voter browser
invokes the castVote() function on the Voting smart contract on a local node of the Ethereum
network. This is then validated and propagated throughout the network until it’s included on a new
blockchain block by a mining node. The new block is propagated throughout the network, and then it
finally gets back to the local node.
1
Vitalik Buterin, “DAOs, DACs, DAs and More: An Incomplete Terminology Guide,” http://mng.bz/vNrq.
external software services. Individuals involved with the DAO interact, as with DOs,
through predefined protocols.
The main difference between a DAO and a DO is that interactions between DAOs
and external parties are largely automated, and the interaction protocols are pro-
grammed in a smart contract, whereas interactions between the individuals who own
the DO and external parties are subject only to a manual protocol. The key point is that
from the point of view of external parties, DAOs are more trustworthy than DOs
because automated interactions are predictable, whereas interactions based on a man-
ual protocol rely entirely on the reputation of the individuals following it.
According to these definitions, opinions diverge as to whether blockchain plat-
forms built with the main or only purpose of supporting a cryptocurrency can be
classified as DAOs or DOs. Because the Bitcoin infrastructure doesn’t allow for imple-
mentation of easily automated interaction protocols, some think it should be classi-
fied as a DO.
DECENTRALIZED AUTONOMOUS CORPORATION
A decentralized autonomous corporation (DAC) is a DAO that can be partially owned
through a purchase of shares. As with classic (centralized) corporations, a DAC redis-
tributes dividends periodically, depending on its financial success. A pure DAO, on the
other hand, is generally a nonprofit organization, and participants benefit economi-
cally exclusively by contributing to its ecosystem and increasing its internal capital.
The key aspects of each of these terms are summarized in table 1.1.
Table 1.1 Matrix summarizing key aspects of each term, with DAO standing for Dapp
DO NO YES NO YES
Although you’ve learned some of the high-level terms, you can’t truly understand the
purpose of Dapps and how they work without familiarizing yourself with the concept
of blockchain. Because Dapps are built on top of the blockchain and rely heavily on
it, you should learn about it and its underlying technologies. I’ll cover this in the
next section.
DB server
Mainframe
Mainframe
DB server
Email server
Distributed application Decentralized application
An application is decentralized if it’s replicated in its entirety over each node of a net-
work, with each node being theoretically owned by a different entity. The higher the
number of entities owning nodes of the network, the more trustful the network in its
entirety is. Obviously, networks that have only a few owners can’t be considered trust-
ful because they don’t truly decentralize the processing.
A centralized application is generally distributed, but decentralized applications can
also be distributed over multiple servers within each logical node.
can then be retrieved at any point of the supply chain with the help of a scanner
that reads the certificate ID from the stone. Almost 2 million diamonds have
already been stored on Everledger.
The pharmaceutical company Pfizer is partnering with the biotechnology com-
pany Genentech to develop MediLedger, a blockchain-based drug delivery
tracking system. The aim is to verify the provenance and authenticity of Pfizer
drug deliveries throughout the entire distribution chain to prevent thefts,
fraud, and counterfeiting.
IDENTITY VERIFICATION
As with provenance tracking, verification of proof of identity tries to protect busi-
nesses and individuals from the consequences of fraud and identity theft. KYC-Chain
is a novel platform built on the Ethereum blockchain that allows users to manage
their digital identity securely. It also helps businesses and financial institutions to man-
age customer data in a reliable and easy manner. The system is designed so that users
own the “keys” to their personal data and identity certificates. Consequently, identity
owners, who can be individuals or companies, are the only ones who get to choose
which part of their information is shared, with whom, and under what terms. Such
information is digitally attested by notaries and institutions before being shared by
owners and registered agents.
PROVING OWNERSHIP
Traditional blockchains associated with cryptocurrencies such as Bitcoin as ledgers
implicitly prove the ownership of digital assets, such as the amount of Bitcoin stored at
a certain address. Only the legitimate owners of the address are able to transfer funds
because they’re the only ones who know the private key.
TrustToken tries to go further. It’s a Dapp conceived for proving the ownership of
physical assets, such as real estate; financial assets, such as stocks and bonds; commod-
ities, such as gold; and even intellectual property, such as music, books, and patents,
through smart contracts. The idea is that you can transfer the ownership of these
assets from one person to the other in the same way Bitcoins are transferred between
addresses. The underlying assumption for TrustToken to be successful is that proof of
ownership recorded through the system should be enforceable under law.
ECONOMY OF THINGS
The tech startup Slock.it (https://slock.it/) is building the infrastructure for the
“economy of things,” which lies at the intersection between the Internet of Things
and blockchain technology. This infrastructure, which the company has named the
Universal Sharing Network, has the potential to be used as a financial internet, where
connected autonomous objects can not only sell and rent themselves but also pay for
each other’s services. The technology the company is developing, based on Ethereum
smart contracts, aims to provide autonomous objects an identity and the ability to
receive payments and enter into agreements without the need for intermediaries.
Smart lockers, which enable the unlocking of physical objects when a fee is paid, are
some of the applications already created on this platform. Because smart lockers make
renting of sports equipment, hotel rooms, bicycles, and offices easy, this solution is
thought to provide the foundation for the sharing economy.
DECENTRALIZED PREDICTION MARKETS
Prediction markets reward people for correctly predicting real-world events, such as
the winner of a presidential election, the outcome of a referendum, the level of inter-
est rates at a specific date, or the winner of a sports competition. Aside from specula-
tive uses, they’re also useful tools for economists, public administration planners, and
corporate strategists, who can base their decisions on the event probabilities being
currently traded, which are thought to reflect the “wisdom of the crowds.”
Although centralized markets such as predictit.org (www.predictit.org) exist, sev-
eral decentralized initiatives are starting to emerge. Augur is a decentralized market
prediction platform built on Ethereum. The idea is that decentralization brings the
following benefits:
Being based on the Ethereum network, it has no central point of failure, so it’s
inherently highly available.
Nobody controls the definition of markets: anyone can start a new market on a
new prediction and can get rewarded for having created that market.
The official outcome of each prediction isn’t decided centrally; it’s crowdsourced
from market participants, so it’s less likely to be subject to manipulation.
Funds are stored on the blockchain, which eliminates counterparty risk, makes
payment to prediction winners fast, and reduces the likelihood of errors.
INTERNATIONAL TRADE FINANCE
International trade between a supplier and a manufacturer located in different coun-
tries is a complex business. As you can see in figure 1.9, it’s generally based on a com-
plicated workflow involving many parties, such as banks that facilitate the payment,
commercial intermediaries that facilitate the distribution, shipping and delivery com-
panies that transport the goods, insurers that cover financial risks while the goods are
in transit, and customs officials who check the legality of the goods and the payment
of import duties.
Parties involved in a specific transaction often have never dealt with each other
previously. But for the transaction to complete successfully, they must communicate
with each other effectively, generally through established lengthy protocols designed
to protect a party against the malicious behavior of another party. Parties cross-check
each other, and this takes a huge amount of paperwork and time, which often causes
long delays.
we.trade is a platform sponsored by a consortium of banking partners (including
Société Générale, Deutsche Bank, Nordea, Santander, and HSBC) that aims at simpli-
fying and streamlining such processes with the help of blockchain technology. The
platform tracks each step of the transaction openly and transparently so that each
party is able to submit and consume the relevant documentation with the confidence
Insurer
Electronic invoicing
Invoicing system
Figure 1.9 Typical international trade involving many parties: banks, commercial intermediaries,
shipping companies, insurers, customs officials, and so on
that no one will tamper with it. Trades that used to take weeks can be now completed
in a few days.
REGULATORY AUDITING
The blockchain is particularly suitable for ensuring that records stored on it haven’t
been altered or tampered with. Balanc3 is a Dapp built on Ethereum that ensures the
integrity of accountancy records for regulatory purposes.
CROWDFUNDING
WeiFund aims at providing open source modular and extensible decentralized crowd-
funding utilities based on the Ethereum blockchain. Users can set up and manage
crowdfunding campaigns through these utilities. The possibility of encoding funding
rules based on smart contract technology allows users to know precisely what will hap-
pen with their money if the campaign fails or is successful.
GAMBLING
Intuitively, a natural fit for a decentralized application is a gambling platform, because
users get the benefit of being assured that bets are processed fairly and predictably.
Edgeless is an example of such a platform, and it’s currently being developed after a
successful crowdfunding campaign.
Now that you’ve learned about some successful Dapp implementations, you might
be wondering whether it’s always worth basing your application on blockchain tech-
nology. We’ll explore this in the next section.
2
Gideon Greenspan, “Avoiding the Pointless Blockchain Project,” http://mng.bz/4Oqg.
conditions that programming logic can’t enforce. A classic example for a non-fully auto-
matically enforceable smart contract is that of an electronic loan. If the borrower had to
keep the borrowed money stuck on a blockchain account so a smart contract could auto-
matically give it back to the lender if the borrower missed an interest payment, the borrow-
ing wouldn’t make any economic sense. In these cases, it isn’t clear yet whether a court of
law would be able to enforce the nonautomated elements of a smart contract or it would
be necessary to complement the deal with a traditional legal arrangement.
Panels for
File explorer toggle Code editor running code
Figure 1.10 Screenshot of the Remix opening screen, with the code on the left and the code execution panels
on the right. I’ve hidden the file explorer by clicking the double arrow toggle at the top left.
Defines a state variable as a “mapping” between Pragma directive indicating the supported
an address and an integer. A state variable is the version of the Solidity compiler. (The code
equivalent of a member variable. A mapping is supports a compiler later than 0.4.0 but
equivalent to a hash table or hash map. earlier than 0.5.0.)
pragma solidity ^0.4.0;
Defines a contract, which is similar
contract SimpleCoin { to a class in other languages
Let’s examine this code in detail. A contract in Solidity is a type similar to a class in any
other language: it has state variables (such as coinBalance), a constructor, functions
(such as transfer), and events.
The coinBalance state variable is defined as a mapping. A mapping is a hash map,
equivalent to a hashMap in Java, Dictionary in C#, or dict in Python. In this example,
the type of the key is an address, whereas the value is a uint256—an unsigned 256-bit
integer. An address holds a 20-byte value and can identify a specific smart contract
account or a specific user account. An account, as you’ll see later in detail, is the
sender or the receiver of a transaction. The coinBalance state variable therefore rep-
resents a collection of coin accounts, each holding a number of SimpleCoin tokens.
The transfer function is meant to move a number of SimpleCoin tokens from the
coin account of the function caller to a specified coin account. In smart contract ter-
minology, a function caller is the transaction sender. msg is a special implicitly defined
variable that represents the incoming message. It has various properties, among which
msg.sender represents the address of the sender of the transaction, who is the caller
of transfer.
The body of the transfer function is simple to understand. It involves subtracting
the specified amount from the cash account associated with the function caller and
adding the amount specified in the _amount parameter to the account associated with
the address specified in the _to parameter. To keep this initial code simple, this imple-
mentation isn’t performing any boundary checks yet on the number of SimpleCoin
tokens owned by the transaction sender, who, for example, shouldn’t be allowed to
send more tokens than they own. You’ll perform such checks when we revisit Simple-
Coin in later chapters.
At this point, you should understand that your SimpleCoin contract is, in practice,
a class with a constructor (SimpleCoin function), some state (coinBalance variable),
and a method (transfer function). Table 1.2 gives a quick summary of the Solidity
keywords you’ve come across.
Table 1.2 A summary of Solidity keywords used in the first code sample
Keyword Explanation
msg.sender Property of the msg object representing the address of the message sender
If you’ve typed your code correctly (I recommend you copy the code from the files pro-
vided on the book website!), and no compilation errors have occurred, you should see
the following buttons in the Run tab: Deploy and At Address, as shown in figure 1.12.
Ignore At Address for now and focus your attention on Deploy. By clicking this button,
you’ll deploy the SimpleCoin contract on an emulated blockchain within Remix.
Figure 1.12 Once the code has been compiled correctly, the Run tab will show two buttons:
Deploy and At Address. You can instantiate the contract by clicking Deploy.
The contract will be stored against an address on the emulated Ethereum blockchain,
and a new Deployed Contracts panel will appear, as shown in figure 1.13. You can read
the deployment address by clicking the Copy Address icon and pasting it in Notepad,
for example.
Figure 1.13 After deploying the contract, the Deployed Contracts panel
appears, containing a drop-down with a SimpleCoin option; click it, and you’ll
see the contract operations.
Transfer is a CoinBalance is
write operation. read-only.
In this case, CoinBalance is blue because it allows you to read the coin balance associ-
ated with an address. Transfer is red because by clicking it you’ll alter the state of the
contract, specifically by changing values contained in the coinBalance mapping state
variable.
Now check that the coinBalance associated with the address specified in the con-
structor has the full initial supply of SimpleCoin you set at construction. Wrap the
address with double quotes: "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C".
Enter it in the text box and click CoinBalance. Some output will appear. At the bot-
tom, you should see the expected number of SimpleCoin tokens you specified in the
constructor: 10,000.
0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C is the address of one of the five
test accounts present on the Remix IDE. You can see them in the Transaction Origin
drop-down list box on the top-right of the screen. Although they aren’t fully visible on
the screen, their full addresses are reported in table 1.3. (I’ve retrieved them one by
one by clicking the Copy Address icon next to the Account drop-down.)
Table 1.3 Remix test accounts whose full address is hidden behind the HTML
0xca35b7d915458ef540ade6068dfe2f44e8fa733c
0x14723a09acff6d2a60dcdf7aa4aff308fddc160c
0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db
0x583031d1113ad414f02576bd6afabfb302140225
0xdd870fa1b7c4700f2bd7f44238821c26f7392148
You can double-check that the amount of SimpleCoin tokens associated with any
address different from 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C is zero. For
instance, enter the following address, wrapped with double quotes as you did earlier,
in the CoinBalance text box: "0x583031D1113aD414F02576BD6afaBfb302140225".
After clicking the button, you’ll see a zero, as expected.
To recap, when you instantiated the contract, an amount of 10,000 SimpleCoin
tokens got assigned as initial money supply to the address starting with 0x14723A09.
No other address owns any tokens yet, as summarized in table 1.4.
Table 1.4 Balance of each Remix test account after contract instantiation
0xca35b7d915458ef540ade6068dfe2f44e8fa733c 0
0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 10,000
0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db 0
0x583031d1113ad414f02576bd6afabfb302140225 0
0xdd870fa1b7c4700f2bd7f44238821c26f7392148 0
Now you’ll call the transfer function to move some tokens from the account with the
address starting with 0x14723a09 to a different test account. Because the transfer
function moves tokens from the account of its caller, the function must be called from
the contract creator’s address starting with 0x14723a09. Pick this address from the
Account drop-down at the top right of the Run tab, then enter in the text box of the
transfer method the destination address—for example, the address starting with
0x4b0897b0—and a number of tokens to be transferred—for instance, 150 tokens.
You should separate the values of these parameters with a comma:
"0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", 150
Table 1.5 Balance of each Remix test account after a transfer operation
0xca35b7d915458ef540ade6068dfe2f44e8fa733c 0
0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 9,850
0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db 150
0x583031d1113ad414f02576bd6afabfb302140225 0
0xdd870fa1b7c4700f2bd7f44238821c26f7392148 0
As an exercise, you can try to transfer coins from the address starting with 0x4b0897b05
to a different address and recheck if the amounts are correct. While doing so, please
don’t perform any crazy transactions yet, such as trying to move more coins than a cer-
tain address is holding. To keep the code simple for the moment, you haven’t coded
any boundary conditions to handle such situations. You’ll learn about these in the
next chapter.
Although the code you’ve written so far is simple, your main objective at this stage
was only to start to familiarize yourself with smart contracts, the Solidity language, and
Remix. By now, you should have achieved that objective, and you should understand
how contract instantiation works and how to interact with a contract from different
accounts.
SimpleCoin is still at the stage of an embryonic Dapp. So far, you’ve only executed
its code on a JavaScript VM-based simulator and, because it’s lacking a UI, you’ve seen
its output through Remix. In the next chapter, you’ll take a step further and install an
Ethereum client. You’ll then deploy SimpleCoin to a real Ethereum network and
interact with it again.
Summary
A decentralized application is a novel type of application that isn’t owned or
controlled by any entity and runs on a trustless decentralized P2P network.
The topology of a decentralized application is different from that of a conven-
tional, centralized, one because both its business logic layer and its data layer
(the blockchain) are fully replicated on each node of the network.
Dapps rely on blockchain technology, which is based, in turn, on public key
cryptography, cryptographic hash functions, and the concept of mining through
a consensus protocol.
Many appropriate use cases exist for decentralizing an application, especially in
the fields of provenance and authenticity tracking, identity verification, regula-
tory auditing, prediction markets, and crowdfunding.
Decentralized applications aren’t always the best solution for a business prob-
lem. For example, it doesn’t make sense to decentralize an internal enterprise
application that isn’t shared with any external participant.
You can implement smart contracts, which are at the heart of Dapps, within the
Ethereum platform in a language called Solidity, similar to JavaScript. It’s possi-
ble to write simple smart contracts through the Remix Solidity IDE and simu-
late their activation and interaction with various mock Ethereum accounts.
The previous chapter introduced Dapps and the underlying concepts and techno-
logies, among which is Ethereum. In this chapter, I’ll cover Ethereum in much
greater depth, so you’ll get the foundation you need to develop Dapps on this plat-
form effectively. I’ll begin by presenting the Ethereum wallet, a UI tool you’ll use to
start interacting with the Ethereum P2P network by transferring some Ether, the
Ethereum cryptocurrency. Then you’ll get a wide overview of smart contracts,
the key technology that Ethereum introduced.
After learning about Go Ethereum, one of the many clients available on the
platform, and once you understand the purpose of accounts, you’ll move to the
next level and start interacting with the Ethereum network through Go Ethereum
31
in several ways: with commands entered into the operating system shell, with instruc-
tions entered into the Go Ethereum console, and with HTTP requests. At that point,
you should have acquired enough familiarity with the platform to progress with con-
fidence through the rest of the book. It’ll be a dense but rewarding chapter. Let’s
get started.
You’ll learn about Mist in a later chapter. For the moment, we’ll focus on the Ethe-
reum wallet. The main purpose of the wallet is to store, receive, and transfer Ether,
the Ethereum cryptocurrency. It’s similar to a Bitcoin wallet, if you’ve ever handled
bitcoins, and you’ll initially use it to transfer Ether so that you can start to interact with
the platform in the simplest way. It’s also a useful tool to learn how to deploy smart
contracts and interact with them on one of the public Ethereum networks.
After you select the Ropsten network, the wallet will start to synchronize with the
related blockchain. By default, the synchronization mode is Light, which, as you saw
in the previous chapter, downloads the current state trie from a peer full node, so you
don’t have to wait long (minutes). This will allow you to get up and running quickly.
But if you want to perform write operations, such as transferring Ether or deploying
smart contracts, which is what you’ll be doing, you must get a full copy of the block-
chain—you can choose between Fast and Full. (Go back to the previous chapter if you
don’t remember how these sync modes work.) Here’s a rough estimate of what to
expect when you’re synchronizing the Ropsten blockchain locally:
Fast —Uses roughly 1 GB of disk space and takes two to four hours
Full —Uses roughly 100 GB of disk space and can take up to a day or two
Once you’re synchronized, you’ll be able to see synchronization details at the top of
the screen, including the name of the network you’re connected to, the latest block
number, and the number of seconds passed since receiving the last block, as shown in
figure 3.2.
WARNING To perform the operations I’ll cover in this chapter and the next,
you must choose Fast or Full synchronization; otherwise, you won’t be able to
transfer Ether or deploy a contract through the wallet. To be able to execute
a transaction, you must have a full local copy of the blockchain. If the wallet
appears unresponsive after a while and you don’t notice any progress in the
synchronization, it might be because the wallet hasn’t managed to connect to
any peer nodes. In that case, close it down and try to synchronize the Ropsten
blockchain through the geth client. If you need to do this, read about geth in
section 3.3, and then synchronize it to Ropsten as explained in chapter 8, sec-
tion 8.1.
At this point, you’re ready to create accounts. Click the Wallets tab, which will bring
you to the Accounts Overview screen, and then click the Add Account button, which
has a plus symbol next to it, as you can see in figure 3.3.
You’ll see a small dialog box asking for a strong password. (Make sure you stretch
the dialog from the bottom-right corner until you see the OK button.) After entering
a password (twice), you’ll be reminded to back up your keyfiles (more on this later)
and password.
Figure 3.3 Accounts overview screen. You can create an account by clicking Add Account.
WARNING Manage your passwords carefully. If you forget your password, you
won’t be able to click any “I Forgot My Password” button. Losing your password
means losing the Ether stored in the account. This isn’t a major problem
when pointing to a test network, because Ether has no value there. But, espe-
cially when moving to the production network, you should get into the habit
of choosing a strong password and keeping a copy of it somewhere secure.
Better safe than sorry!
NOTE If you’re using the Ethereum wallet for Mac OS or LINUX, the inter-
face is slightly different, screenshots won’t match what you see, and my
descriptions might not work to the letter. Also, the default network shown
might be different. But you should be able to find alternative ways to perform
the operations I describe.
After the wallet has generated the account, on the Accounts Overview screen you’ll
see Account 1 with the related hexadecimal address and a balance of zero Ether. I’ll
cover accounts in more detail later; for now, create one more account in the same way,
and you now should see two accounts on the screen, as shown in figure 3.4. Now that
you have a couple of accounts (feel free to create more), you can try out some com-
mon operations with the wallet.
NOTE The menu option Develop > Start Mining will appear only after the
blockchain has been entirely synchronized in Fast or Full mode.
The CPU of your machine will get busy, and after a few minutes you should have accu-
mulated enough Ether to get going.
If for any reason mining is taking too long, an alternative way to fund your Ropsten
accounts is through the so-called faucet. The following URL can send your addresses
free test Ether: http://faucet.ropsten.be:3001/donate/<destination address>, for exam-
ple, http://faucet.ropsten.be:3001/donate/0x8713Cb74c7DB911f2056C8DD2bA5036-
7eeEa11D0. After a few seconds, your destination address should receive 1 Ether, as
you can see in figure 3.5. You can check the status of the Ether transfer from the fau-
cet by entering your address in the text box at the top of the Ropsten Etherscan web-
page: https://ropsten.etherscan.io/. If faucet.ropsten.be isn’t working as expected or
you keep getting gray-listed, try https://faucet.kyber.network/. Alternatively, try Goo-
gle ropsten faucet.
TRANSFERRING ETHER
Now you can try to move some Ether between accounts. It’s easy. First, go to the Send
screen. Select the source (Account 1) and target account addresses (copy the address
of Account 2 from the Accounts Overview screen), then select the amount of Ether
you want to transfer—for example, 0.5 Ether. Finally, after deciding on a transaction
fee, click Send Transaction. Don’t worry too much about this for now; we’ll examine
transaction fees later.
You’ll be prompted to enter a password, as shown in figure 3.6. Enter the password
of the source account (Account 1) to digitally sign the transaction and subsequently
prove that the account owner is sending it, and then click Send Transaction. You’ve
now completed your first Ether transaction!
Figure 3.6 Password entry screen for moving Ether between accounts. You’re
required to enter the password of the sending account when transferring Ether
with the Ethereum wallet, to digitally sign the transaction and consequently prove
it’s genuinely the account owner who’s sending the Ether.
To check the status of the transaction, go back to the Accounts Overview screen and
click Latest Transactions at the bottom of the screen. Clicking on the related link will
allow you to drill down into further details, such as those shown in the screenshot in
figure 3.7.
You can get a better idea of how your transaction has contributed to the Ropsten
blockchain by checking it on Etherscan, a website reporting the real-time evolution of
the Ethereum blockchain. Use this URL to access the test network: https://ropsten
.etherscan.io/. You’ll be able to get detailed block and transaction information.
Now that you’ve acquired some familiarity with Ethereum, it’s time to learn more
about one of the greatest innovations that this platform introduced: smart contracts.
Once you grasp how smart contracts work, you’ll be able to make further progress on
SimpleCoin, the cryptocurrency you started to build in the previous chapter.
1. A user starts a transaction 2. A contract function executes its 3. The contract reads/writes
message by invoking a contract logic on the EVM. its state from/to the blockchain.
function, for example vote(), from
an account containing some Ether. Ethereum node
Ethereum Virtual Machine (EVM) Blockchain
VotingContract
vote()
Figure 3.8 An Ethereum contract receives a transaction message from a user account. Its logic is executed on
the Ethereum Virtual Machine (EVM); then the successful miner calculates the cost for the computational and
network resources used, in a unit called gas, and charges the user account in Ether.
reading state from the blockchain, or writing state to the blockchain (specifically
from/to the State Merkle-Patricia trie). The account sending the message to the con-
tract gets charged (in Ether) by the successful mining node for computation and net-
work resources consumed during the processing of the requested operation. The
amount of such computation and resources is calculated in a unit called gas, as you’ll
see in section 3.2.3, so it’s common to say that a transaction consumes a certain
amount of gas (rather than resources).
If you want to understand smart contracts, how they get instantiated by users and
by other contracts, and especially how they get executed, you need to go in greater
detail through various concepts I’ve only touched on so far:
Accounts
Ether and gas
Transaction messages
The Ethereum Virtual Machine
I’ll start by telling you more about the various types of accounts.
3.2.1 Accounts
You’ve already come across the concept of accounts a few times. Accounts are available
in two types:
Externally owned accounts (EOA) (or simply External Accounts)—These are also
known informally as user accounts. They’re publicly identifiable from their pub-
lic key, but they can only be operated by knowing the private key. If you buy
some Ether, you’d store it in this type of account. Also, you’d start a transaction
against a smart contract from an EOA.
Contract accounts —These are the accounts that contracts are executed under.
The account address is generated at deployment time, and it identifies the loca-
tion of the contract in the blockchain.
Both EOAs and contract accounts hold data in the form of a key-value store and an
Ether balance. Table 3.1 compares the main properties of EOAs and contract accounts.
3.2.2 Ether
I’ve mentioned Ether casually a few times, so it’s probably time you learned more about
it. Ether is the cryptocurrency that the Ethereum blockchain supports. Its main pur-
pose is to represent monetary value for services and goods traded over the platform.
Ether is also used to pay for transaction fees. These are, as mentioned in section 3.2
and covered more in section 3.2.3, calculated in a unit called gas, which measures
computational resources that a transaction consumes. But these fees are settled in
Ether (calculated from the price of a unit of gas, expressed in Ether). Miners charge
transaction fees to get compensated for the computational power they provide the
network while appending new transaction blocks to the blockchain.
Ether comes in various denominations, which are all defined, as you can see in
table 3.2, as a multiple of Wei, the smallest Ether denomination.
Wei 1 Wei 1
Figure 3.9 summarizes the Ether lifecycle, which goes through the following steps:
1 Minting Ether
2 Transferring Ether
3 Storing Ether
4 Exchanging Ether
Miner account
address: 0xab32c
Ether is minted into Ether: 200.678
the account of the miner.
2. Transferring Ether
Ether is transferred
from a miner account
You can buy Ether
to other accounts. You can manage Ether stored
from exchanges by paying
in an account with a variety
for it in real currencies.
3. Storing of wallets based on different
4. Exchanging Ether technologies.
Ether User account
$ address: 0x4dac2
Ether: 12.67
Mobile
wallet
£ Cryptocurrency
exchange 4. Exchanging
Ether Desktop
You can sell Ether to wallet
exchanges and get it
converted into real
currencies.
Online
$ wallet
¥ Paper Hardware
wallet wallet
Figure 3.9 The Ether lifecycle. Ether is minted by miner nodes into miner user accounts. Then it’s transferred to
EOAs (also known as user accounts). From there, it can be stored on various wallets. Ultimately, it can be
converted to real currency, such as USD, EUR, YEN, GBP, and others, through cryptocurrency exchanges.
MINTING ETHER
If you’re unfamiliar with cryptocurrencies, you must be wondering how Ether is
minted and exchanged. Ether is generated through the mining process, during which
miners compete to group and append transactions into new blockchain blocks, as I
discussed in section 1.1.2. When successful, a miner gets rewarded with a certain num-
ber of Ether coins. Blocks are added to the Ethereum blockchain every 15 seconds or
so, and the money supply increases accordingly.
TRANSFERRING ETHER
Once Ether has been generated, it’s allocated to the miner’s external account. Miners
can then transfer Ether to other external accounts or contract accounts, either through
the Ethereum wallet or programmatically, as you’ll see later.
EXCHANGING ETHER
Because Ether is valuable, it doesn’t generally get transferred for free between accounts.
It’s often transferred in return for goods and services traded through smart contracts,
but also in return for conventional currency, such as US dollars, euros, pounds, yen, and
so on. Although it’s possible to buy Ether from individual owners and pay them an
agreed amount of conventional currency, it’s more effective to handle such transactions
using cryptocurrency exchanges. Two main types of exchanges are available: central-
ized, such as Kraken, Coinbase, and Coinsquare, and decentralized, such as EtherEx.
Each exchange is generally biased toward a specific real-world currency.
STORING ETHER
Once someone acquires Ether, whether through mining, smart contract trading, or
exchange-based trading, it’s allocated to an account. You can manage accounts using
many methods, each with a different trade-off between convenience and security. The
most convenient one is generally through desktop or online wallets, which allow you
to transfer Ether easily. The most secure one is through cold or paper storage, which
means generating the private key offline and holding it literally on a piece of paper.
Hardware wallets present another high-security option and are conceptually similar to
paper wallets because they can be considered offline. The main difference is that the
account owner stores the private key on a small electronic device similar to a USB key.
Table 3.3 summarizes the different options.
I’ve mentioned that transaction fees are charged in Ether but calculated in a unit
called gas. Let’s see what gas is and how it’s related to transaction costs.
3.2.3 Gas
Gas is the unit of measure for transaction fees charged on the Ethereum platform.
The amount of gas used to complete a transaction depends on the amount of compu-
tational resources that the EVM spends while running the transaction. Specifically, it
depends on the exact low-level EVM instructions that have been executed during the
transaction. Table 3.4 gives an idea of the amount of gas charged for the most com-
mon EVM operations.
The main reason the execution of a transaction is charged in units of gas, and indi-
rectly in units of computational work, is to prevent denial of service (DoS) attacks by
unscrupulous participants who might want to disrupt the network. To launch a DoS
attack, a malicious participant would have to spam the network with a high number of
transactions, each performing a large amount of computational work; for instance, an
infinite loop. The amount of gas corresponding to this work would be high, and it
would have to be paid in a correspondingly high amount of Ether—it’s unlikely any-
one would pay to disrupt a service!
Most smart contract development IDEs give an idea of the total amount of gas
required to complete a transaction. For example, in the screenshot in figure 3.10, you
Figure 3.10 Transaction costs for the execution of the SimpleCoin transfer function
can see a gas estimate for the execution of the transfer function of the SimpleCoin
contract from the last section of chapter 1, obtained by clicking the Details button on
the output panel.
Transaction fee costs are calculated according to this formula: transaction fees (in
Ether) = number of units of gas consumed * price per unit of gas (in Ether). Let’s
break it down:
The EVM determines the number of units of gas consumed while running the trans-
action, and that depends on the computational cost of the code being run
during the transaction.
The sender of the transaction decides the price of a unit of gas (in Ether). The
higher it is, the more likely it is that miners will include the transaction in the
block they’re processing. Miners prioritize transactions that are likely to pay
high fees, so if a transaction is expected to consume a relatively low amount of
gas, the sender will have to set a relatively high gas price to guarantee quick pro-
cessing.
The transaction sender sets a limit for the maximum amount of gas that a transac-
tion should consume. This protects the sender from higher-than-expected
transaction costs due to execution of the code in a way different from what was
intended; for instance, if the developer introduces a bug that causes an infinite
loop. Such limits should be relatively close to the estimated amount of gas
needed to complete the transaction.
While a transaction is being executed, the EVM consumes its gas. Two outcomes are
possible at the end of the transaction:
1 The transaction completes successfully. In this case, the unused gas is returned to the
sender.
2 The amount of gas available ends before the completion of the transaction. In this case,
the EVM throws an end of gas exception, and the transaction is rolled back.
You might be wondering who pockets the transaction fee. Given either of the two
transaction outcomes, the miner who has processed the transaction receives the fee.
For the first outcome, they earn the fee by including the transaction in a new block
that has been successfully appended to the blockchain. For the second outcome, even
though the EVM throws an exception, the miner still charges the gas in Ether, and
they collect the related transaction fee as usual. In short, a successful miner is
rewarded by minting new Ether and getting transaction fees from the transaction
senders. In the early stages of the Ethereum platform, most of a miner’s profits came
from minting.
Typical calls are direct invocations of contract member variables, including mappings,
and invocations of so-called constant functions, which don’t alter contract state. You
performed calls, for example, when you checked account balances of SimpleCoin, the
basic cryptocurrency you started to build at the end of chapter 1.
TRANSACTIONS
A transaction, which I introduced to you in the Dapp dynamic view in chapter 1, is
sent through a message that gets serialized and stored on the blockchain during the
mining process. It contains the following fields:
Sender address
Recipient address
Value —Amount of Ether to be transferred (in Wei), in case the message is being
used to transfer Ether (optional)
Data —Input parameters, in case the message is being used as a function call
(optional)
StartGas —Maximum amount of gas to be used for the execution of the mes-
sage. If this limit is exceeded, the EVM throws an exception and rolls back the
state of the message.
Digital signature —Proves the identity of the transaction sender
GasPrice —The price of a unit of gas (expressed in Ether) the transaction initia-
tor is willing to pay, as discussed in the gas section
You executed transactions when you performed SimpleCoin transfers. The execution
of a transaction has the following characteristics:
It can perform write operations, which alter the state of the blockchain.
It consumes gas, which must be paid for in Ether.
It’s processed asynchronously: it gets executed through mining and then gets
appended on a new blockchain block, which gets broadcast throughout the
network.
each other in exactly the same way, according to a predefined protocol called Wire,
described in the Yellow Paper. This means all nodes must be able to append new trans-
action blocks to the blockchain (if mining is activated) and verify them while blocks
get propagated throughout the network.
From an implementation point of view, the network contains two broad categories
of nodes:
Miners —They process the latest transactions and consolidate them into the
blockchain in exchange for transaction fees and a mining reward (in Ether) if
they manage to execute the consensus algorithm successfully. In that case, they
propagate the blocks they’ve consolidated onto the blockchain to other peers
of the network. Because these nodes generate new blocks, they’re considered
producers (although they’re technically also still consumers).
Full nodes —They mainly verify the validity of the blocks they’ve received from
neighboring peers and keep propagating them to the rest of the network.
Therefore, they’re considered consumers.
Mining nodes run on clients optimized for processing transactions, generating blocks,
and executing the Proof of Work algorithm efficiently, to get rewarded relatively fre-
quently. Mining implementations, such as ethminer, have been written in C++ and use
GPU libraries such as NVIDIA’s CUDA. Consequently, they run on GPU hardware that
can deliver superior performance.
On the other hand, full nodes don’t have performance requirements, so standard
clients have been implemented in various languages. Table 3.5 summarizes the main
client implementations available to date, ordered by popularity, as reported in Ether-
nodes (https://ethernodes.org/network/1).
Client Language
Go Ethereum (geth) Go
Parity Rust
Ethereum(J) Java
Pyethapp Python
ethereumjs-lib JavaScript
ruby-ethereum Ruby
ethereumH Haskell
Each client comes with a console, and some of them also include a graphical browser
or a wallet. While working with this book, you’ll use Go Ethereum, also known as geth,
which is the most popular client, installed on over 70% of the network nodes.
After geth has synchronized the full blockchain (this could take from hours to days,
depending on your hardware and internet connection), the console will start to slow
down and show blocks being added to the blockchain in real time.
NOTE As for the wallet, you can synchronize geth in Light or Fast mode—for
example, C:\program files\geth>geth –-syncmode "light"—if you prefer
to get up and running more quickly (in minutes as opposed to hours or even
days) and don’t mind not having downloaded the full blockchain locally.
I’ll present both techniques to you. Let’s start with the simpler tool: the interactive
JavaScript console.
If a geth client is already running on the machine, attach to a running geth pro-
cess with the attach command:
C:\program files\geth> geth attach ipc:\\.\pipe\geth.ipc
You have a running geth process, so you’ll go for the second option.
NOTE In this book, I’m assuming you use Windows, as over 60% of the nodes
of the Ethereum network run on this operating system. Consequently, I’ll
show shell commands with a Windows command prompt format. Also note
that after successful execution of instructions in the console, you might see
undefined right before or after the correct results. You can ignore it.
DISPLAYING VERSION INFORMATION
First of all, you can query the console for version information. A Web3 object named
web3 is implicitly instantiated when opening the console, so you can access version
information in this way by typing
> web3.version
As you can see, the version property is an object that contains many subproperties. If
you want, you can be specific and query an individual property of the version object:
> web3.version.api
Because the console accepts JavaScript instructions, it’s possible to assign the values of
Web3 properties and subproperties to variables and then display them through the
console object:
> var apiVersion = web3.version.api
> var nodeVersion = web3.version.node
> console.log(‘Api version: ' + apiVersion)
> console.log(‘Node version: ' + nodeVersion)
CHECKING CONNECTIVITY
You can get some client connectivity information from the web3.net object. (You can
omit the web3 namespace because it’s implicitly referenced.) If you type
> net
As for the version object, you can directly access individual properties of the net object
as follows:
> console.log('this geth instance is listening for network connections : ' +
web3.net.listening)
> console.log('number of peers connected to this geth instance: ' +
web3.net.peerCount)
If you want to get more detailed information about your node, you can use the
web3.admin object and call
> admin.nodeInfo
The peers property gives you detailed information about the peers you’re connected to:
> admin.peers
Then you can display summary information about this block by calling
> eth.getBlock(latestBlockNum)
You also can drill down at transaction level. You can get the first transaction stored in
the latest block in this way:
> eth.getTransactionFromBlock(latestBlockNum, 0)
from: "0x392fd4954de442bb6c4d57f1923b4708642d3408",
gas: 210000,
gasPrice: 120000000000,
hash: "0x4eb5ae8d7b7919f92d1dd02fcc407d6...",
...
I encourage you to have a look at the content of the whole eth object:
> eth
Go Ethereum client
Figure 3.12 Comparison between accessing geth through Web3.js and JSON-RPC
The RPC interface has been designed against the JSON-RPC 2.0 standard, and conse-
quently it sends and receives data in JSON format. You can find more information on
JSON-RPC in the sidebar.
If you want to communicate with geth directly through JSON-RPC, you have to do
two things:
1 Stop any instance of geth running in a standard operating system command
shell or in a geth console.
2 Start geth in RPC mode using the --rpc and --rpcapi options:
C:\program files\geth>geth --rpc --rpcapi "eth,net,web3,personal"
When you launch geth in RPC mode, it’s accessible through an HTTP server that
accepts HTTP requests, by default on
http://localhost:8545
JSON-RPC
JSON-RPC is a lightweight remote procedure call that uses JSON as a data format.
You invoke an RPC call by sending a request object to a server, typically over HTTP,
or in any other way, such as socket or even messaging, because the transport layer
isn’t part of the protocol.
The request object must contain the following members:
jsonrpc—This sets the protocol version, currently 2.0.
method—Name of the remote procedure to be called.
params—Array with procedure parameters.
id—A call identifier, typically a string or integer. It must be not null.
After the server processes the call, it replies with a response object, which contains
the following members:
jsonrpc—This sets the protocol version, currently 2.0.
result—This field is present if the response is successful; it isn’t included if
errors occur.
error—This field is present if errors occur; it isn’t included if the response is
successful.
id—Same as specified in the request.
You’ll perform JSON-RPC calls to geth’s HTTP server using the cURL console com-
mand. To help you appreciate the differences between the Web3 API and the JSON-
RPC API, I’ll show you how to execute in cURL the same operations you performed in
Web3 through the interactive console.
{"jsonrpc":"2.0","id":23,"result":"Geth/v1.6.5-stable-cf87713d/windows-
amd64/go1.8.3"}
(If you’re using Windows, you must escape JSON double quotes, as explained in the
sidebar.) The result is equivalent to what you got from web3.version.node.
And in Linux:
$curl -H "Content-Type: application/json" -X POST --data
'{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":23}'
http://localhost:8545
To get the number of peers connected to the client, you must execute this call:
C:\>curl -H "Content-Type: application/json" -X POST --data
{\"jsonrpc\":\"2.0\",\"method\":\"net_peerCount\",\"params\":[],\"id\":23}
http://localhost:8545
0 0x0
9 0x9
1234 0x4d2
Once you have the latest block number, you can inspect it by calling (replacing the
block number in params with the one from your result):
C:\>curl -H "Content-Type: application/json" -X POST --data
{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"params\":[\"0x1a70
5d\",true],\"id\":23} http://localhost:8545
Then you can inspect the first transaction of the block you retrieved in a way equiva-
lent to how you did in Web3 through the interactive console (again, putting the block
number you got in results into params):
C:\>curl -H "Content-Type: application/json" -X POST --data
{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionByBlockNumberAndIndex\",\
"params\":[\"0x1a705d\",\"0x0\"],\"id\":23} http://localhost:8545
> miner.setEtherbase(eth.accounts[1])
At this point, the CPU of your machine will go to nearly 100%. Then you can stop
mining:
> miner.stop()
In the unlikely event you’ve mined some Ether, this will now be assigned to your
eth.accounts[1], or to eth.accounts[0] if you decided not to reconfigure it.
When you kicked off mining on the geth interactive window with miner.start(),
you might have noticed output similar to the following:
INFO [09-29|18:08:23] Imported new chain segment blocks=1
txs=20 mgas=4.401 elapsed=25.066ms mgasps=175.592 number=1732751
hash=fa5a62…050eb5
INFO [09-29|18:08:25] Updated mining threads threads=0
INFO [09-29|18:08:25] Transaction pool price threshold updated
price=18000000000
INFO [09-29|18:08:25] Starting mining operation
INFO [09-29|18:08:25] Commit new mining work number=1732752
txs=5 uncles=0 elapsed=7.017ms
INFO [09-29|18:08:27] Generating DAG in progress epoch=57
percentage=0 elapsed=922.455ms
INFO [09-29|18:08:28] Generating DAG in progress epoch=57
percentage=1 elapsed=1.846s
INFO [09-29|18:08:29] Generating DAG in progress epoch=57
percentage=2 elapsed=2.772s
You might wonder what DAG is and why it takes such a long time to compute. DAG
stands for directed acyclic graph, and it’s the data structure underlying Ethash, the
Proof of Work (PoW) algorithm for mining on the Ethereum platform. DAG
requires a relatively high amount of memory, so Ethash is considered a memory-
intensive PoW algorithm. It consequently discourages mining through application-
specific integrated circuit (ASIC) hardware, which is effective only for CPU-intensive
PoW algorithms, such as the one used on the Bitcoin network. The Ethash algorithm
encourages mining instead through commodity hardware, such as a GPU chipset
(explained more in sidebar).
Mining is a specialized topic outside the scope of this book. If you’re interested
in learning more about Ethash, I encourage you to consult the official notes at
http://mng.bz/WaOw.
Now that you’ve experienced mining firsthand, you might ask yourself what hap-
pens if you have the luck to append a new block to the blockchain, get the related
Ether reward in your etherbase account, and then decide to quit your mining activity
by shutting down your node. Would the block you’ve created and appended to the
blockchain still be valid, even if you’ve disappeared from the network? Would the
transactions included in the block still be valid? Would you still be able to transfer the
Ether in your etherbase account to another account?
The answer to all these questions is yes. Remember that the blockchain validation
process, performed continuously by all active full nodes, only cares about the cryp-
tographic consistency between a block hash and the public address of the miner who
has generated the block, in the same way it cares about the consistency between a
transaction hash and the public address of the account that has generated it. So
whether the node that created a new block is active or inactive is as irrelevant to the
block (and transaction) history as whether your computer is on or off after having
transferred some Ether from an account of your desktop Ethereum wallet to another
account.
GPU mining
If you want to try your luck and hope to get rich by generating Ether on the public pro-
duction network with CPU mining, as you’ve done so far in the test network, I hate to
break the news, but you’re more likely to get rich by winning the lottery. As you saw
in chapter 1, the execution of the PoW algorithm is successful only if the hash
obtained combining the block information and a nonce has certain characteristics—
for example, a high number of leading zeros. PoW algorithms are designed so that
you must try millions of nonce values before hitting the lucky one that generates a
valid hash. Consequently, mining successfully means being able to generate more
hashes per second than other miners.
With the best CPU chipset, you’ll be able to generate at most 1 megahash per second
(Mh/s), where megahash means one million hashes. With good GPU chipsets, you
might be able to generate up to 30 Mh/s—nearly 30 times the hashing capability of
a standard CPU. Also consider that mining pools, which are organizations that pool
various GPU miners together so they can share resources and rewards, can generate
up to 30 Th/s (30 trillion hashes per second), which means up to 30 million times
what a CPU is able to generate during the same time. Finally, consider that in the
Ethereum space, around 40 mining pools have a hash rate ranging between 30 Gh/s
and 30 Th/s.
Now you can understand why your chances of generating Ether using a CPU alone are
slim. You might find this stark reality disappointing, and you might even think that the
huge influence of mining pools on the mining process might bring into question Ethe-
reum’s credibility, as far as decentralization is concerned. Many Ethereum partici-
pants believe that as long as many mining pools are competing, decentralization
should be guaranteed. Also consider that the new consensus algorithm being imple-
mented, Stake of Work, introduced in the previous chapter, might change completely
how power is concentrated (or hopefully spread) in the Ethereum network. Here’s a
quick summary of the hash rate that different hardware can achieve:
Hardware Hashrate
For the rest of this chapter, we’ll deal only with EOAs, which I’ll call accounts.
As with most blockchain systems, the security of the Ethereum platform is based on
public key cryptography. An account is therefore identified by a private/public key
pair. The account’s address is represented by the last 20 bytes of the public key.
The private/public key pair associated with an account is stored in a text keyfile.
The public key is visible in plain text, whereas the private key is encrypted with the
password introduced at account creation. Account keyfiles are in the keystore folder
within the Ethereum node’s data directory:
Windows: C:\Users\username\%appdata%\Roaming\Ethereum\keystore
Linux: ~/.ethereum/keystore
Mac: ~/Library/Ethereum/keystore
TIP It’s strongly recommended that you back up the keystore folder on a
regular basis and keep a copy of the passwords you’ve introduced when creat-
ing each account in a secure place. Sorry if I keep pestering you with this, but
if you haven't noticed, I do want to make a point of how sensitive key and
password details are in the blockchain world!
Account portability
You can’t use an account that you’ve created on the public production network on a
test network, for example Ropsten, and vice versa. This is because the keystore of
each network is different and is located in a separate folder within the Ethereum
folder:
Main prod network keystore: ~/.ethereum/keystore
Rinkeby test network keystore: ~/.ethereum/rinkeby/keystore
Ropsten test network keystore: ~/.ethereum/testnet/keystore
You can create accounts and interact with them through four different avenues:
The Ethereum wallet, as you saw earlier in this chapter
geth commands
Web3 on the geth console
JSON-RPC calls
You’ve already seen how to manage accounts with the Ethereum wallet. In the next
several sections, you’ll manage accounts through geth commands and the geth con-
sole. You’ll also get a quick feel for how to perform some operations on accounts
through the JSON-RPC API.
b You’ll be prompted to enter a password twice, and then you’ll be shown the
address of the account you created:
Your new account is locked with a password. Please give a password.
Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {47e3d3948f46144afa7df2c1aa67f6b1b1e35cf1}
TIP Get into the habit of choosing strong passwords or generating them
through a strong password generator. I’m repeating myself; I know, I know!
But this is important, believe me!
You’ll see the accounts you created through the geth account command and the geth
console:
Account #0: {edde06bc0e45645e2f105972bdefc220ed37ae10}
keystore://C:\Users\rober\AppData\Roaming\Ethereum\keystore\UTC--2017-
06-24T08-49-46.377533700Z--edde06bc0e45645e2f105972bdefc220ed37ae10
Account #1: {4e6c30154768b6bc3da693b1b28c6bd14302b578}
keystore://C:\Users\rober\AppData\Roaming\Ethereum\keystore\UTC--2017-
06-24T13-26-18.696630000Z--4e6c30154768b6bc3da693b1b28c6bd14302b578
Account #2: {70e36be8ab8f6cf66c0c953cf9c63ab63f3fef02}
keystore://C:\Users\rober\AppData\Roaming\Ethereum\keystore\UTC--2017-
06-24T18-21-36.890638200Z--70e36be8ab8f6cf66c0c953cf9c63ab63f3fef02
Account #3: {c99048e9b98d3fcf8b5f0d5644794b562f9a2ea4}
keystore://C:\Users\rober\AppData\Roaming\Ethereum\keystore\UTC--2017-
06-24T18-21-47.794428600Z--c99048e9b98d3fcf8b5f0d5644794b562f9a2ea4
…
UPDATING ACCOUNTS
After geth creates and saves an account in a keyfile in the keystore folder, a subse-
quent geth release might implement a new keyfile format. In that case, it becomes
necessary to update the account. Another reason you might want to update an
account is because you want to change the password.
You can update account 47e3d3948f46144afa7df2c1aa67f6b1b1e35cf1 you created
earlier with the following geth command (obviously replace with your account number):
C:\program files\geth>geth account update
47e3d3948f46144afa7df2c1aa67f6b1b1e35cf1
You’ll be prompted to enter the existing password, to unlock the account, and subse-
quently a new password, which you’ll have to type twice, as usual. You’ll then be shown
the new address of the account:
Unlocking account 47e3d3948f46144afa7df2c1aa67f6b1b1e35cf1 | Attempt 1/3
Passphrase:
INFO [09-30|08:36:25] Unlocked account
address=0x47e3d3948f46144afa7df2c1aa67f6b1b1e35cf1
Please give a new password. Do not forget this password.
Passphrase:
Repeat passphrase:
The geth account update command offers the same --password option that the geth
account new command provides. But in this case you can also use it to unlock the
account for the purpose of converting it into a new keyfile format.
As for the geth account command, you’ll be asked to enter a password twice, and then
you’ll be shown the account address:
Passphrase:
Repeat passphrase:
"0x70ff99d4bc8054b2e09269bcbfdddf8e1ae7d155"
LISTING ACCOUNTS
You can list accounts with the interactive console by displaying the value of the
account property of the web3.eth object. You’ll get the same result set you obtained
with the geth account list command:
> eth.accounts
You also can directly reference a specific account of the eth.accounts array:
> eth.accounts[0]
Before transferring Ether from a certain account, for example accounts[1], you must
unlock it:
> personal.unlockAccount(eth.accounts[1]);
As usual, you’ll be asked to enter the password associated with this account:
Unlock account 0x4e6c30154768b6bc3da693b1b28c6bd14302b578
Passphrase:
true
Then, you can transfer Ether between accounts with the web3.eth.sendTransaction
function, which takes an amount in Wei, as follows:
> var sender = eth.accounts[1];
> var recipient = eth.accounts[2];
> var amount = web3.toWei(0.0025, "Ether");
> eth.sendTransaction({from:sender, to:recipient, value: amount});
"0xf1c342c668bcd1d59f3e95cfaf08acc6d7cda8adae02da05ceb76c8c3c137eef"
If the balance hasn’t been updated yet, it’s because the transaction hasn’t been mined yet.
contract SimpleCoin {
constructor() public {
coinBalance[0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C] = 10000;
}
This code is rudimentary. Even if you don’t know the Solidity language yet, you can
see a hardcoded value in the constructor and a lack of input validation in the transfer
function. You can improve the code in several ways. First of all, you can parameterize
the constructor so the initial money supply doesn’t get allocated to the address of an
arbitrary test account, but to the address of the contract owner’s account. Then you
can introduce some checks in the transfer function to prevent incorrect transfers.
Finally, you can set things up so that when tokens get transferred, an event can be
raised, and then clients of the smart contract can be notified or react to it.
You’ve already come across the special property msg.sender, whose value is the
address of the message sender (or function caller). When it comes to the constructor,
the message sender is the account that instantiates the contract, which consequently
becomes its owner. As a result, when the constructor gets called, the amount of tokens
specified in the _initialSupply parameter gets allocated to the contract owner.
MAKING TRANSFERS MORE ROBUST
Rewrite the transfer function as shown in the following listing.
Listing 3.2 A more robust transfer function with checks on the input
The require special function throws an exception if the condition isn’t met. You can
also throw the exception directly with the throw keyword, but this way of validating
input is being deprecated. For example
require(coinBalance[msg.sender] > _amount);
RAISING AN EVENT
A contract can declare one or more events that can be raised in any of its functions. A
client that’s monitoring the state of a contract can handle an event. For instance, you
can declare an event that notifies that a transfer of SimpleCoin tokens has taken
place:
event Transfer(address indexed from, address indexed to, uint256 value);
Listing 3.3 SimpleCoin with parameterized constructor, input validation, and event
contract SimpleCoin {
mapping (address => uint256) public coinBalance;
Figure 3.13 The Deploy operation now accepts the constructor input.
After you instantiate the contract by clicking Deploy, the CoinBalance
and Transfer buttons appear.
You can check the contract owner’s address balance in the coinBalance mapping. As
expected, you’ll get 10,000. You can also double-check that the balances of the other
addresses are zero, as shown in table 3.6.
0xca35b7d915458ef540ade6068dfe2f44e8fa733c 0
0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 0
0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db 10,000
0x583031d1113ad414f02576bd6afabfb302140225 0
0xdd870fa1b7c4700f2bd7f44238821c26f7392148 0
After clicking Transfer, you’ll get the following error message, thanks to the require
check you added earlier:
transact to browser/SimpleCoin.sol:SimpleCoin.transfer errored: VM error:
invalid opcode.
The constructor should be payable if you send value.
The execution might have thrown.
Debug the transaction to get more information.
Now try to transfer 150 tokens from the contract owner’s account to the same recipi-
ent you just tried. You need to select the account starting with 0x4b0897b on the
Transaction Origin drop-down list and reenter the following comma-delimited value
into the transfer text box:
"0xdd870fa1b7c4700f2bd7f44238821c26f7392148", 150
The operation will now be successful, as you can see in the output on the left side of
the screen shown in figure 3.14.
If you click the arrow next to Debug, you can verify in the logs property that the
Transfer event has been raised at the end of the function call:
[
{
"event": "Transfer",
"args": [
"0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db",
"000000000000000000000000dd870fa1b7c4700f2bd7f44238821c26f7392148",
"150"
]
}
]
After rechecking all the balances, the results should match table 3.7.
0xca35b7d915458ef540ade6068dfe2f44e8fa733c 0
0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 0
0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db 9,850
0x583031d1113ad414f02576bd6afabfb302140225 0
0xdd870fa1b7c4700f2bd7f44238821c26f7392148 150
3.5.3 How does the coin transfer execute in the Ethereum network?
You might have understood the Solidity code that performs the coin transfer but...if
this transfer was taking place on a real Ethereum network rather than on the Remix
JavaScript EVM emulator, would you know where within the network it would be exe-
cuted? And would you know what effect a transfer of SimpleCoin tokens would have
on the blockchain? You can get the answers to these questions by looking at the dia-
gram in figure 3.15. I’ve adapted it for SimpleCoin from the transactional view you
saw in figure 1.8 (chapter 1).
You’ll see other transaction lifecycle diagrams similar to this for all Dapps I’ll cover
in the book. The lifecycle of an Ethereum transaction will be cemented in your head
progressively throughout the book, until it becomes second nature to you.
1. Transfer click
event is
handled by
web page
JavaScript
To: ac3432a <Javascript>
Javascript and
Amount 120 Web3.js code
</Javascript>
Transfer <HTML>
8. Transfer </HTML>
user public address: confirmation
from:0x6cba SimpleCoin is displayed SimpleCoin
web wallet app on web page wallet web app code
Transaction
Event Internet
from:0x6cba
Transfer
to:0xac3432
amount:100
6. Block is validated,
executed, and
propagated to peers
Peer Local
full node full node
Block 233
tran1652b1
tran27655c
5. Transaction is Transaction
Block 233 3. Transfer transaction
placed on new block; from:0x6cba
tran1652b1 is validated and
block is propagated to:0xac3432
tran27655c propagated to peers
to peers amount:100
Transaction
from:0x6cba
to:0xac3432
amount:100
Peer
Mining node full node
4. Transfer transaction
is validated and
propagated to
mining node
Figure 3.15 The lifecycle of a SimpleCoin transfer transaction. A transfer transaction is created
when a SimpleCoin wallet invokes the transfer() function on the SimpleCoin smart contract
on a local node of the Ethereum network. This is then validated and propagated throughout the
network until it’s included on a new blockchain block by a mining node. The new block is then
propagated throughout the network, and finally it gets back to the local node.
Summary
The Ethereum wallet is a GUI that allows you to interact with the platform by
creating accounts and transferring Ether intuitively.
The most popular Ethereum client is Go Ethereum, also known as geth. It
comes with an interactive console that references Web3.js, a high-level interface
to Ethereum clients.
It’s possible to interact with geth, for instance to create accounts, through vari-
ous avenues:
– geth commands executed in the operating system command shell
– Web3.js instructions executed in the geth interactive console
– HTTP JSON-RPC commands executed through cURL or a UI tool such as
Postman
Ethereum smart contracts, or just contracts, are written in a high-level language
such as Solidity, compiled into EVM bytecode, deployed on the Ethereum net-
work, and stored in the blockchain.
It’s possible to communicate with contracts using calls, transactions, and events.
A transaction involves the consumption of computational and network resources,
which is calculated in a unit called gas and settled in Ether, the cryptocurrency
of the Ethereum platform.
72
EthTweet 22 J
events, raising 66
Everledger 18 JSON-RPC protocol 51–55
EVM (Ethereum Virtual Machine) 37, 45 accessing blockchain with 55
exchanging Ether 41 checking client connectivity with 53–54
displaying version information with 53
externally owned accounts (EOA) 39, 59
managing accounts with 64
JVM (Java Virtual Machine) 45
F
fast synchronization 33
K
faucet 35 keyfile 59
full nodes 10, 46 keystore folder 59
full synchronization 33 KYC-Chain 19
G L
gambling 21–22 listing accounts
gas 42–43 with geth commands 61
geth with Web3 on geth console 62–63
commands 60–62
console 48–51 M
accessing blockchain 50–51
checking connectivity 49–50 MAINNET network 47
manual protocol 16
displaying version information 48–49
MediLedger 19
mining with 56–57
memory 45
performing conversions 51 miner.start() function 56
JSON-RPC 51–55 mining
accessing blockchain 55 Ether 35
checking client connectivity 53–54 with geth console 56–57
displaying version information 53 minting, Ether 41
overview of 47–48 msg variable 25
Web3 on console 62–64 msg.sender property 25
GPU mining 58
N
H
network nodes 10–11
Hardware wallet 41
hash map 25 O
hexadecimal encoding 54
Online wallet 41
OpenBazaar 2
I ownership, proving 19
IaaS (Infrastructure as a Service) 4
identities, verifying 19
P
independent transactions 3 P2P (peer-to-peer) networks 5–7, 9, 45
Infrastructure as a Service (IaaS) 4 Paper storage 41
_initialSupply parameter 65 parameterizing constructors 65
international trade finance 20–21 Parity 58
Internet of Things 19 participant nodes 9
V W
validation 7 wallets for Ethereum 32–37
variables common operations with 35–37
See state variables overview of 32–34
version information we.trade 20
displaying with geth console 48–49 web applications 8
displaying with JSON-RPC 53 web3.eth object 62
volatile memory 45 web3.eth.sendTransaction function 63
vote processing 7 Web3.js libraries 8
VoteConfirmation event 15 on geth console 62–64
voting web3.net.peerCount 54
centralized web3.personal object 62
security in 5 Wire protocol 9–10
trust in 5
centralized applications 4–5
decentralized applications 5