• Non ci sono risultati.

On programming Ethereum smart contracts: a ticketing application.

N/A
N/A
Protected

Academic year: 2021

Condividi "On programming Ethereum smart contracts: a ticketing application."

Copied!
104
0
0

Testo completo

(1)

SCUOLA DI INGEGNERIA

DIPARTIMENTO DI INGEGNERIA DELL’INFORMAZIONE

Tesi di Laurea Specialistica in Ingegneria Informatica

ON PROGRAMMING ETHEREUM SMART CONTRACTS:

A TICKETING APPLICATION

Candidato:

Sara Cadau

Relatori:

Prof. Gianluca Dini

Ing. Stefano Di Sandro

Ing. Alessio Bechini

(2)

purpose of investigate the potential of using Ethereum blockchain technology and to better understand the basic mechanics behind a smart contract through a real world example: the sale of event’s tickets.

The system developed handles the selling of tickets using 2 different smart contracts that interact one each other in a completely automated way to offer a complete selling service across provider, retailer and final customer. In order to analyze the dynamics among these entities I implemented three possible interaction models This document wants to be an introduction to the basics of Ethereum that you will need to understand from a developer’s standpoint, in order to produce contracts and decentralized applications.

(3)

I Introduction to Blockchain 4

1 Introduction to Bitcoin 5

1.1 Bitcoin . . . 5

1.2 The Blockchain . . . 6

2 Ethereum 9 2.1 The Ethereum Project . . . 9

2.1.1 What is Ether . . . 9

2.2 How it works . . . 10

2.2.1 Nodes . . . 11

2.2.2 Smart Contracts . . . 11

2.2.3 Gas and Execution Costs . . . 12

2.2.4 Accounts . . . 13

2.2.5 Transactions . . . 14

2.2.6 The Ethereum Virtual Machine (EVM) . . . 18

II Development in Blockchain 20 3 Smart Contracts Development 21 3.1 Write a Smart Contract: The Solidity Language . . . 21

3.1.1 Introduction to Smart Contracts . . . 21

3.1.2 State Variables . . . 22

3.1.3 Our first tiny contract . . . 22

3.1.4 Visibility in Solidity . . . 23

3.1.5 Functions . . . 24

3.1.6 Remarkable Data Types: Address Type . . . 25

3.1.7 Remarkable Data Types: Mappings . . . 27

3.1.8 Modifiers in Solidity . . . 28

3.1.9 Events . . . 28

3.1.10 Inheritance . . . 29

3.1.11 Handling errors . . . 31

3.1.12 Interacting Smart Contracts in Solidity . . . 31

3.1.13 The Death of a Contract . . . 34

4 Deploy Ethereum Smart Contracts 35 4.1 A Browser Tool: Remix IDE . . . 35

4.2 Compile and deploy a Smart Contract Locally . . . 38

4.2.1 The Node.js Package Manager: npm . . . 38

(4)

4.2.2 The solc compiler . . . 38

4.2.3 The Truffle Suite . . . 43

4.2.4 Testing Smart Contracts on Truffle . . . 46

4.2.5 The TestRPC Node Utility . . . 49

4.3 Interact with the Blockchain using Client Interfaces . . . 50

4.3.1 Metamask . . . 50

4.3.2 The Geth Console . . . 53

5 Integrating the Ethereum Blockchain into Apps 54 5.1 The WEB3.js Library . . . 54

5.1.1 Making web3 accessible . . . 54

5.1.2 Sending Transactions . . . 55

5.1.3 Callback Functions . . . 60

5.1.4 Deploy Contracts . . . 61

5.1.5 Call Smart Contract Functions . . . 64

5.1.6 Interacting Smart Contract . . . 67

III A Real World Blockchain Based Example 69 6 Provisioning dApp 70 6.1 Introduction . . . 70

6.1.1 The Project . . . 70

6.1.2 Base scenario . . . 70

6.1.3 The Browser Interfaces . . . 71

6.2 Intermediated Selling . . . 73

6.2.1 The 2-steps Selling . . . 73

6.2.2 The Direct Selling . . . 81

6.3 Pre-Sale Selling . . . 85

6.3.1 Phase 1: The Pre-Sale . . . 86

6.3.2 Phase 2: The Sale . . . 89

7 Conclusions 93 7.1 General Considerations . . . 93

7.2 Time and Costs: two sticking points . . . 95

Appendix 97 Appendix A: Recursive Length Prefix . . . 97

(5)

In 2008 a person or a group of people known as Satoshi Nakamoto released the white paper "Bitcoin: A Peer-to-Peer Electronic Cash System" [1.1] starting the cryptocurrency revolution.

The system proposed by Nakamoto reforms the payment system as we know it because transfer payments cost almost nothing. Cryptocurrency technology will allow us to reach everyone even who hasn’t a bank account, this will transform the way business will be done by discarding the role of the middleman.

The possible applications will be wide-ranging and include global payment and remittance systems, decentralized exchanges, merchant solutions, online gaming, and digital contracting systems.

Standing the interest in cryptocurrency, it is not surprising that there was en-couragement all around to start a variety of projects on digital currency with special emphasis on cryptocurrency. All these projects are based on the same data structure used by Bitcoin: the blockchain.

The blockchain is a public digital ledger on which the entire network relies, it offers a way to securely create a tamper-proof log of sensitive activity (like money transfers) and has gotten a lot of attention recently thanks largely to Bitcoin.

The tech community is now finding other potential uses for the blockchain tech-nology like: distributed cloud storage, digital identity management ( i.e. for bank-ing, health-care, authentication), digital voting and above all smart contracts, a blockchain 2.0 feature introduced for the first time in the Ethereum Project by Vi-talik Buterin.

However, there are downsides or potential risks for cryptocurrency too. Cryp-tocurrency like Bitcoin depends on mining, and once the incentives for mining will disappear, no one knows if the cryptocurrency in question will continue to have consensus on the digital register.

There are over 400 cryptocurrencies and the number is increasing on a daily basis. At the moment Ethereum is the second most important cryptocurrency system, the cryptovalue it uses is named Ether (ETH). As said before the system relies on a new generation blockchain platform ( or blockchain 2.0 ) and provides a living environment to smart contracts, code fragments of arbitrary complexity, deployed in the blockchain and executed in the same way by all the nodes of the network.

The following document will explore the world of smart contracts by a developer point of view. In the first part we’ll see an introduction to the technology followed by a guide to implement a decentralized application based on Ethereum Blockchain System with some examples in Solidity ( the language of election for Smart Contracts ). The third and final includes a description of the dApp I developed to experiment the technologies we’ll discuss.

(6)

Introduction to Blockchain

(7)

Introduction to Bitcoin

1.1 Bitcoin

Bitcoin, the first decentralized cryptocurrency, was designed to address some of the issues that a centralized system could not resolve. In particular Bitcoin is designed as an alternative to the classic payment system in which the control was decentralized and the supply of money was predetermined.

The proposed system was born as a solution to the double-spending problem so that every cryptocurrency can be spent only once. In this system a timestamp is generated as computational proof of the chronological order of transactions. The architecture is peer-to-peer and distributed so there is no need of trusted third parties anymore. The payment system uses cryptographic proof instead of trust to verify transactions. Bitcoin is run using open-source software, which means it can be downloaded by anyone, and the system runs on a decentralized peer-to-peer network. It is not only decentralized but also fully distributed, this means that all the nodes or computer terminal are connected with each other.

