List of Figures

Chapter 1. A first look at decentralized applications

Figure 1.1. A centralized application is strongly associated with the single entity controlling it. Consequently, users decide whether to access it depending on their trust of the entity.

Figure 1.2. Comparison of a centralized voting application with a decentralized one. One institution owns all servers of a centralized application. A decentralized voting application runs simultaneously on multiple nodes of a network that different entities own.

Figure 1.3. A decentralized voting application is exposed to the voter as a web application, which contains both HTML and JavaScript and is downloaded from a conventional web server. The web application, which doesn’t contain any server-side scripts (otherwise, it would be partially centralized), is generally configured to communicate directly with a specific node of the network.

Figure 1.4. A peer-to-peer (P2P) network is made of nodes that communicate directly with each other without the coordination of a master node.

Figure 1.5. Each node of the Ethereum network hosts a blockchain database and a node client capable of executing application code stored in the blockchain. Nodes communicate through the Wire protocol and expose the same interface but can be implemented in different languages.

Figure 1.6. The Ethereum network includes two main types of nodes. Full nodes process transactions passively and can read, but can’t write on, the blockchain. Mining nodes process transactions actively: they validate the correctness of transactions as full nodes do, but they also assemble transactions into new blocks that are appended onto the blockchain.

Figure 1.7. The entire static view of a decentralized voting application, including client and server sides

Figure 1.8. The lifecycle of a voting transaction. A voting transaction is created when a voter browser invokes the castVote() function on the Voting smart contract on a local node of the Ethereum network. This is then validated and propagated throughout the network until it’s included on a new blockchain block by a mining node. The new block is propagated throughout the network, and then it finally gets back to the local node.

Figure 1.9. Typical international trade involving many parties: banks, commercial intermediaries, shipping companies, insurers, customs officials, and so on

Figure 1.10. Screenshot of the Remix opening screen, with the code on the left and the code execution panels on the right. I’ve hidden the file explorer by clicking the double arrow toggle at the top left.

Figure 1.11. The Auto Compile option in the Compile tab makes sure the code entered in the editor is recompiled at every change.

Figure 1.12. Once the code has been compiled correctly, the Run tab will show two buttons: Deploy and At Address. You can instantiate the contract by clicking Deploy.

Figure 1.13. After deploying the contract, the Deployed Contracts panel appears, containing a drop-down with a SimpleCoin option; click it, and you’ll see the contract operations.

Figure 1.14. SimpleCoin operations buttons: CoinBalance and Transfer. CoinBalance is a getter of the coinBalance state variable and is a read-only operation. Transfer allows you to transfer the specified number of tokens to the indicated address.

Chapter 2. Understanding the blockchain

Figure 2.1. An Ethereum node includes an Ethereum client and a blockchain database. The client contains a client process, an Ethereum Virtual Machine, a memory pool, and a JSON-RPC API exposing the functionality of the node externally. There are two types of nodes: full nodes and mining nodes.

Figure 2.2. The lifecycle of a transaction. A voting transaction is created when a function is invoked on a smart contract on a chosen Ethereum node through the JSON-RPC interface. The node places the transaction in the memory pool and executes it on the EVM for validation. If the validation is successful, the transaction is broadcast to peer nodes until it reaches a mining node; otherwise, it dies out.

Figure 2.3. A mining node receives the transaction from a peer node and places it in its memory pool. The node later picks it and executes it on the EVM, among other transactions, to place it on a new block. If the block is appended on the blockchain, the transaction is removed from the memory pool and the block is broadcast to peer nodes.

Figure 2.4. The full node’s process, from when it receives the new block to when it processes all its transactions on the EVM for validation, then, if validation is successful, removes the related transactions from the memory pool and propagates the block further into the network

Figure 2.5. A developer writes the voting smart contract in the Solidity language, then compiles it into EVM bytecode and inserts it into a contract deployment transaction. This is pushed to the local Ethereum node and propagated throughout the network. It’s then mined and appended to the blockchain.

