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 WellKnown.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 suddenly...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, probably I’ve said it too fast. I’ll repeat it more slowly:
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 applications. 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 pronounced 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, implement, 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.
Before I talk about decentralized applications, I’ll refresh a concept you’re already familiar with, most likely without realizing it: that of a centralized application. Probably you’ve never heard this expression before because conventional web and enterprise applications are implicitly centralized with respect to their users. I can hear you asking, what does “centralized” mean exactly?
A centralized application or system is controlled by a single or central entity: an individual, company, institution, governmental agency, and so on. The entity hosts the system 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 system. You shouldn’t find anything surprising about it.
Let’s move on to decentralized applications. If you consider for a moment the alternative e-commerce application I introduced earlier, you’ll agree it has advantages with respect to SmallWebRetailer.com:
Consensus is a distributed and trustless form of agreement on the verification of a transaction. Distributed means that an independent central authority doesn’t perform the verification of a transaction; instead, all parties contribute to and agree on its verification. Trustless means that parties don’t need to trust each other to agree on the verification outcome. Consensus is reached when a qualified majority of the participants have agreed on the outcome of the transaction.
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
The consequence of this architecture would be that the processing would be decentralized 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.
To explain more clearly the benefit of building a Dapp, as opposed to developing a conventional centralized application, I’ll illustrate for you a typical use case: an electronic voting application.
Traditional centralized voting applications are generally provided by a company to facilitate shareholder voting or by a local administration or government to facilitate the approval or selection of law proposals. The institution running the application owns it, directly or indirectly, at least during the voting session.
As you can see at the top of figure 1.2, a centralized voting application runs on one or more application servers connected to a central database. The system is exposed to the voters through one or more web servers hosting the voting website. The institution can have the web, application, and database servers hosted directly on the premises or in the cloud. Cloud hosting can happen through a cloud computing provider offering Infrastructure as a Service (IaaS) if the voting system has been implemented in-house by the institution, or through a cloud application provider offering Software as a Service (SaaS) if the voting system is only leased or rented from an external provider 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.
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 collected, processed, and stored at various levels of the application architecture. Depending on how the application has been designed, it could be possible for some malicious database administrators to even modify votes retroactively.
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 system was secured adequately against external manipulation. For example, external parties 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.
A decentralized application is based on two key technical principles:
How can you address trust and security concerns by decentralizing the voting application according to the two principles I outlined? A decentralized voting application makes trust and security breaches pointless by replicating its execution over a network including many servers, each in theory owned by a different party. Think about it: if votes were processed and verified not by one single server but independently by many servers owned by different parties, and they were stored not in a single database but in many databases, each one local to the processing party, both trust and security concerns would be addressed:
A blockchain database is based on a data structure that, as its name suggests, is a chain of blocks. A block can be seen as a record containing a set of transactions, each one digitally signed, some metadata (such as block number and time stamp information), and a link to the previous block. Each transaction, each block as a whole, and the links between blocks are secured with cryptographic technology, which makes them immutable: retroactive alteration of single transactions is nearly impossible, especially as more blocks are added to the chain. A blockchain database therefore addresses trust and security concerns by providing further protection against manipulation attempts by malicious participants and external parties.
At this stage, you might find the decentralized voting application concept promising from a logical or a high-level point of view, but you might still be confused about physical and lower level aspects of its architecture. You might have doubts in various areas:
I’ll try to answer these questions in the next two sections, which cover low-level details of the decentralized voting application. I’ll also assume the voting Dapp has been developed for Ethereum, the blockchain and Dapp platform this book is focused on. Doing so will allow me to start introducing Ethereum and to refer to concrete infrastructural components while presenting two complementary low-level views of the system:
The structural view of the decentralized voting application includes a description of the components of both the client side, represented by the web UI through which a voter submits a vote, and the server side, represented by a network of servers running the application logic.
The voting application web client, shown in figure 1.3, gets initially downloaded into the user browser from a conventional web server, generally as a web application containing HTML and JavaScript. The web user interface doesn’t contain any server-side scripts and communicates directly with a specific server of the network through a client-side JavaScript library called Web3.js. It might also allow the user to communicate with a network node located on their premises. So far, this application differs in no major way from a conventional web application.
The server side of a decentralized application is a P2P network of servers that run the same code and have identical copies of a blockchain database. As you know, a key characteristic of this network topology is that it uses no central coordination, but instead uses direct communication between each node and a number of other nodes, known as peer nodes or simply peers. No master node is needed. As shown in figure 1.4, a node doesn’t need to be connected to all of the other nodes of the network. Being connected to a few nodes is sufficient to ensure transactions are rapidly propagated to the whole network.
Various P2P networks supporting blockchain platforms exist. The most well-known one is the Bitcoin network.
In this book, I’ll focus on the Ethereum network, whose participant nodes, as shown in figure 1.5, host a blockchain database and a piece of software called a node client, which allows a node to communicate with other nodes. Because all nodes are equivalent to each other, within the Ethereum network you have no clear-cut concept of client and server. Each node is a server to other nodes, but, at the same time, it’s also a client of other nodes. That’s why the software element of an Ethereum node is called a client.
Ethereum clients expose a common client interface and communicate with each other through a P2P protocol called Wire. That protocol enforces a standard way of sending data throughout the network, specifically a transaction, such as a submitted vote, and a block, such as a set of votes consolidated in the blockchain database.
Various implementations of an Ethereum client exist. As you can see in figure 1.5, they’re written in various languages, from C++ to Go, but all implement the standard client interface and the Wire protocol, so they can interact seamlessly.
The advantage of an Ethereum node client over a Bitcoin node client is that it’s able not only to propagate cryptocurrency transactions and blocks throughout the 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 blockchain. 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.
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:
You’ve examined the structural view of the voting Dapp. Figure 1.7 shows the entire system, including the client and server sides.
Adding a temporal dimension to the static view you saw in figure 1.7, figure 1.8 illustrates step-by-step the full lifecycle of a voting transaction:
Although decentralized applications are a relatively new idea, standard terminology around them started to appear relatively soon after the first Dapps were built. In this section, I’ll provide a summary of the key terms that Vitalik Buterin, the creator of Ethereum, described in a famous blog post[1] he wrote to explain key Dapp concepts. You’ve already come across some of these terms in the previous sections, but now I’ll define them more precisely.
Vitalik Buterin, “DAOs, DACs, DAs and More: An Incomplete Terminology Guide,” http://mng.bz/vNrq.
A smart contract is an arrangement between two or more parties that involves an exchange of digital assets. One or more of these parties allocates digital assets to the contract at its initiation. Subsequently, the assets are redistributed among the parties according to a predefined protocol encoded in logic and a state that’s initialized at the start of the contract.
An autonomous agent is a software entity that interacts autonomously with external software services and can reconfigure or even reprogram itself following verified changes in the external environment.
A traditional centralized organization contains assets and different classes of individuals, typically investors, employees, and customers. Investors control the organization by owning a part of it through the purchase of shares. Interactions between some classes of individuals are influenced by whether they control the organization. For instance, employees can get recruited by investors or by other employees authorized directly or indirectly by investors.
A decentralized organization (DO) isn’t controlled by any one person or entity. Predefined protocols are what determine interactions between classes of individuals involved in the organization. But such protocols can be designed so that certain individuals have more power than others—for instance, depending on the number of shares owned—exactly as with centralized organizations.
A decentralized autonomous organization (DAO) is both a DO and an autonomous agent. Like an autonomous agent, it’s a software entity that interacts autonomously with 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 programmed 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 manual protocol rely entirely on the reputation of the individuals following it.
According to these definitions, opinions diverge as to whether blockchain platforms 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 implementation of easily automated interaction protocols, some think it should be classified as a DO.
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 redistributes dividends periodically, depending on its financial success. A pure DAO, on the other hand, is generally a nonprofit organization, and participants benefit economically exclusively by contributing to its ecosystem and increasing its internal capital.
The current widely accepted definition of decentralized application corresponds to that of DAO described previously, which is still in use among Ethereum purists. I’ll use this definition for Dapp for the rest of this book. The reason why the initial terminology used the word organization rather than application was because the Ethereum founders wanted to put emphasis on the fact that a decentralized application can transact with other parties exactly like conventional organizations: by following rules and protocols and exchanging monetary value, obviously in the form of cryptocurrency rather than conventional currency.
The key aspects of each of these terms are summarized in table 1.1.
|
Is software |
Has capital |
Is autonomous |
Is owned |
---|---|---|---|---|
Autonom agent | YES | NO | YES | NO |
DO | NO | YES | NO | YES |
DAO | YES | YES | YES | NO |
DAC | YES | YES | YES | 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.
Decentralized applications shouldn’t be confused with distributed applications. The two concepts have similarities, but they’re not the same thing.
An application is distributed if it runs over multiple servers within a network. The simplest example of a distributed application is a web application, which is typically distributed over a web server, an application server, and a database server, and possibly an email server and legacy mainframes. The centralized voting application seen earlier is an example of a distributed application. It’s distributed because it’s spread over several servers, but it’s also centralized because all the servers are owned by the same institution.
A distributed application runs over multiple servers of a network. A decentralized application is replicated in its entirety over each node of a wide network.
Comparison of the structures of distributed and decentralized applications
An application is decentralized if it’s replicated in its entirety over each node of a network, 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 trustful 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.
In the last few years, many Dapps have been developed. Some have received various rounds of venture capital funding and have been deployed successfully into production. Others have failed to convince investors and users and never passed the proof-of-concept stage.
Given the novelty of the technology, it’s hard to predict what’s going to work and what’s going to fail. Nevertheless, various use cases are being widely recognized as a good fit for the blockchain and in particular for Ethereum. Ideal Dapps are those that take advantage of the main benefits of these technologies, specifically record immutability, decentralization, security, and resilience. As a result, the main fields likely to be revolutionized by Dapps are provenance and ownership tracking, authenticity tracking, identity verification, regulatory auditing, charity expense auditing, prediction markets, customer loyalty management, crowdfunding, electronic voting, investing, gambling, lending, online games management, author royalty payment, Internet of Things, cloud computing, and even freedom of speech. Let’s see what innovative solutions have already been found in some of these areas.
One of the biggest problems affecting supply chain management, particularly when involving long chains of processed goods crossing several countries, is tracking the authenticity of materials. Here are some Dapps that are innovating in this area with blockchain-based solutions:
As with provenance tracking, verification of proof of identity tries to protect businesses 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 manage 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.
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; commodities, 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.
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.
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 interest rates at a specific date, or the winner of a sports competition. Aside from speculative 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, several 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:
International trade between a supplier and a manufacturer located in different countries is a complex business. As you can see in figure 1.9, it’s generally based on a complicated workflow involving many parties, such as banks that facilitate the payment, commercial intermediaries that facilitate the distribution, shipping and delivery companies 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 simplifying 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 that no one will tamper with it. Trades that used to take weeks can be now completed in a few days.
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.
WeiFund aims at providing open source modular and extensible decentralized crowdfunding 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 happen with their money if the campaign fails or is successful.
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 technology. We’ll explore this in the next section.
Deciding whether the blockchain is a suitable technology for an application you’re planning to build might be difficult. What you should ask yourself is whether the functionality that a blockchain platform offers will meet your business requirements. More importantly, consider whether the benefits of using such a platform would be outweighed by all the technical limitations and additional complexities that come with this technology. A sobering blog post titled “Avoiding the Pointless Blockchain Project”[2] analyzes the requirements necessary to justify the use of a blockchain platform over more traditional technologies such as SQL or NoSQL databases. It concludes that a blockchain project only makes sense if you can answer yes to all of the following questions:
Gideon Greenspan, “Avoiding the Pointless Blockchain Project,” http://mng.bz/4Oqg.
According to these criteria, for example, an internal enterprise application that wouldn’t expose any data to external parties wouldn’t be a suitable choice for a Dapp. Other poor Dapp candidates are applications for which confidentiality around the business rules is important. A smart contract is, by definition, completely open and transparent to all interacting parties. Therefore, preventing participants from accessing and understanding the logic of the rules would defeat the purpose.
Although decentralized microblogging applications such as EthTweet are considered sensible Dapps to those who value the fact that messages can’t be censored and altered after they’re sent, an instant messaging Dapp, such as a “decentralized WhatsApp,” wouldn’t be a particularly useful product for a fundamental reason. One of the technical downsides of the blockchain platform is that processing transactions (in this case instant messages) requires roughly 15 seconds to consolidate a new blockchain block. Therefore, messages would never be instant at all.
When building a Dapp, you also should keep in mind some operational aspects that, given the novelty of the technology, may cause some issues down the road. For instance, although a smart contract can automatically guarantee funds are routed and released subject to certain conditions, a commercial transaction might also be subject to real-world conditions that programming logic can’t enforce. A classic example for a non-fully automatically 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 automatically give it back to the lender if the borrower missed an interest payment, the borrowing 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.
By now, you should have a good understanding of what a Dapp is, the purpose of Dapps over conventional apps, the main architectural components of a decentralized application, and whether it makes sense to embark on a project based on blockchain technologies. It’s now time to take one little step further and get on with some programming. In the rest of the chapter, you’ll start building the smart contract for a custom cryptocurrency. You’ll then activate it and interact with it.
Most Dapps are designed using functionality based on the exchange of cryptocurrency or tokens through rules encoded in one or more smart contracts. You’ll start to get a feel for Dapps programming by building SimpleCoin, a basic cryptocurrency that will present useful preliminary concepts about smart contracts and the Ethereum platform. You’ll progressively build on it in the following chapters, where you’ll learn more about Dapp development. You’ll also use or reference SimpleCoin from other Dapps that you’ll build in later chapters.
Because you haven’t installed an Ethereum platform client on your computer yet, you’ll be writing code on the Remix Solidity (previously known as Browser Solidity) integrated development environment (IDE) for now. This online tool will allow you to implement smart contracts in a high-level language called Solidity, similar to Java-Script, and run them on a local JavaScript VM that emulates the Ethereum Virtual Machine that you’ll meet in the next chapter. It’s also possible through this tool to interact with real smart contracts deployed on the Ethereum network.
Open a web browser and go to: http://remix.ethereum.org/. You should see a screen like figure 1.10. On the website, the left side of the IDE is a file explorer (which you can hide by clicking the double arrow toggle at the top left); in the middle you have the code editor; and the right side contains various panels to run the code and interact with it.
In your first encounter with Solidity, you’ll implement the simplest possible smart contract. If you think of a smart contract as the equivalent of a class in an object-oriented language, you’ll write a single class with only one member field, one constructor, and one method. Then you’ll run it and interact with it.
Hide the file explorer by clicking the double arrow toggle at the top left, and then enter the code in listing 1.1 in the Remix editor, in the left side of the screen.
pragma solidity ^0.4.0; 1 contract SimpleCoin { 2 mapping (address => uint256) public coinBalance; 3 constructor() public { 4 coinBalance [0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C] = 10000; 5 } function transfer(address _to, uint256 _amount) public { 6 coinBalance[msg.sender] -= _amount; 7 coinBalance[_to] += _amount; 8 } }
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 represents 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 terminology, 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 implementation 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 SimpleCoin 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.
Move now to the right side of the screen to deploy the SimpleCoin contract. First, make sure the Auto Compile option in the Compile tab is checked, as shown in figure 1.11, so that Remix will recompile the code at every change. Also, make sure you’ve selected version 0.4.24 of the compiler (for example 0.4.24+commit.e67f0147), because this is the version I’ve been using when writing SimpleCoin.
If you’ve typed your code correctly (I recommend you copy the code from the files provided 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.
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.
Now that the SimpleCoin contract has been deployed, you’ll be able to perform simple operations against it: you’ll check SimpleCoin token balances and move tokens across accounts.
Click the SimpleCoin drop-down list within the Deployed Contracts panel. Two new buttons will appear: CoinBalance and Transfer, as shown in figure 1.14.
The Remix IDE shows two types of buttons:
In this case, CoinBalance is blue because it allows you to read the coin balance associated 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 constructor 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 bottom, 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.)
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.
Account address |
Account balance |
---|---|
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
Now click Transfer. The function returns no result, as expected.
Check the number of tokens present in the contract creator’s address by clicking CoinBalance after entering the contract creator’s address ("0x14723A09AC-ff6-D2-A60Dcd-F7aA4AFf308FDDC160C") in the related text box. The value is now 9,850, as expected.
If you perform the same check on the destination address ("0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB"), you’ll get 150. All other addresses still have zero tokens, as summarized in table 1.5.
Account address |
Account balance |
---|---|
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 certain 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.
If the compiler configured in the Compile tab is version 0.4.25, Remix will only allow you to enter addresses with a valid checksum in the code editor. I’ll explain what a valid checksum is in chapter 5. But for now, it means 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c (all in lowercase) and 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C aren’t interpreted as being equivalent to each other. Unfortunately, addresses in the Account drop-down within the Run tab are all in lowercase and therefore aren’t compliant. If you want to know the corresponding address with a valid checksum, you can use Etherscan, the online blockchain viewer (https://etherscan.io/). Enter the incorrectly formatted address (for example, 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c) in the text box at the top of the screen, and you’ll see the correctly formatted corresponding address (0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C) in the Address header also at the top of the screen.