Every node can leave and rejoin the network whenever it wants and will later accept the longest proof of work known as the blockchain as the authoritative record. This longest blockchain is the proof of what has happened while these nodes were gone. To an outsider, bitcoin is a digital currency that is created and held electronically. These bitcoins are sent and received using a mobile app, computer software, or ser-vice provider that provides a bitcoin wallet. The wallet generates an address, similar to a bank account number, except that a Bitcoin address is a unique alphanumeric sequence of characters where the user can start to receive payments. Usually, bit-coins may be obtained by buying them at a Bitcoin exchange or vending machine or as payment for goods and services.

Bitcoin solves the double-spending problem by maintaining a ledger of balances, but instead of relying on a single trusted third party to manage this ledger, Bitcoin de-centralizes this responsibility to the entire network.

This solution is revolutionary because the double-spending problem can be solved without needing a third party. In computer science, the double-spending problem refers to the problem that digital money could be easily spent more than once. Other than that the system uses public-key cryptography and each transaction has a digital signature and also contains a hash that permits an easy tamper detection.

All Bitcoin transactions are published online, but the only information that identifies a Bitcoin user is a pseudo-randomly generated Bitcoin address, making the transac-tions somewhat anonymous. This potential anonymity is distinct from the anonymity

(8)

provided by other electronic payment systems. Bitcoin’s anonymity depends on the actions of the user, in other words, in Bitcoin you don’t need to explicitly register or reveal your real-world identity, but the pattern of your behavior might itself be identifying.

1.2 The Blockchain

The distributed architecture on which the entire Bitcoin network (as other cryp-tocurrency systems) relies is called Blockchain.

Basically the blockchain is a publicly accessible database shared by all nodes par-ticipating in a system based on, for example, the Bitcoin protocol. A full copy of a currency’s blockchain contains every transaction ever processed, allowing anyone to use Bitcoin software to verify the validity of a transaction.

Because any entity can submit information to the blockchain, it is necessary for the operators of the blockchain to evaluate and approve all insertions before they are permanently included into the blockchain. We cannot be sure of the authors trust-worthiness so it is vital that all new information must be checked and confirmed before being accepted.

New transfers of cryptocurrency, or transactions, are broadcast to the entire network and checked against the blockchain to make sure that the bitcoins have not been al-ready spent, thus solving the double-spending problem. Each node collects all these transactions into a block, only one block can be added at a time, and every block contains a proof (a Hash Pointer ) that ensures that it follows in sequence from the previous block.

Inside a block transactions are organized in a Merkle tree structure. Merkle trees are binary trees of hashes. Merkle trees in bitcoin use a double SHA-256, the SHA-256 hash of the SHA-256 hash of something. [1.2] A merkle tree is a tree constructed by hashing paired data (the leaves), then pairing and hashing the results until a single hash remains, the merkle root. In Bitcoin, the leaves are almost always transactions from a single block. [1.3] A simplified scheme of how the blocks are organized is showed in Figure 1.1.

Figure 1.1: Simplified Blockchain (Source)

A node is a computer that partecipates in the distributed network. This parte-cipation can be in different ways:

(9)

the complete ledger. A light client is program that allows users in low-capacity environments to still be able to execute and check the execution of transactions without needing to run a full node. When a common user installs a bitcoin wallet and emits transactions he runs a light node.

• Full: Any computer, connected to the network, which fully enforces all the consensus rules of the network is called a Full Node. A full node downloads the entire blockchain in the user’s device. Full nodes form the backbone of the system and keep the entire network honest. Some of the consensus rules that full nodes enforce are:

– Making sure that the correct block reward is given out for each block mined

– Transactions have the correct signatures

– Transactions and blocks are in the correct data format – No double spending is occurring in any of the blocks

The full nodes basically validate the nodes and transactions and relay the information to the other nodes (using the gossip protocol).

• Miner: A miner is a particular type of full node which additionally creates new blocks. Any node connected to the blockchain can maintain and verify the network. In this case the node has a full copy of the ledger in memory, collects transactions and proposes new blocks to the consensus protocol. This kind of node is incentivized to a honest behavior by mathematically enforced economic incentives coded into the protocol.

What we call ‘consensus’ is a security aspect of the blockchain technology which ensures that the ledger transactions is kept synchronized across the network. Nodes accept the block only if all transactions in it are valid and not already spent and express their acceptance of the block by working on creating the next block in the chain using the hash of the most recent accepted block as previous hash pointer value. There are three main methods of finding consensus in blockchain: Practical Byzantine Fault Tolerance (PBFT), Proof of Stake (PoS) and Proof of Work (PoW). Bitcoin uses the Hashcash Proof of Work system for block generation, in order for a block to be accepted by network participants. Miners must complete a proof of work which covers all of the data in the block. The difficulty of this work is adjusted so as to limit the rate at which new blocks can be generated by the network to one every 10 minutes.

Due to the very low probability of successful generation, this makes it unpredictable which mining computer in the network will be able to generate the next block. For a block to be valid it must hash to a value less than the current target; this means that each block indicates that work has been done generating it. Each block contains the hash of the previous block, thus changing a block (which can only be done by making a new block containing the same predecessor) requires regenerating all successors and redoing the work they contain. This protects the block chain from tampering. In the blockchain environment something called fork can happen, basically in some special conditions the chain is divided in two branches and just one of them will be considered as valid. When nodes add new blocks they consider the longest chain as the valid version of the blockchain so the next block will be attached to it confirming that branch as the valid one. What happens is showed on Figure 1.2.

(10)

Figure 1.2: Blockchain Fork Example (Source)

This system doesn’t rely on a trusted party server to maintain the ledger. Each node keeps a list of all the transactions ever made organized in blocks made and connected to each other in the same way for every node. In this way the blockchain’s “distributed database” is kept in consensus across the whole network.

Individual user interactions with the ledger (transactions) are secured by strong cryp-tography, the most widely used proof-of-work scheme is based on SHA-256 and was introduced as a part of Bitcoin. There aren’t accounts, each user is referred using ad-dresses (each user can have as many adad-dresses as he likes) and the system calculates balances through the value of transaction an address did. With this informations, anyone can find out how much value belonged to each address at any point in history and verify if that address has enough funds to perform a particular transaction. The most common alternative to PoW is proof of stake. In this case nodes are called validators (or Minters) and instead of resolving mathematical problems they invest coins in the system. A miner’s chance of being chosen to create the next block is proportional to the amount of currency he owns. Once a node creates a block it still has to be committed to the blockchain. In this case we have different mechanisms to handle this, two examples being Tendermint and Casper.

(11)

Ethereum

2.1 The Ethereum Project

Since Bitcoin’s announcement in 2008 the world of cryptocurrencies is constantly evolving, new features appeared giving birth to what we called blockchain 2.0. This new version is an environment in which, in addition to transactions, it is possible to execute code fragments of arbitrary complexity, the smart contracts. Using smart contracts blockchain operations can be automated and executed without a middle-man.