Figure 2.6. You’ll progress from writing smart contracts in Solidity, to interacting with smart contracts remotely through the Web3.js Java-Script library, to building a web UI in HTML and JavaScript.

Figure 2.7. A private key is generated with a random number generator. It’s then fed to an algorithm that generates a public key.

Figure 2.8. To understand the purpose of private and public keys, you can think of the public key as your postal address, known by everybody, and the private key as the key to your mailbox, only owned by you.

Figure 2.9. You can use a private key to decrypt a document that has been encrypted with the related public key, as you can see in the top diagram. As shown in the bottom diagram, a private key also allows someone to sign a document digitally to prove provenance. The generated digital signature can then be verified against the document and the related public key.

Figure 2.10. A hash function produces a hash of a fixed size (64 bits in this example) given an input of any size.

Figure 2.11. A physical check forged by reusing the original signature and altering the recipient and amount

Figure 2.12. An e-check can be secured with a digital signature generated with the private key associated with the sending bank account and the details of the check. It can be verified by checking the digital signature against the public key associated with the sender bank account and the check details.

Figure 2.13. An attempt at forging an e-check secured by a digital signature is unsuccessful because the new original digital signature doesn’t match the altered check details.

Figure 2.14. A blockchain is a sequence of blocks, each containing a sequence number, a timestamp, and a list of transactions, each individually digitally signed. Each block also references the cryptographic hash of the previous block.

Figure 2.15. An attempt at altering the contents of a block, for example its transactions, won’t be successful: the new hash generated from the altered block details won’t match the original block’s hash already directly referenced in the next block and indirectly referenced in the subsequent blocks.

Figure 2.16. Proof of Work: generation of an unsuccessful and a successful block hash

Figure 2.17. The structure of a block, including a header containing metadata, such as the block number, timestamp, previous block hash, and Merkle root of the transactions Merkle tree, and a body containing the transactions collection

Figure 2.18. A Merkle tree. Individual transactions are located at the bottom; the tree’s leaves are the hashes of the individual transactions; and the next row up is made of the hashes of the tree’s leaves. The top row, which is the hash of the hashes below, ends the tree: this is the Merkle root.

Figure 2.19. An Ethereum improved block header. The header of a block of the Ethereum blockchain contains the root of the transactions Merkle- Patricia trie, which is a more compact and efficient structure than a Merkle tree. In addition, it contains the Merkle-Patricia root of receipts (which are the transactions effects) and the blockchain state.

Figure 2.20. Detailed block processing in an Ethereum node. When a full node receives a new block, it separates the header and the body. It then creates a local transactions trie and a local receipts trie and updates the existing state trie. The new and updated tries are then committed in the respective stores.

Chapter 3. The Ethereum platform

Figure 3.1. Choosing the test Ropsten network from the Develop > Network > Ropsten menu option or through the Alt+Ctrl+2 shortcut

Figure 3.2. You can see synchronization details, including the name of the network and the latest block number, at the top of the screen.

Figure 3.3. Accounts overview screen. You can create an account by clicking Add Account.

Figure 3.4. Account details shown on the Accounts Overview screen after their creation

Figure 3.5. Account balances after using the faucet facility

Figure 3.6. Password entry screen for moving Ether between accounts. You’re required to enter the password of the sending account when transferring Ether with the Ethereum wallet, to digitally sign the transaction and consequently prove it’s genuinely the account owner who’s sending the Ether.

Figure 3.7. Summary transaction information from the Transactions panel of the Accounts Overview screen

Figure 3.8. An Ethereum contract receives a transaction message from a user account. Its logic is executed on the Ethereum Virtual Machine (EVM); then the successful miner calculates the cost for the computational and network resources used, in a unit called gas, and charges the user account in Ether.

Figure 3.9. The Ether lifecycle. Ether is minted by miner nodes into miner user accounts. Then it’s transferred to EOAs (also known as user accounts). From there, it can be stored on various wallets. Ultimately, it can be converted to real currency, such as USD, EUR, YEN, GBP, and others, through cryptocurrency exchanges.

Figure 3.10. Transaction costs for the execution of the SimpleCoin transfer function