The original blockchain accepts the execution of Script code designed to be Not Turing Complete. The Script code has a low complexity and doesn’t allow some features (like loops) making the language deterministic (you can know for sure when and how a given program will end) and lightweight. The language design has also an attack prevention purpose: with loops and recursion it becomes more difficult to limit the resources required by a script. It would be possible to create scripts which crash nodes, which take hours to validate or which consume the host memory. The execution time is easy to control by limiting the length of the script. This type of code is purposely simple but introduces a lot of limitations, for this reason developers carried forward projects to expand the way in which users interact with blockchain. One of the most important project is Ethereum, a system announced in 2014 by Vitalik Buterin, Gavin Wood and Jeffrey Wilcke. Its first version, called Frontier, was released in 2015 followed a year later by Homestead, the actual version.

Ethereum works on its own blockchain and supports the execution of code fragments, smart contracts. Ethereum supports more complex languages which potentially can solve any computational problem. The aim of the project is to propose an alterna-tive environment to bitcoin for the development of decentralized applications better fitting to programmers needs.

2.1.1 What is Ether

The criptocurrency used in the Ethereum system is ether, ETH, and it is currently valuated at over 700 e(you can check the actual value at cryptocompare.com). Ether is a digital asset necessary for the Ethereum distributed platform functioning, it is similar to bitcoin from a security point of view. Just like cash it doesn’t require

(12)

a third party to process or approve a transaction.

Ether provides the fuel for decentralized applications on the network. This means to perform any kind of change in the network you need to pay a transaction fee in ether.

The transaction fees are calculated based on how much computational power is re-quired and how long it takes to run the requested operations.

Unlike the Bitcoin system there is no upper limit to the amount of ether produced in the network. When the platform was released 60 millions ether where created on presale. 12 million were created to the development fund and 5 ethers were created for every block mined as reward.

On October 2017 there was a major update on the system called Byzantium in which the reward was reduced to 3 ethers for block.

The ether supply is not infinite, the issuance of ether is set at 18 million per year. This rate is not expected to be kept: sometime in 2018-2019 Ethereum will be switched from Proof of Work to a new consensus algorithm under development, called Casper that is expected to be more efficient and require less mining subsidy.[2.1]

Ethereum has a metric system of denominations used as units of ether. The smallest one is Wei, one Ether is equal to 10ˆ28 Wei. This denomination is the base unit of ether, it is used to specify quantities of currency like fee amounts.

The Wei and Gwei units are the most used. Here’s a list of denominations from the Ethereum documentation:

Figure 2.1: Ether’s Denominations

2.2 How it works

Ethereum Blockchain is programmable, instead of giving users a predefined set of operations (like script language in Bitcoin blockchain) Ethereum allows them to create their own programs.

In this way it offers a platform to a various types of decentralized application rather then simply elaborate transactions. Obviously performing more complex operations has a higher execution cost.

Ethereum works similar to Bitcoin, nodes maintain and update the distributed ledger. Each node runs the Ethereum Virtual Machine (EVM) which executes instructions in the same way for every node connected to the network.

In Ethereum executing programs is possible thanks to the EVM which is capable of executing algorithms of arbitrary complexity. Programs are developed in different

(13)

high level languages and then compiled in a low level language designed to run into the EVM.

The most used language is Solidity, very similar to Javascript, but also Serpent, a python-like language is commonly used.

Ethereum is a quasi-Turing Complete system: to be complete it should be capable of execute programs which never terminate. In Ethereum it’s not possible that some program keeps running indefinitely because the computations are strictly bounded to a parameter which limits the amount of operations done. More practically speaking executing a code has a price and the user decides how much he’s willing to pay right before start the execution. (more details in the Gas and Execution Costs paragraph)

2.2.1 Nodes

Blockchain’s nodes are peers of a distributed network, there are no servers o hier-archies of users. Participants keep the network updated, each node executes the same instructions on their own EVM. The system works this way not for efficiency purposes but to maintain the consensus. The network guarantees an extreme fault-tolerance and protects data saved on the blockchain from many kind of attacks which aim at stealing or tampering the assets.

Security is a priority in a blockchain based system and this fact goes against running time.

Any device can be a blockchain node,there are have different types of node de-pending on how they participates in the network. Like in Bitcoin the backbone is made by node which keep a full copy of the ledger saved locally named full nodes. These nodes effectively participate in the maintenance and updating of the blockchain and can validate transactions. Ethereum too has miners. As already described in The Blockchain section miners are full nodes which perform mining operations on the blockchain. As full nodes participate to the transaction validation process but they can also create new blocks. Each miner generates a block containing all the transactions not yet confirmed, as already said the new block to add to the longest chain will be chosen through the execution of a consensus algorithm.

Miners compete to place their block on the blockchain resolving a mathematical problem (if the consensus is the proof-of-work type), when a node wins it receives a cryptocurrency reward. Every node wants to win, this incentives the correct behav-ior of each node and this enhances the system security. Peers which only interacts with blockchain without participating to consensus protocol are called light nodes. This type of node runs light client, wallets, to emit transactions but doesn’t keep a ledger copy and can’t validate transactions.

2.2.2 Smart Contracts

The most important feature introduced by blockchain 2.0 is the concept of smart contract.

A Smart Contract is a code fragment who lives in the blockchain at its own ad-dress. Each node retrieves the code from the blockchain and sends it to its EVM which execute it in the very same way for each node of the network.

Smart contracts can be seen as an autonomous entity who lives inside of the Ethereum execution environment and activates when receives messages or transactions. They

(14)

contain code functions and can interact with other contracts, make decisions, store data and send ether to others.

Contracts are defined by their creators, but their execution, and by extension the services they offer, is provided by the Ethereum network itself. They will exist and be executable as long as the whole network exists, and will only disappear if they were programmed to self destruct.[2.1]

Source codes are written in the Solidity Language and are compiled by the EVM in files called EVM bytecode. The bytecodes are transmitted to the blockchain with an unique address assigned when the code is compiled.

This contract address is necessary to interact with it and invoke its functions, this can be done using some primitives we’ll see later in details.

To upload a contract it is necessary to execute a transaction and in case of success the contract address will be returned.

2.2.3 Gas and Execution Costs

The fundamental unit of computation is "gas", each computational step cost 1 gas unit, the more complex is the code the more gas it will consume to execute. Not only is gas used to pay for computation steps, it is also used to pay for storage usage, the total fee for storage is proportional to the smallest multiple of 32 bytes used. Even the bandwidth used affects how much gas the contract consumes reducing the pos-sibility of a successful DOS attack. One important aspect of the way the Ethereum works is that every single operation executed by the network is simultaneously ef-fected by every full node.

However, computational steps on the Ethereum Virtual Machine are very expen-sive, for this reason Ethereum smart contracts are normally used for simple tasks, like verifying signatures and other cryptographic objects, rather than more complex uses, like file storage or email, which can put a strain on the network.

Imposing fees prevents users from distressing the network: Ethereum is a Turing complete language, this allows the execution of loops and makes Ethereum suscep-tible to the halting problem, a problem in which you cannot determine whether or not a program will run infinitely.

If there were no fees, a malicious actor could easily try to disrupt the network by executing an infinite loop within a transaction, without any repercussions. Thus, fees protect the network from deliberate attacks.

The maximum amount of gas a transaction can use and its price can be set when the transaction execution occurs; the product between the startgas and gasprice values indicates how much the user is able to spend for a given transaction. Furthermore, gasprice is used by miners to evaluate which transaction has the priority when the block is created.

The reason is higher gas price on a transaction will cost the sender more in terms of Ether but deliver a greater value to the miner and thus will more likely be selected for inclusion by more miners. Miners, in general, will choose to advertise the mini-mum gas price for which they will execute transactions and transactors will be free to define these prices in determining what gas price to offer.

(15)

Figure 2.2: From Private Key to Ethereum Address (Source)

Since there will be a (weighted) distribution of minimum acceptable gas prices, trans-actors will necessarily have a trade-off to make between lowering the gas price and maximizing the chance that their transaction will be mined in a timely manner. Another information included in the package is the ’value’ field, this parameter de-fines the amount of ether the sender wants to transfer to the recipient account. When a transaction is sent the gasprice provided must be lower than the account’s current balance or the execution will stop and system will rollback to the state before the call, same thing for the ’value’ parameter.

2.2.4 Accounts

Ethereum uses objects called accounts, each of them contains a 20-bytes address through which transactions and information exchange can be performed directly be-tween accounts. An account can be seen as a pseudonymous, anyone can generate an account by installing an Ethereum Wallet on his device, a Wallet is a software which permits a user to interact with the Ethereum Network, more precisely it holds all the key pairs (private and public) the user uses. There’s no limit on how many accounts someone can create and they are all managed using a Wallet. Keys represents the account itself and are fundamental to send and receive ethers: the private key is used to sign each transaction and the public one is used to define the Ethereum address where other accounts can send ethers.

An account is a data object: an entry in the blockchain ledger, identifiable by an address, containing data about the state of that account, such as its balance. In the blockchain environment an address is a public key belonging to a particular user; it’s how users access their accounts. In practice, the address is technically the hash of a public key, not the public key itself. More precisely an address is calculated as the last 160 bits of the SHA3–256( In Ethereum is called Keccak) hash of the public key (which is derived by the private key applying ECDSA).

Two types of account can be distinguished: • External Owned Accounts (EOA)

A EOA is controlled by the owner of a private key, which can be a human or even a server. This type of account can’t hold EVM code. Anyone who knows the private key can send messages from an EOA by creating and signing a transaction.

(16)

• Contract Accounts (CA)

A CA is not controlled by humans but by the code it contains. Every time the contract receives a message its code activates allowing it to read and write to internal storage, send messages and even create new contracts. The activation can be made by external owned accounts or by other contract accounts. An account contains the following fields:

• nonce: a counter to keep track of the number of transactions or contracts generated from an address. It is used to ensure each transaction is performed once;

• balance: a scalar equal to the number of Wei owned by the address;

• codeHash: optional, external owned accounts don’t hold any code, this field is used in contract accounts. This field contains the hash of the EVM code held by the account.

This code is the one being executed when the contract account receives a mes-sage call, it is immutable this means it cannot be changed after construction. All the code fragments are stored into the state database under their hash value to ensure a fast retrieval. The hash is calculated using keccak-265 (sha3) • data: account’s data storage, optional and empty by default.

2.2.5 Transactions

Any blockchain based system functioning revolves around the computational con-structs responsible of the state changes in the distributed ledger: transactions. In Ethereum transactions can be sent from EOAs or CAs, they basically change account balances within the EVM and therefore in the blockchain.

From a lower level point of view a transaction is a single signed instruction which goes in the blockchain and it is stored into each node in the network.

Once a transaction is admitted into the blockchain (and this means the next block contains that particular transaction) the only way to roll it back is a state fork, which requires all the nodes on the network to agree to revert that transaction. It is almost impossible something like this happens for real so this makes the model more secure. If for some reason the recipient can’t receive funds the sender balance won’t be decreased. It’s not possible to lose funds during a transaction.

Each transaction is serialized to be stored and transmitted in only one format. In Ethereum the RLP (Recursive Length Prefix) encoding/decoding algorithm is used to serialize data and possible to reconstruct them quickly. The purpose of RLP (Re-cursive Length Prefix) is to encode arbitrarily nested arrays of binary data, and RLP is the main encoding method used to serialize objects in Ethereum. The only pur-pose of RLP is to encode structure; encoding specific data types (eg. strings, floats) is left up to higher-order protocols; but positive RLP integers must be represented in big endian binary form with no leading zeroes (thus making the integer value zero be equivalent to the empty byte array). [2.3]

(For more detailed informations about the RLP algorithm: Appendix A)

When a transaction is created, and before the EVM sends it to the blockchain, the sender account must sign it with his private key. It is important to understand

(17)

that if a person has the private key of someone else he can easily impersonate the account owner. So it is fundamental to keep private keys in a safe place.

There are two types of transaction: those which result in message calls and those which result in the creation of new accounts with associated code (Contract Ac-counts) both types contains the following fields:

• nonce: a scalar value indicating the number of transactions sent by the sender. • gasprice: this value is equal to the number of Wei to be paid per unit of gas.

Indicates the fee the sender offers to pay to execute the contract’s code. • gaslimit: maximum amount of gas allowed for executing the transaction • to: this field contains the recipient address to which the transaction is sent.

When a transaction is done to upload a smart contract it is empty, in this case a contract address is returned so the new contract can be accessed by users. • value: number of Wei to transfer to destination, if any. It is possible to send

value even to contracts.

• v,r,s: these values contain the signature of the transaction, is used to determine the sender. Other informations contained into the transaction data package are: • blockHash: contains the hash of block the transaction resides inside the network • blockNumber: indicates the index of the block containing the transaction • from: the 20-bytes hexadecimal address of the sender

• hash:transaction hash value

• input stuff the sender wants to attach to the transaction package • transactionIndex: the transaction location inside the block

• init: used into the contract creation transactions, it is an unlimited size byte array containing the EVM-code needed for the account initialization. This EVM-code fragment returns the body, a second fragment of code which exe-cutes each time the contract account receives a message call, init code instead is executed only once, during the initialization phase.

• data: a message call transaction contains an unlimited byte array too, this specifies the input data needed to execute the body code fragment.

The gaslimit parameter in practice represents the maximum number of operations (or computational steps) the transaction execution can perform. The presence of the gaslimit field is needed in order to avoid an excess of resources consumption. Infinite loops are prevented because these value sets a limit to how many computation steps an execution can use so when the maximum amount of gas is consumed the execution stops.

A transaction defines a state transition into the blockchain, this transition is made in few steps, first of all a validity check is made performing some tests:

1. The transaction is correctly serialized in the RLP(Recursive Lenght Prefix) format

(18)

2. The transaction signature is valid

3. The transaction nonce is valid (transaction nonce has to be equal to the sender’s current nonce)

4. The sender account balance contains enough funds to pay gas and funds transfer described into the transaction fields.

Once the transaction is validated the execution begins with a first change of the state: the nonce of the account of the sender is incremented by one and the balance is decreased by a part of the upfront cost, calculated as

v0= TgTp+ Tv (2.1)

where:

• Tg is the gasLimit value,

• Tp is the gasPrice,

• Tv is the amount of Wei to transfer.

The amount of gas avalaible for the computation is defined as

g = Tg g0 (2.2)

where g0 is the intrinsic gas, the amount of gas a transaction requires to be paid