Figure 3.11. geth synchronizing with the MAINNET network at startup

Figure 3.12. Comparison between accessing geth through Web3.js and JSON-RPC

Figure 3.13. The Deploy operation now accepts the constructor input. After you instantiate the contract by clicking Deploy, the CoinBalance and Transfer buttons appear.

Figure 3.14. Output of successful transfer operation

Figure 3.15. The lifecycle of a SimpleCoin transfer transaction. A transfer transaction is created when a SimpleCoin wallet invokes the transfer() function on the SimpleCoin smart contract on a local node of the Ethereum network. This is then validated and propagated throughout the network until it’s included on a new blockchain block by a mining node. The new block is then propagated throughout the network, and finally it gets back to the local node.

Chapter 4. Deploying your first smart contract

Figure 4.1. A contract written in a high-level language such as Solidity is compiled into EVM bytecode and deployed to the network through a deployment transaction containing the contract EVM bytecode, which is executed through a local full node of the network. The deployment transaction is propagated throughout the network; then it’s processed by a mining node and included in a new block that gets replicated throughout the network. It’s like any other transaction, except that what’s being stored on the blockchain isn’t Ether or data but EVM bytecode.

Figure 4.2. After you enter the Solidity code of a contract, the wallet compiles it into EVM bytecode. Supply the contract parameters, click Deploy, and a new dialog box will confirm the deployment transaction.

Figure 4.3. A dialog box asks you to enter the password of the account that you’ll deploy the contract from. After you supply it and click Send, a deployment transaction is generated and sent to the network.

Figure 4.4. After a contract transaction has been submitted to the network, you can monitor its network confirmations in the Latest Transactions panel of the Contracts screen.

Figure 4.5. After the contract receives 12 confirmations, which makes it very likely the deployment transaction is permanently stored on the blockchain, a deployed contract appears in the Contracts panel.

Figure 4.6. Checking the SimpleCoin balance is a read-only operation, so you only need to specify the input address. Transferring coins is a write operation. As seen here, you have to specify the number of coins to be transferred, the destination address, and the sending account.

Figure 4.7. If a transaction generated from a write operation, such as SimpleCoin.transfer(), fails validation checks, it can’t be sent to the network.

Figure 4.8. When connecting to Ethereum through the Ethereum wallet or the Go Ethereum client console, you do so through a local node. When connecting to Ethereum through Metamask, you do so through a remote node.

Figure 4.9. Creation of a password to secure the MetaMask wallet

Figure 4.10. MetaMask initially points to Main Ethereum Network.

Figure 4.11. It’s possible to connect to various Ethereum networks through MetaMask.

Figure 4.12. Dialog box for importing accounts from JSON files

Figure 4.13. After you import an account from the keystore, all its details appear on MetaMask.

Figure 4.14. The screenshot shows how you can configure Remix to use external MetaMask nodes (rather than the local JavaScript Virtual Machine emulator) by selecting Injected Web3 in the Environment drop-down list.

Figure 4.15. After configuring Remix to point to external Metamask nodes and starting the deployment of a contract (such as SimpleCoin), you get a (deployment) transaction confirmation dialog box from Metamask. This shows information on the account executing the deployment transaction and on transaction costs. The dialog box also asks the user to confirm whether to go ahead with the deployment of the contract.

Figure 4.16. It’s possible to monitor the status of the deployment transaction in the bottom area of the Metamask wallet. This will change from Submitted to Confirmed.

Figure 4.17. Transaction details from the Etherscan website, invoked when clicking the (Submitted or Confirmed) status on the MetaMask wallet

Figure 4.18. After the completion of the deployment transaction, the contract address is shown in Remix, below the Deploy button.

Figure 4.19. To transfer SimpleCoin tokens, which is a contract-state write operation, the sending account needs to be authorized. Subsequently, the MetaMask transaction confirmation dialog box is shown to get user confirmation.

Chapter 5. Programming smart contracts in Solidity