before to be executed. This value depends on the sum of

• a quantity of gas depending on the number of bytes contained into a transac-tion, the cost expressed in gas is 4 for every zero byte and 68 for every non-zero byte of data or code for a transaction.

• the amount of gas that has to be paid to create a contract. • the amount of gas paid for every transaction.

According to the Ethereum Yellow Paper’s fee schedule ([2.4]) the execution price of a create operation is 32000 in terms of gas units. Each transaction has a cost of 21000 gas units as defined in the documentation. The computation, of any type, contract creation or message call, results in a deterministic change of state which is never invalid. There can be no invalid transactions from this point because the validity test are already being passed. If a transaction is successfully executed a receipt is returned containing certain information concerning its execution and the remaining gas, if any, is returned to the sender’s account.

The transaction receipt contains a set of four items like

• the total gas used in the block in which the transaction is included in the moment after the transaction is executed,

• the set of logs created during the transaction execution, • a filter made from the information given by those logs and • the status code of the transaction.

(19)

The receipt is serialized using a RLP method, the same EVM uses to serialize the transaction before uploading them into the blockchain.

Transactions are not secret, they are all visible on the blockchain, there are no names but amounts and addresses are accessible to anyone who scans the network. By using any of the scanners available online we can see the information contained in every transaction ever made. Figure 2.3 shows an example from etherscan.io:

Figure 2.3: Transaction Example

The figure reports the public informations about a single transaction:

• TxHash: Contains the 256 bit hash of the whole transaction object. It is the ID used to track the transaction in the blockchain.

• TxReceipt Status: Indicates if the transaction execution was successful • Block Height: the block number in which the transaction was included. Also

how many block confirmations the block has are reported.

• TimeStamp: the transaction timestamp indicates the time the transaction en-tered the blockchain

• From: The sender address • To: The receiver address

(20)

• Value: How much Ether was sent

• Gas Limit: The maximum amount of gas the sender is willing to pay • Gas Used By Txn: The actual amount of gas the transaction used • Gas Price: The current price in gwei for each gas unit.

• Actual Tx Cost/Fee: The execution cost expressed in Ether. It is the product of GasUsed and GasPrice.

• Cumulative Gas Used: The total amount of gas used when the transaction was executed on the block.

• Nonce: Represents the number of transactions the sender has made on the network.

• Input Data: Additional data included in the transaction Messages

In addition to transactions there are messages. Messages are data objects passed across the network too but they are sent only between Smart Contracts and do not directly result in any changes into the blockchain history. They are not serialized and exist only inside the EVM. Messages are usually sent to trigger actions in the recipient smart contract and this may result in transactions and then in changes to the ledger.

Two contract can communicate between each other using messages messages. Messages are similar to transaction but they are emitted by contract instead of users, a message is sent when a contract is running in the EVM and the opcode CALL (or DELEGATECALL) is executed. Once received, the message triggers the recipient contract account to execute some of its code: this is the mechanism by which we obtain an interaction between two smart contracts.

2.2.6 The Ethereum Virtual Machine (EVM)

Let’s see now how the Ethereum virtual machine works in a more detailed way. The EVM is a stack-based machine with shared state, this means it behaves like a giant data object but is composed by a network of autonomous discrete machines in constant communication with each other. In this way every component has the same internal state of the others. This internal state represents the EVM global state which is made by account balances and all the transactions made to make that balance having its value in the present.

The EVM works on words of 256 bits, this was chosen to ease the Keccak-256 hash scheme and the elliptic-curve computations.

As already said the EVM is capable of execute arbitrary programs written in the Solidity language: these program are fully deterministic, this means that given a certain input the execution will always produce the output in the same way. The determinism of solidity programs makes possible for all the nodes in the network to execute the code in the exactly same way and obtain the same output for that particular input making the EVM a state machine.

(21)

When a user updates a smart contract through his node it is included into the latest block and broad-casted in the network where it is stored on every node. Each node has the job of running the code as a part of block processing protocol. this is done independently making the whole system highly parallelized but also highly redundant and this improves security.

The EVM runs its own language, the EVM bytecode, which is the one into the smart contracts compile. Th high level language in which the smart contract is writ-ten is compiled in bytecode and then uploaded into the Ethereum blockchain using a node or a simple client.

In a secure network private communications are enciphered using asymmetric cryp-tography so that even if they are intercepted by attackers informations are kept unreadable without the correct key. In blockchain the same principle is applied: cryptography ensures that messages, in the form of EVM transaction requests, are coming from the actual address holder and not an interposed third entity trying to stole funds or informations. Public key cryptographic communications don’t require a secure channel between parties. This is essential in Bitcoin and Ethereum, because any computer running the protocol can join the network, without any filter.

Asymmetric cryptography is an efficient way to send messages back and forth over a network where sender and recipient do not trust the channel they are using to communicate. In the EVM environment those messages are signed transactions sent through the network in order to change the state of the distributed ledger. Within EVM public key cryptography is also used to generate and validate Ethereum ad-dresses and to digitally sing each transaction emitted by that address. At a high level, it can be said that Ethereum uses encryption to validate and verify that all the changes made to account balances in the EVM are legitimate and that no account balance has been increased (or decreased) erroneously.

The computational complexity involved in encrypting data makes it useful only for small data objects, like the alphanumeric string that becomes your private key. This is why encryption is used almost only for validation.

However, if you hand over your private keys to someone else, that person can access the EVM and pull your money out without you ever knowing. As far as the network is concerned, anyone with your private key is you because the EVM is a global ma-chine, it has no way of knowing which node you’ll create a transaction from.

As already seen in the previous section before uploading a signed transaction in the blockchain EVM runs the validity tests and then serializes it using RLP.

(22)

Development in Blockchain

(23)

Smart Contracts Development

In this part we’ll introduce the basic instruments a developer needs to know to approach the Ethereum environment for the first time. We will move our first steps in the language used to write smart contracts, Solidity, and then we will proceed with some tools that can be used to design a decentralized application.

3.1 Write a Smart Contract: The Solidity Language

In this section we’ll introduce Solidity, a contract-oriented language for implementing smart contracts designed to target the Ethereum Virtual Machine. Solidity is stati-cally typed, supports inheritance, libraries and user-defined types; it is the most used as well as the most robust programming language for smart contracts development.

3.1.1 Introduction to Smart Contracts

A smart contract in Solidity can be seen as something similar to a class in another object-oriented language; it is a collection of code (its functions) and data (its state) that resides on the Ethereum blockchain located at a specific address.

In general, a contract can include State Variables, Functions, Modifiers, Events, Struct types and Enum Types, we’ll see each of them in details, for now here’s a summary of what these constructs are:

• State variables are values which are stored in contract storage in a permanent way.

• Functions are executable fragments of code inside the contract, can be invoked internally or externally of the contract which included them with different levels of visibility.

• Modifier are functions too which can be applied to other function to define execution requirements.

• Events are interfaced used to log smart contract activities from the EVM. • Structs are a tool to create complex user-defined data types that can group

different types of variables.

• Enums can be use to create new types with a finite set of values.

(24)

Furthermore, exactly like classes, contracts can inherit from other contracts.

3.1.2 State Variables

There are various types of state variable some of them are are expressed as: uint data; int signeddata; ufixed double; fixed signeddouble; bool result; address owner;

In this fragment we have two integers, two fixed point numbers, a boolean and an address respectively. The presence of the u prefix indicates the value is an unsigned integer or fixed point number.

In Solidity numbers can be expressed using an arbitrary amount of bits, integers can be expressed from 8 up to 256 bits in steps of 8, it is possible to specify the size using the keywords uint8 to uint256 and int8 to int256 respectively for signed and unsigned. uint and int are aliases for uint256 and int256.

Integers can be used inside complex expressions as parameters of comparison op-erators (<=,<,==,!=,>=,>), obtaining a boolean in return, bit opop-erators like &,| or ˆ, classic arithmetic operators for sum (+),subtraction (-), multiplication (*) and division (/) and unary operations left and right shift (« and »), unary - and unary +, remainder (%) and exponentiation (**). The result of a shift has the type of the left operand, shifting by a negative value throws a runtime exception; same thing for division by zero and modulus with zero.

Signed and unsigned fixed point numbers are identified by keywords fixed and ufixed respectively. They can be of different sizes, in this case two parameters are needed: ufixedMxN and fixedMxN where M is the number of bits (from 8 up to 256 bits divisible by 8) used by the type and N represents the number of decimal points we can use, this value goes from 0 to 80. Keywords fixed and ufixed are aliases for ufixed128x19 and fixed128x19. Comparison and arithmetic operators are the same as for integers except for exponentiation and shift which are not available for fixed point numbers.

Booleans have two possible constant values: true and false, they are considered as value types because they are passed by value just like numbers, same thing for address type, a particular variable type as we will see later.

3.1.3 Our first tiny contract

Let’s see now how a smart contract is structured.

Same as classes a smart contract needs a constructor, it is a function with the same name as the contract.

(25)

creates the contract instance.

Using the constructor is very helpful to customize the instance of the contract when we deploy it.

Here is an example of a simple contract. pragma solidity ^0.4.18;

contract tiny_contract { uint counter;

function tiny_contract (uint number, uint p){ counter = number * p;

} }

The first line of a Solidity smart contract is pragma solidity ^0.4.18 is needed to tell the compiler to use the solidity version 0.4.18, so pragma is a way to give instruction to the compiler before the execution of the code.

The line uint counter declares a state variable of type uint (unsigned integer of 256 bits). We can see the state variables as data stored on a database that can be managed by the owning contract. This contract doesn’t do anything more than setting the counter value, we’ll see later a more complicated example.

3.1.4 Visibility in Solidity

It is possible to define the visibility level for both state variables and functions, this can be done using the keywords external, public, internal and private. Lets see their effects:

• external: functions declared as external represent the contract interface, they can be called by other contracts using transactions, this type of functions can’t be directly invoked inside the contract.

Example. If we have a function foo() declared as external, calling just foo() inside the contract will not work, using instead the form this.foo() will do the job. State variables can’t be declared as external in Solidity.

• public: A function is defined as public by default, in this case it can be invoked both internally and externally the smart contract in the same way. As regards variables a getter function is automatically created when the contract is compiled so it can be retrieved from anyone who invokes the getter function. • internal: Functions and state variables defined as internal acts only inside the contract, this means that they can’t be invoked from the outside, only the contract in which they are defined can invoke those function or retrieve the internal variable’s value. In case of inheritance the ’child’ contracts can access the internal values and functions of the father. By default state variables are defined as internal.

• private: Anything declared as private is only accessible to the contract in which is defined, inherited contracts can’t access something declared as private on the father.

(26)

Note: anything defined inside a contract is visible, this means that declaring something as private prevent interactions or any type of access from other contracts or data structures but doesn’t hide its existence from the rest of the blockchain. So if a variable is declared as private in a contract a user can see it but can’t retrieve or rewrite its value.

3.1.5 Functions

As we seen in the visibility paragraph, internal functions can be executed only inside the context of the current contract, instead externals consist of an address and a function signature which can be passed and returned from external function calls. A function is declared as follows:

function (<parameter types>) {internal|external} [pure|constant|view|payable]

returns(<return types>){ <body> }

Functions are public by default so the keyword public can be omitted.

The returns keyword followed by a list of parameters indicates there are output values the function has to return and what is their type. The returns field can-not be empty, this means that if the function doesn’t return anything the part returns (<return types>) has to be removed.

The names of output parameters can be omitted, the output values can be spec-ified using the return keyword inside the function body, multiple values can be returned, obviously their number has to be the same as the number of output pa-rameters. Input and output parameters can be used as expressions in the function body, they are also usable as left side of assignments

There are different ways to access a function inside the current contract it can be called using its name or using the dot notation this.function_name. The first way result in an internal function, the latter in an external one, please note it’s not possible to use this inside a constructor because the contract has not been created yet.

In the following example we will see how functions can be invoked by contracts and in which way visibility modifiers affect the behavior of execution.