Figure 5.1. Sequence diagram illustrating an external function invocation. The calculateAlpha() function of the TaxCalculator2 contract calls the external calculateGamma() function on the GammaCalculator contract. Because the call is external, the function parameters are sent to the external contract through a transaction that’s stored on the blockchain.

Chapter 6. Writing more complex smart contracts

Figure 6.1. The core crowdsale workflow: 1) investors book crowdsale tokens by paying for them in cryptocurrency; 2) if the crowdsale has met the minimum funding target, tokens are released to the investors; a token bonus might be granted to the organizers, the development team, or other parties involved with the token sale; and the project organization keeps the Ether received and will use it to fund project costs; 3) if the crowdsale is unsuccessful, investors can be refunded.

Figure 6.2. Contract diagram illustrating the token contract hierarchy: SimpleCoin is a base contract, and ReleasableSimpleCoin has been inherited from it.

Figure 6.3. After moving ownership functionality into the Ownable contract, both SimpleCoin and Simple-Crowdsale can still use the onlyOwner modifier by inheriting it from Ownable.

Figure 6.4. Crowdsale’s contract diagram, including Ownable contract and token contract. Both SimpleCrowdsale and SimpleCoin are inherited from Ownable. SimpleCrowdsale has a ReleasableSimpleCoin state variable, so it depends on ReleasableSimpleCoin. (If you’re unfamiliar with objectoriented class diagrams, the hollow-headed arrow means “inherited from,” and the filled arrow means “depends on.”)

Figure 6.5. Place in Releasable-SimpleCoin’s At Address text box the address from SimpleCrowdsale's crowdsaleToken state variable.

Figure 6.6. ReleasableSimpleCoin's state variables and functions

Figure 6.7. Tranche-based token pricing. The total investment up to the minimum funding objective is divided into several tranches, each with a different token price. The token price rises as the total investment received moves from one tranche to the next.

Figure 6.8. Contract diagram illustrating the crowdsale contract hierarchy, with the latest addition of TranchePricing-Crowdsale, derived from SimpleCrowdsale

Figure 6.9. Releasable-SimpleCoin is inherited both from SimpleCoin and Pausable, which is in turn inherited from Ownable.

Figure 6.10. Amended crowdsale contract structure including Pausable contract

Figure 6.11. ReleasableSimpleCoin and SimpleCrowdsale are now also Destructible.

Chapter 7. Generalizing functionality with abstract contracts and interfaces

Figure 7.1. A UML contract diagram showing asymmetry in the crowdsale contract hierarchy and ambiguity regarding token pricing strategy or funding limit strategy in the name of some contracts. For clarity's sake, I’ve omitted ownable, pausable, and destructible base contracts.

Figure 7.2. Funding limit strategy contract hierarchy, including an abstract base contract and two concrete child contracts

Figure 7.3. Making the crowdsale contract hierarchy symmetrical and more explicit. SimpleCrowdsale has been made abstract by pushing the implementation of fixed token pricing down to a new FixedPricingCrowdsale contract.

Figure 7.4. Reorganized crowdsale contract hierarchy, with two layers of abstract contracts at the top and a bottom layer of concrete contracts encapsulating all combinations of the contract pricing and funding limit options. The FundingLimitStrategy contract hierarchy now encapsulates the checks on the funding limit in an efficient way that avoids code duplication.

Figure 7.5. Relationships between an interface and its concrete implementations. You can represent this relationship in two ways. The first one resembles inheritance, with the interface being the parent of its implementations. The second one uses an explicit interface symbol that’s useful if you don’t want to show all the interface implementations.

Figure 7.6. A contract diagram of UnlimitedFixedPricingCrowdsaleWithComplexCoin. You can appreciate the relationships between the abstract SimpleCrowdsale contract and the ReleasableToken token interface and between the concrete UnlimitedFixedPricing-CrowdsaleWithComplexCoin crowdsale contract and the concrete ReleasableComplexCoin token contract.

Figure 7.7. Get the SafeMath library address from Remix by clicking the copy icon.

Figure 7.8. Copy the SafeMath library address into the Calculator constructor text box.