pragma solidity ^0.4.18; contract tiny_contract { uint private counter;

function tiny_contract (uint number, uint p){ counter = number * p;

}

function f(uint a) private returns(uint b){ return a + 1;

}

function setValue(uint a){ counter = a;

}

function getValue() constant returns(uint){ return counter;

(27)

function computeValue(uint a, uint b) internal returns(uint){ return a+b; } } contract D { function readData(){

tiny_contract c = new tiny_contract(); uint local = c.f(7); local = c.getValue(); local = c.computeValue(3, 5); } } contract E is tiny_contract{ function g(){

tiny_contract c = new tiny_contract(); uint val = computeValue(3, 5);

} }

Lets see in detail each of these contracts.

In Contract tiny_contract we have a private state variable and four functions with different visibility settings.

As we can see contract D tries to call the f() function declared in c and then we have our first error due to the private visibility setting of the f() function. Same thing it happens when a c.computeValue call occurs, in this case computeValue is an internal function so it’s not accessible by an external contract like D.

The last contract E is inherited by tiny_contract, E calls the function computeValue without errors, this function is declared inside tiny_contract, invoking f() would generate an exception instead.

3.1.6 Remarkable Data Types: Address Type

In Ethereum blockchain actors (EAO or CA) are identified by their address. Ad-dress is a data type which holds a 20 byte value, the size of an Ethereum adAd-dress, and it is needed to perform almost every operation into the blockchain. In order to retrieve contracts and send transactions and messages the application has to know the address value of sender and recipient.

This type have members which are accessible using the dot notation, those members can be properties or functions. When a function is called we can access to the address which call it using msg.sender, this information can be very useful when designing the contract behavior.

Something we can do is save the contract’s owner address into the contract storage so we can secure the code allowing the execution of some operation only to the owner. Lets update our example:

pragma solidity ^0.4.18; contract tiny_contract{

(28)

uint counter; address owner;

function tiny_contract(uint number, uint p){ counter = number * p;

owner = msg.sender; }

function getValue() constant returns(uint){ return counter;

}

function setValue(uint new_value) public { if (owner == msg.sender)

counter = new_value; }

}

As you can see we added a new line inside the constructor function, this saves the creator address into the owner state variable. There’s also a new function setValue which changes the counter value, the security check compares the address saved in the owner variable and the msg.sender value, if they match the operation counter = new_value will be performed, if they don’t nothing will be done. If there wasn’t a security check anyone could change the counter’s value but all the values would be stored on the history of the blockchain.

Given an address type variable we can access to a series of properties and functions as you can see in the following list:

• Balance and Transfer

Using the balance property we can read the current amount of ether owned by the account located by address. Transfer is a function used to send ether (expressed in Wei) to an address, if the execution fails (due to lack of balance or gas for example) the Ether transfer reverts and the contract execution stops. Lets see a simple example:

address rec = 0x12345; address myAddress = this;

if(rec.balance <10 && myAddress.balance >= 10) rec.transfer(10);

In the first line there is an address variable containing the recipient address; the second one save into a variable the owner address (in Solidity Smart Contracts the keyword this equals to the owner address). The last line of this example checks if the accounts respect some conditions (sender has to own at least 10 Wei and recipient has to have less than 10 Wei), if the if block returns true then the argument of transfer will be send to the recipient address.

• Send

Send function does the same work of transfer but in a low-level way. If the execution of send fails it returns false but the execution will not stop or emit an exception. If you want to use send instead of transfer it is strongly recommended to do that checking the value the send returns and in case of false implement a code that handles the recipient withdrawal.

(29)

• Call

The function call offers a way to interact with smart contracts passing them any sort of arguments. Call returns a boolean which indicates the invoked function terminated or caused an EVM exception. It is also possible to specify the amount of gas we want to use, this can be done as indicated below: address acontract = 0x15frf789irdt890adr56e0;

acontract.call.gas(800)("save",42);

In this case we called the save function defined inside the contract which re-sides at the address acontract and we are passing the "randomvalue" string as parameter of the function. It is possible to send Ethers using the call value, we can do that in the same way we supply gas:

acontract.call.gas(800).value(1 ether)("sendsomething",42);

In this case we are sending 1 ether to the contract, suppling 100k gas units for the sendsomething execution.

3.1.7 Remarkable Data Types: Mappings

Mapping types are an useful tool to manage multiple variables of the same type, can be seen as hash tables which are organizes such that every possible key exists and is mapped to a value byte-represented by all zeros. The key data is not actually stored in a mapping, only its keccak-256 (Solidity alias for sha3) hash used to query the values.

Mappings are only permitted as variables or as storage reference type inside internal functions. A mapping variable is declared as follows:

mapping(_keytype =>_valuetype)

_keytype can be any type except for a mapping. _valuetype instead can be any type including mapping. It is possible to declare mapping variables as public, in this case a getter is created and _keytype becomes a required parameter for the getter which will return _valuetype. In the following example we add to our tiny contract a function to set the sender balance using a mapping we retrieve the balance value of the address contained in msg.sender and than we update it using newbalance value. pragma solidity ^0.4.18;

contract tiny_contract{ uint counter;

address owner;

mapping (address => uint) public balances; function tiny_contract(uint number, uint p){

counter = number * p; owner = msg.sender; }

function getValue() constant returns(uint){ return counter;

(30)

}

function setValue(uint new_value) public { if (owner == msg.sender)

counter = new_value; }

function setBalance(uint newbalance) public { balances[msg.sender]=newbalance;

} }

3.1.8 Modifiers in Solidity

Modifiers are functions that can be applied to other functions. they can be used to check if some requisites are met before even starting the function execution.

In the previous example we used the security check: if(owner == msg.sender){

<do something> }

If, for example, we use often this kind of check we could think of define a modifier which does that:

modifier isOwner(){

require(msg.sender == owner); _;

}

Using the modifier our function becomes something like this: function setValue(uint new_value) public isOwner{

counter = new_value; }

Lets see in details our brand new modifier: first of all the require() call, this function evaluates the condition passed as argument and throws an exception if the condition is not met. This exception will stop the execution of our smart contract preventing not allowed operation. The _; keyword is a compiler directive which tells the compiler to replace _ by the body of the function so if the requirement is met whatever operation the calling function includes will be performed. A modifier is a function indeed so it can accept parameters and more than one modifier can be applied to a function.

A predefined modifier is payable, if a function is declared with this modifier it means the function can accept ether transfers when it’s called, the amount of sent ether will be stored in the value property of msg which can be accessed with the dot notation: msg.value. If the .value() option is used towards a not-payable function an exception will be thrown.

3.1.9 Events

Events are an important tool a developer can use to monitor the smart contract exe-cution behavior. Every function can emit events an this can be used to call javascript

(31)

callback in the user interface which are listening for those events.

Events are members of contract and when they are called their arguments are stored in the transaction’s log. Being part of a transaction these logs are associated to the address of the contract and written into the blockchain. Log and event data is not accessible from within contracts not event the one that created them. We can now modify our example using a event that logs when someone tries to change the value of the counter state variable.

pragma solidity ^0.4.18; contract tiny_contract {

uint counter; address owner;

mapping (address => uint) public balances; event CounterValue(uint value, address _from); function tiny_contract(uint number, uint p){

counter = number * p; owner = msg.sender; }

function getValue() constant returns(uint){ return counter;

}

function setValue(uint new_value) public{ if(owner == msg.sender)

counter = new_value;

CounterValue(counter,msg.sender); }

function setBalance(uint newbalance) public{ balances[msg.sender]=newbalance;

} }

When the setValue function is invoked the event CounterValue will be emitted, in this case it will log the changed value of counter if the owner is calling and the old value if the caller isn’t the owner.

3.1.10 Inheritance

As already said contracts are very similar to classes, another point in common with them is the possibility of inherit a contract from another.

Solidity supports multiple inheritance, when a contract inherits from more than a contract only a single contract is created on the blockchain, the code from all the father contracts will be copied into the new child contract.

The syntax is pretty simple:

contract Child is Father1, Father2 { ... }

Child contract will obtain access to all of the internal functions defined within the Father, as already said on Visibility section private function still will not be

(32)

accessi-ble.

Functions inside the child can be overridden by another function with the same name and the same input arguments of the father’s function. If the overriding func-tion has a different number or type of output arguments an error will be returned. To call the original function instead of the overriding one the dot notation will be used.

Another way to call a function defined inside a superior inheritance level is using the keyword super in the dot notation. In this case the child will call a function defined on the next contract in the final inheritance graph so the actual function that is called is not known in the context of the class where it is used.

For example, supposing we have 4 contracts A,B,C,D involved in an inheritance scheme like this:

contract A{ address owner;

function owned() public{ owner = msg.sender; }

}

contract B is A {

function kill() public{ if(msg.sender == owner)

selfdestruct(owner); }

}

contract C is B{

function kill () public{ super.kill();

} }

contract D is B{

function kill () public{ super.kill();

} }

contract E is D,C{}

Contract B inherits from A so it has the access to the state variable owner. Contracts C and D are children of the contract B, they both call the function kill() but they actually calls two different definitions of it: the final contracts order graph is as follows: E, C,D ,B,A this means that using the super the contract C is invoking D.kill(), whereas D is calling B.kill().

(33)

3.1.11 Handling errors

Solidity offers different ways to handle errors, it can be done by calling some func-tions: Assert, Require and Revert.

In general Solidity uses state-reverting exceptions to handle errors so if an error occurs all the changes made to the state in the current call will be undone.

The functions Assert and Require are used before starting the real execution of a function, they check if some condition are met and if they aren’t an exception is thrown. In detail the Assert should be used to test for internal errors; Require instead should be used to check if some needed conditions are valid, such as inputs, state variables and return values in case of externally invoked functions.

The Revert is used to trigger exceptions in a different way of assert and require. This kind of function can be used to detain an error and revert the current call to its previous state during the execution of a function. Require is inserted at the beginning of the code unit, Revert instead can be placed anywhere a developers wants to check the correct state of the execution.

Internally if a require fails Solidity performs a revert operation and executes an invalid operation to throw an assert exception. In both cases this makes EVM to revert all the changes made to the state. Reverting is made because there is no other safe way to continue the execution if an error occurs and the system has to ensure the atomicity of transactions.

3.1.12 Interacting Smart Contracts in Solidity

We’ll see now how the interaction between smart contracts works. Contracts creating other Contracts

Firstly, a contract can create another contract, it can do that using the new keyword, in this case the new contract’s full code has to be known to prevent recursive creation dependencies which are not allowed in solidity.

It is possible to send Ethers to the contract being created using the value() member of new, it’s not possible to pass the amount of gas instead. Here’s an example:

contract tiny_contract { uint counter;

address owner;

mapping (address => uint) public balances; event CounterValue(uint value, address _from);

function tiny_contract (uint number, uint p) public payable { counter = number * p;

owner = msg.sender; }

function getValue() constant returns(uint){ return counter;

}

function setValue(uint new_value) public{ if(owner == msg.sender)

(34)

counter = new_value;

CounterValue(counter,msg.sender); }

function setBalance(uint newbalance) public{ balances[msg.sender]=newbalance; } } contract C { tiny_contract T; function C (){ T = new tiny_contract(1,2); }

function create_tiny(uint p1, uint p2){

tiny_contract T = new tiny_contract(p2,p3); }

function create_ and_send(uint p1, uint p2,uint p3){

tiny_contract T = (new tiny_contract).value(p1)(p2,p3); }

}

In this example we can see three possible uses of new: in the first one the contract’s creation function is included within the constructor of C contract, the second case is similar to the third, a new contract is created by invoking a C’s function. The only difference in the third creation is that we are sending funds to the new tiny_contract. In all the cases if creation fails an exception is thrown.

External Function Calls

As already said it is possible to call a function internally or externally: functions defined inside the current contract can be called directly using their names. Calls like these are translated into simple jumps inside the EVM, the effect is that we have not the current memory cleaned because we are not changing the execution context. Obviously only functions in the same contract can be called internally.

If a function is called using the dot notation this.function() or

contract_instance.function() the call is still valid but the function will be called externally, this type of calling translates in the EVM as a message call instead of a jump.

If there are two contracts we want to communicate with each other then functions need to be called externally. To perform an external call all function arguments have to be copied to memory and the contract address instance we are interacting with has to be known. It is also possible to specify a certain amount of ethers to send and the gas value using .value() and .gas() respectively.

Interacting Contracts Solidity Code pragma solidity ^0.4.10;

(35)

address public owner;

event Funds_Received(uint value,address _from, uint timestamp); function() public payable{

Funds_Received(msg.value,msg.sender,now); }

function tiny_father() public payable{ owner = msg.sender;

}

function receiveFunds() public payable{

Funds_Received(msg.value, msg.sender,now); }

function getBalance() public returns(uint){ return this.balance;

} }