Figure 7.9. After the call to calculateTheta() completes, you can click Details and check the result in the Decoded Output field.

Chapter 8. Managing smart contracts with Web3.js

Figure 8.1. The geth interactive console showing it’s connected to TESTNET

Figure 8.2. The contract build and deployment process: 1. the contract is compiled with the Solidity compiler; 2. the contract binary interface and bytecode are pushed to an output file; and 3. a JavaScript using Web3 is created. This does three things: a. creates a contract factory of the contract from its binary interface (ABI); b. instantiates the contract by invoking new() on the contract factory; and c. feeds the bytecode to it.

Figure 8.3. The output from geth after generating the genesis block of your private network

Figure 8.4. The output from geth after launching it against the private network you’ve created

Figure 8.5. As soon as you launch mining for the first time, the DAG gets generated.

Figure 8.6. After the DAG has been generated and the first blocks get created

Figure 8.7. Ganache accounts and related private keys, shown at startup

Figure 8.8. It’s possible to interact with Ethereum smart contracts through development tools such as the Ethereum wallet and Remix. Alternatively, you can perform contract operations through explicit Web3.js instructions issued from the geth console or the Node.js console. You can execute the same Web3.js instructions implicitly from an HTML web UI.

Figure 8.9. SimpleCoin web UI

Figure 8.10. The balance of the source and destination accounts have changed following a successful coin transfer.

Chapter 9. The Ethereum ecosystem

Figure 9.1. Core components of the Ethereum platform you’ve learned so far: geth, Ethereum wallet, MetaMask, Ganache, Remix, solc, and Web3.js

Figure 9.2. Full view of the current Ethereum ecosystem, showing the items we haven’t yet covered in bold

Figure 9.3. The structure of an ENS name. You can see the root domain, eth, at the far right, followed by the domain name at its left, and nested child subdomains moving from right to left.

Figure 9.4. ENS resolves names into external (user) addresses, contract addresses, and Swarm content hashes. You can’t tell from the domain name itself if it’s mapped to an address or a Swarm hash. As you’ll see later, a domain name must be mapped explicitly to a specific name resolver for either an address or a Swarm hash (or some other resource identifier).

Figure 9.5. The ENS registry design. The ENS registry contract is a map between resource types and related domain resolver contracts. In the future, it can support a new resource type by pointing a domain name (associated with the new resource type) to a new resolver. Domain ownership is registered through a specific registrar.

Figure 9.6. The domain name resolution process: 1. you query the Registry to identify the correct resolver; 2. you request the relevant resolver to translate the domain name into an address.

Figure 9.7. Architectural diagram of a Swarm network. The Swarm network, made of nodes each running a Swarm client, is similar to the Ethereum network, in which every node runs an Ethereum client. Contrary to Ethereum nodes, which all have the same copy of the blockchain data, each Swarm node contains a different set of data.

Figure 9.8. The Swarm upload process: 1. the caller uploads a file to the distributed preimage archive gateway; 2. the DPA sends the file to a chunker; 3. the chunker chops the file into 4 KB chunks and calculates a hash for each one; 4. the chunk hashes are placed in a chunk-index document; 5. the chunkindex document is chunked and reorganized in a Merkle tree structure, whose root hash is called root key; 6. the chunker stores each chunk onto the netStore against its hash; 7. the netStore distributes 4 KB chunks across the Swarm network; 8. the chunker returns the root key to the DPA; 9. finally, the DPA returns the root key to the caller.

Figure 9.9. Chunk and chunk-index Merkle tree structure. The document at the top contains the hashes of chunks of the initial chunk-index document (containing the hashes of all 4 KB chunks). The intermediate layer is made of chunks of the initial chunk-index document. The layer at the bottom contains the 4 KB chunks of the original file.

Figure 9.10. The Swarm download process: 1. a caller hands a root key to the DPA; 2. the DPA calls the chunker, and it supplies the root key; 3. the chunker retrieves the root chunk associated with the root key from the netStore, then walks the tree until it has retrieved all the chunks from the Swarm network; 4. the chunker reconstructs the file from the chunks and returns it to the DPA; 5. the DPA returns the requested file to the caller.