contract tiny_son{

address public owner; tiny_father tf;

event Funds_Received(uint value,address _from, uint timestamp); function() public payable{

Funds_Received(msg.value,msg.sender,now); }

function tiny_son(address father_address)public payable{ owner = msg.sender;

tf= tiny_father(father_address); }

function sendFunds(uint amount) public payable{ tf.receiveFunds.value(amount).gas(10000)(); }

function getValues() public returns (uint,uint){ uint father_balance = tf.getBalance();

return (this.balance,father_balance); }

}

In this example we have 2 contracts, tiny_father and tiny_son. We assume we already know the address of an instance of tiny_father and we use it to retrieve an already existing contract, this means no constructor is executed. Doing that we can say we have a direct link to tiny_father through the state variable tf. Now that we have it, it is possible to call tiny_father’s function externally using the dot notation. The tiny_son calls the tf’s function, in this case can send to the tiny_father some funds and check the amount of its donations and the tiny_father current balance.

An exception will be thrown if called the contract doesn’t exists or if the called contracts execution fails (throwing itself an exception) or goes out of gas.

Obviously any interaction between contract has to be made carefully. The code of both contracts has to be known in advance because the implementation of the contract can be completely arbitrary. This means that using its functions the called

(36)

contract can change all the state variables of the calling contract as it wishes. For this reason developers have to take any proper security measure to prevent any sort of vulnerability.

It is also possible for a contract to create a new contract itself using the new, changing the tiny_son constructor to perform this operation we would obtain some-thing like this:

function tiny_son(address father_address)public payable{ owner = msg.sender;

tf= new tiny_father(); }

3.1.13 The Death of a Contract

As the traditional class objects also the smart contracts can be destroyed, when this happens it will not be possible to interact with them anymore. We can do such a thing using the function selfdestruct(address) (or its alias suicide(address)). It is important to restrict the access to this kind of function so the contract couldn’t be destroyed by anyone. We can do that using the same check we saw before. The address type parameter is needed with the purpose of sending the remaining funds stored in the contract to that address.

contract tiny_contract{ address owner; function tiny_contract(){ owner = msg.sender; } function kill(){ if(owner == msg.sender) selfdestruct(owner); } }

When the contract is destroyed funds will go into the owner’s wallet and it will not be possible to interact with that contract anymore.

A way to reset smart contract’s variables is the delete operator. Delete behaves like an assignment: it assigns the initial value for the type to the variable involved. For example delete a executes a = 0 if a is an integer, if used on arrays it assigns a dynamic array of length zero or a static array of the same length with all elements resettled. If applied to struct it assigns a struct with all members resettled. Delete doesn’t work on mappings so deleting a struct will reset all the members that are not mappings, note that keys and mapped values can be deleted too.

References

1 Introducing Ethereum and Solidity: Foundations of Cryptocurrency and Blockchain Programming for Beginners Chris Dannen Apress 2017

2 Solidity Online Documentation 3 Solidity Tutorials Gitbook

Riferimenti

Documenti correlati

Gestisci tutti i sensori sempre con l’App Homcloud come se fossero prodotti

Attraverso Smart Contract ognuno può creare e scambiare il proprio token.. Bitcoin e BlockChain,

One compound can have a higher affinity for the stationary phase with a particular mobile phase and will present a higher retention time than another metabolite with a lower

Grazie alla Dashboard personalizzabile, alle funzionalità di Business Intelligence Notarile e di Controllo di Gestione, Notaionext permette allo studio notarile di ottenere

Feline viral plaques are uncommon skin lesions clinically characterized by multiple, often pigmented, and slightly raised lesions1. Numerous reports suggest that papillomaviruses

• The member objects of your new class are typically private, making them inaccessible to the client programmers who are using the class. • This allows you to change those

Lipari (Scuola Superiore Sant’Anna) OOSD September 23, 2010 4 / 37G. Example

In the European lifelong guidance strategy, Career Management Skills (CMS) is the term used to describe the skills, attributes, attitudes and knowledge that individuals