Figure 9.11. Unlocking the Ethereum account you’re using to start up the Swarm client

Figure 9.12. Swarm start-up output

Figure 9.13. The IPFS upload process: 1. a user uploads a file to an IPFS node; 2. the IPFS node breaks down the file into 256 KB blocks; 3. an IPFS object is created for each file block; 4. an IPFS object is created for the file, and it contains links to IPFS objects associated with all the file blocks; 5. each block is stored at a different network location, and an index holding a map between block hashes and corresponding network locations is maintained on each node.

Figure 9.14. The IPFS file download process: 1. IPFS is queried for a file associated with a certain IPFS file object hash key; 2. the IPFS client requests the file object from the corresponding IPFS node; 3. the requested node returns the IPFS file object; 4. the IPFS client scans each link on the Links property of the IPFS file object; 5. each requested IPFS node returns the corresponding IPFS block object; 6. the original file is recomposed on the IPFS node serving the request, and it’s returned to the caller.

Figure 9.15. An oracle is a bridge between the blockchain network and the outside world. It takes care of fetching the requested data from external data providers and returns it to the requesting contract with a proof of authenticity.

Figure 9.16. oraclize_query() parameters

Chapter 10. Unit testing contracts with Mocha

Figure 10.1. The typical AAA structure of a unit test: Arrange (set up test input and the object under test); Act (call the function under test); and Assert (verify the test expected outcome)

Figure 10.2. Output of your first Mocha test, showing the name of the test suite, the name of the test section, and a description of your individual test. The test is passing!

Figure 10.3. Amended test suite, including two constructor tests. Both have passed.

Figure 10.4. Ganache output during test execution. SimpleCoin is redeployed at each test execution.

Figure 10.5. Output of the amended test suite also including tests on the transfer() function. You can now see two sections: one for the constructor tests and the other for the transfer() tests. All tests are passing.

Figure 10.6. Running the whole test suite. The output shows tests are grouped in sections ... and they’re all passing.

Chapter 11. Improving the development cycle with Truffle

Figure 11.1. Error generated when running a Truffle command in Windows

Chapter 12. Putting it all together: Building a complete voting Dapp

Figure 12.1. The workflow of the voting process. Some steps are performed by the administrator, other steps by voters.

Figure 12.2. The Dapp development plan, including all the steps, from creation of a Truffle project to final deployment onto a public test network

Figure 12.3. Truffle project initialization

Figure 12.4. Output of SimpleVoting unit tests on ending the proposal registration session

Figure 12.5. The admin web page. The voting administrator will use this page to register voters, start and end the proposal registration session, start and end the voting session, and tally the votes

Figure 12.6. Screenshot of the voter page

Figure 12.7. The initial workflow status shown on the admin web page at startup

Figure 12.8. Copying the administrator’s account into the corresponding text box

Figure 12.9. Entering the voter address

Figure 12.10. Checking whether an account has been registered as a voter

Figure 12.11. After you start the proposals registration session, the Current Status label will be refreshed with the corresponding status description.

Figure 12.12. Registering a new proposal

Figure 12.13. Ending the proposal registration session

Figure 12.14. The voter page after the votes have been tallied

Chapter 13. Making a Dapp production ready

Figure 13.1. Event handling on the voter page. A new proposal is submitted from the web page to the voting contract. The contract then fires a ProposalRegisteredEvent event on registration completion. The event is propagated throughout the network until it reaches the node the web page is communicating with. Finally, the webpage handles the event, and a new item is added on the proposal table.

Figure 13.2. Duplicated deployment of an OpenZeppelin library. Only one client contract uses each privately deployed instance.

Figure 13.3. Fixing a shared library means redeploying it at a new address, which requires client contracts to be modified and redeployed.

Figure 13.4. When you introduce a proxy to the library, client contracts no longer directly reference an instance of the library; they communicate with the proxy (or library dispatcher), which gets from another contract the latest valid address of the library and then forwards calls to the valid instance.

Figure 13.5. If you decide to make SimpleCoin upgradeable through SimpleCoinProxy, client contracts such as SimpleCrowdsale will call functions on SimpleCoinProxy, which will dispatch them to a specific deployed version of SimpleCoin, generally the latest one.

Figure 13.6. Upgradeability by splitting a contract into two contracts, both inherited from the same abstract Upgradeable contract: a dispatcher holding the state and a target contract holding the functionality. The dispatcher forwards all calls to the target contract. If an upgrade occurs, the dispatcher keeps holding the same unaltered state and forwards the calls to the latest version of the target.

Chapter 14. Security considerations

Figure 14.1. A hash commit–reveal scheme used for auction bid privacy. 1. During the commit phase, you commit a hash of a document containing the sender address, the bid value, and a secret instead of the bid value in clear. 2. During the reveal phase you reveal the bid values together with their secrets. 3. The winner is determined by finding the highest revealed bid. You then verify the results by calculating the hash from its sender address, bid value, and password and comparing it against the previously submitted hash.

Figure 14.2. A hash commit–reveal scheme used for providing reproducible randomness. 1. All players submit their bets. 2. A randomness provider commits the hash of a generated random number, emulating a roulette spin. 3. A transaction, including bets and a random number hash, is processed. All nodes query the provider, which reveals the random number so that winners and losers can be determined.

Figure 14.3. Pros and cons of high and low gas limits

Figure 14.4. Your contract might get manipulated by an external malicious contract, even when you’re confident the contract it directly interacts with is legit.

Figure 14.5. Example illustrating execution in the context of an external contract

Figure 14.6. Example illustrating delegatecall execution in the context of the calling contract

Figure 14.7. Example illustrating callcode execution in the context of the calling contract

Figure 14.8. After the malicious contract has become the highest bidder, the Auction contract becomes unusable because it will unsuccessfully try to refund the malicious contract at every new higher bid and will never be able to set the new highest bidder.

Figure 14.9. If you were to implement Auction.withdrawRefund() incorrectly, for example, by clearing the balance of the caller only after the Ether transfer has been completed, an attacker could attempt to call it many times in parallel while hijacking each call, by slowing down the execution of the receiving fallback() function. Various of these simultaneous Ether transfers are allowed and can complete successfully until one of them finally completes and the balance of the caller is cleared. Before this happens, many illegitimate refunds might take place.

Figure 14.10. Sequence diagram of parallel invocations of an incorrect implementation of withdrawRefund() by an attacker

Figure 14.11. An example of a front-running attack. A malicious miner could detect big buy or sell orders being sent to a stock market-making Dapp and still in the memory pool. They could then decide to front run them by ignoring these big orders and including their own orders in the new block they would try to create, therefore making an unfair profit if the block got mined.

Chapter 15. Conclusions

Figure 15.1. PoS versus PoW. Whereas under PoW, many miners perform work (and consume electricity) simultaneously to append a block, under PoS only one node, called a validator, proposes a new block during a time slot.

Figure 15.2. PoS algorithm. First, validators submit a deposit. Then the selected validator proposes a new block and submits it to secondary validators for approval. If they score the block as correct, it’s appended to the blockchain. The main validator or secondary validators might get penalized in Ether if they’re found to be dishonest.

Figure 15.3. PoA versus PoS. When a malicious node loses their Ether deposit under PoS, their sponsor can set up a new node and continue with malicious behavior. Under PoA, once an authority has been detected as malicious, their sponsor (and all associated identities) is prevented from reentering the network.

Figure 15.4. A constellation network allows Quorum to handle permissioning and privacy. A smart contract is deployed only across the parties involved in a transaction; the transaction is encrypted and stored off-chain, and its hash is stored on the shared Ethereum blockchain.

Figure 15.5. How facts are shared in the Corda network. Each node maintains its own copy of its own facts, but it can share some facts with other nodes. For example, facts 1 and 5 are shared between nodes A and B; fact 4 is only visible to nodes C, D, and E, but not A and B.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset