© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
W. Zhang, T. AnandBlockchain and Ethereum Smart Contract Solution Developmenthttps://doi.org/10.1007/978-1-4842-8164-2_8

8. Security Considerations

Weijia Zhang1   and Tej Anand2
(1)
Austin, TX, USA
(2)
Chappaqua, NY, USA
 

Introduction

We went through many aspects of Solidity smart contract programming already in previous chapters. We covered Solidity programming syntax, using Remix or Truffle to compile source code, and deploying bytecode to an embedded EVM or development blockchain. We also mentioned the token economy and token design such as choosing fungible or nonfungible tokens and using the tokens to represent assets and elements for business use cases.

On the storage and communication side, we talked about the importance of Ethereum blockchain state and event concepts as well as different networks such as mainnet, Rinkeby testnet, and Ropsten testnet.

On the architecture side, we talked about building end-to-end solutions with building blockchain nodes to connect to the Ethereum blockchain, deploying smart contracts , developing web clients or mobile apps, and using Web3 to connect clients with blockchains.

In this chapter, we are going to cover Ethereum blockchain and smart contract security . Security is one of the most critical aspects of software development . It plays an even larger role in the Ethereum blockchain for the reasons shown below in Figure 8-1:

A branching diagram of the complexity of blockchain security. The divisions are the Decentralization nature of blockchain, Constraints of patches and upgradability, Trustless and permissionless environment, Privacy and anonymous nature of blockchain, and High value impact on business.

Figure 8-1

Complexity of blockchain security as compared to conventional IT security

  • Decentralized nature of blockchain Any code written and deployed to the blockchain is going to run in thousands of machines. Anybody can access and run blockchain code.

  • Constraints of patches and upgradability Due to the immutability of blockchains , smart contracts deployed to blockchains cannot be modified. This increases the difficulty for upgrading decentralized applications. When security flaws are detected in blockchain applications, the cost of patching the applications is high, and sometimes, a fork of the blockchain is needed.

  • Trustless and permissionless environment For public blockchains , both the client nodes and decentralized applications are open to global participants. There is no centralized authority to check the qualifications of participants. There is no security perimeter to block bad players from participating.

  • Privacy and anonymous nature of blockchain Blockchain users can remain anonymous. Smart contract functions do not have a way to check the profile of the users. Hackers can carry out blockchain attacks, get the assets, and remain unidentified.

  • High value impact on business Smart contracts normally have a small footprint. Bigger projects might have over thousands of lines of code, while others may only have a few hundred. Smart contracts manage high value crypto assets, and each attack might bring catastrophic results to the decentralized application. Some decentralized applications have suffered huge losses due to simple errors in smart contracts.

Several smart contract breaches have been found in the past. We can classify these security issues as functional security holes and attackable security holes. Functional security holes are obvious code errors and can cause loss of funds with normal transactions and by bona fide users. The functional security holes for smart contract contain the following.

Functional Security Holes in Smart Contracts

Fund Deadlock

This is a security hole where a smart contract can take in fund transfer but will lock the funds in a smart contract indefinitely. For example, a smart contract can implement a receive function to take in funds but not to implement functions for send or transfer. In this case, funds sent to the smart contract will be owned by the smart contract, but there is no way to transfer funds out. Similar to a blackhole, this is a case that takes in everything with nothing going out.

Fund Leakage

This is a functional security hole that can cause leak of funds by an unprivileged user. This is normally due to a lack of access rights and privilege checking. For example, a security hole can be caused by a function that has fund transfer capabilities but is declared public without authenticating the user’s ownership of the fund. In Solidity smart contract programming , there are several places where the security can be enforced, including setting the scope of a function to be public or private, setting the ownership access rights, and using require and assert to make sure access conditions are met before proceeding to the next line of code for execution. When a token is minted or transferred, the smart contract needs to make sure the caller of the function is the owner, or administrator, and an authorized user for the function. It is very important to define roles in smart contracts, and each role will have limited access rights. In CryptoKitty’s example, there are four roles defined including owner of smart contract, CEO of the project, COO, and CFO. For the mint function, the smart contract defines the mint right to COO. You have to be a COO of this project to mint an NFT token. There is also a pause/unpause function to handle emergency situations by halting the execution of smart contracts, and this right is given to the CEO. The CFO can do other things related to auctions. The owner of the smart contract is also a critical role. Normally, whoever deploys a smart contract to the blockchain is the owner of the smart contract by default. This owner can then transfer the ownership to another user, or to a smart contract address, or even renounce the ownership. Because the owner of a smart contract has the highest access privilege, it is very important to protect the private keys for the owner account.

Disabled Smart Contract

This is another functional security hole where a nonprivileged user can call a function to kill the smart contract . This is another thing that needs to be watched. In a smart contract, there might be a function that can be executed to disable the whole smart contract by clearing the states, storage, and settings. If this function is incidentally called, it will completely ruin the smart contract.

Orphan Smart Contract

When a smart contract is deployed, the account that sends the deployment transaction is the owner, and it has high privilege administration rights to the smart contract. Sometimes, to increase the degree of decentralization, the owner might transfer the ownership to another owner account, a smart contract, or denounce the ownership. Once ownership of a smart contract is transferred or denounced after the deployment, the original owner does not have the right to administer the smart contract anymore. It is thus important to come up with a smart contract ownership plan during the design process. Once the smart contract is deployed and ownership transferred or denounced, there is no way to pause or upgrade the smart contracts when an emergency situation arises in the decentralized applications .

Attackable Security Holes in Smart Contracts

This kind of security breach is caused by users with malicious intent. It is less obvious than functional security holes and very difficult to be discovered. Hackers will normally need to construct artificial transactions and carry out multiple steps of attacks. The attackers also remain anonymous and have methods to transfer the funds. These kinds of breaches can also include attacking blockchain nodes and Web3 clients and environments outside the smart contracts. Other breaches have also happened with hackers doing the following: (1) calling faulty internal functions with malicious transactions; (2) changing outside parameters and conditions for a function call; (3) changing whitelist addresses and names; and (4) attacking Oracle. The following are some examples of attackable security holes:

Example 1: Pay bill to arbitrary accounts

The following is a code snippet with a security hole:
pragma solidity ^0.8.6;
contract PayIssue {
function payBill ( address payable recipient, uint256 x_amount ) public payable {
    recipient.transfer(x_amount);
}
}

In the preceding code, there is a function called payBill(address payable recipient, uint256 x_amount) public payable.

This payBill function when called will simply transfer “x_amount” of Ether to the recipient address specified in the function. This function is payable, which allows the funds to transfer to a receiver. Payable is a new keyword in Solidity to specify whether a function or an address can transfer or receive funds.

One main functional security error with this smart contract is that it does not check the privilege of the users calling the function. As this function is public and payable, anyone can call this function and transfer funds to an arbitrary address they specify. In fact, users can call this smart contract to deprive all the funds owned by the smart contract and send them to the hackers address. A simple error in function access scope can cause loss of assets and destroy an otherwise promising project.

Example 2: No guarding of kill or selfdestruct function

There was a security incident in which a “kill” function is coded in a smart contract but does not have privilege checking and eventually caused 300 million in loss of funds. In a community Telegram chat group , a transaction hash is posted. The message sender claimed to be a newbie in Ethereum but had just sent a transaction to call a kill function in a smart contract. Because the kill function does not check user privilege, the function call was executed and effectively reset the storage of the smart contract and destroyed the smart contract. The funds locked by this smart contract are 300 million, and there is no way to recover it once the kill function is executed.

Functions such as kill, destroy, selfdestruct, or renounce are highly privileged operations that have the potential to invalidate a smart contract. It is critical to implement thorough checks on the calling parameters to ensure there is no security risk when these functions are executed.

Best Security Practices for Smart Contracts

In previous sections, we described functional and attackable security holes and some examples. As shown in Figure 8-2, we are now switching to the discussion of good security practices for designing smart contracts and writing code .

A branching diagram of the best practices of blockchain security. Some of the divisions are Have a security risk mitigation plan, Checking both main source code and libraries, Put a cap to the max funds, Leverage the community effort to harden the security, Yes comma there are blockchain whitehats, and Have smart contract audited.

Figure 8-2

Best practice of blockchain security

Have a Security Risk Mitigation Plan

Ethereum and any public blockchains are open and permissionless systems where bad players have the same access to the smart contracts as good players. It is essential to have a mindset that there could be bugs and security holes in the smart contract, and some mitigation plans should be prepared. For example, in the smart contract of CryptoKitty , there is a pause function implemented, and only the CEO can pause or unpause the smart contract. If there is a security hack of smart contracts, the CEO can send a transaction to call the pause function and halt the minting and auction of CryptoKitties.

In addition, it is important to consider the trade-off between decentralization and upgradability. Blockchains are supposed to be immutable, and therefore, the smart contracts by default should be unalterable. On the other hand, there is no way to write Solidity code that is free of bugs or vulnerabilities. A better practice is to classify the smart contracts into two classes one is stable and cannot be updated, while the other is dynamic and can be upgraded by privileged administrators. The smart contracts that are called by Web3 clients can be proxy smart contracts that are not upgradable and have a fixed address, while the other contracts that are called by the proxy smart contract can be upgraded. Once a smart contract is upgraded due to bug fixes, the address of the newly deployed smart contract is updated in the proxy smart contract, and there is no need to change the Web3 clients.

Checking Both Main Source Code and Libraries

Not only can security vulnerabilities happen in the code you write, but also they can exist in the libraries imported to your smart contract. The library’s code might also be written in different versions of Solidity and hence increase the complexities of integration and security risk. For example, some of the libraries are written in Solidity version 0.4, while the main smart contracts that you are working on might be in version 0.8. Solidity version 0.4 does not support certain security features, and modifications are needed to integrate the libraries. This in turn increases vulnerabilities for the whole smart contract. Therefore, it is important to have compatible versions of main code and libraries, and the security review, audit, and test should include library code as well.

Put a Cap to the Max Funds

Due to the complexity of smart contracts, sometimes, it is good to set a maximum amount of asset values a smart contract function can handle. A smart contract can have a global cap, and each function with asset transfer capability will compare the amount of assets to be transferred with the cap. If it exceeds the cap, the function will not execute the transfer. This provides an additional safety guard to prevent asset loss. In fact, the ERC20 smart contracts have an “approve” function to set the maximum amount of funds that can be transferred by a user calling a transfer function.

Because total values of cryptocurrency processed by smart contracts are growing exponentially, projects such as Uniswap and Compound have billions of dollars of assets managed by smart contracts. If there is a security breach with the smart contract code, the impact is huge. It is always a good practice to have a design to put a threshold on the amount of funds that can be impacted if there is a security breach.

Make Your Smart Contract Open Source and Leverage the Community Effort to Harden the Security

Smart contracts are used to power the DeFi world where there are no central authorities and big IT teams to bring trust and security to the platform. It is therefore important for the project community to play a critical role in hardening the smart contracts. Unlike legacy financial applications where software vendors use their engineering resources and services to ensure security and quality, smart contracts are normally open sourced so that the community and users can review the codes to make sure that the business logics are accurately encapsulated in the source code. Community developers are encouraged to review the source code, and big bounties are provided for experts who are able to find any functional, cosmetic, or security defects. Smart contracts are also deployed to testnets first with alpha and beta releases, and communities are requested to find defects and rewarded with bug bounties. Because dApps powered with smart contracts are normally projects that can issue tokens, sometimes, community developers are rewarded with project tokens when they find security issues or defects. Healthy and growing projects that manage billions of dollars of crypto assets always have enthusiastic community developers who work hard to improve the security of smart contracts.

Yes, There Are Blockchain Security Whitehats

Sometimes, smart contracts get hacked with different endings. It happened several times that “hackers” did not have intention to steal the fund, but rather to teach a lesson to the project team. So if a security breach does happen, it is important to watch where the funds get moved to. Hackers who have intention to use the stolen funds will normally transfer the fund to a “mixer” to hide the identity and remove the traceability of the fund. Whitehat hackers will just move the fund to a security location, tell the project team about the security breach, let the project team fix issues, and then move the fund back. So if a security breach does happen, don’t panic; the result might not be as bad as it looks.

Have Smart Contract Audited

Smart contracts auditing is a good practice to harden security. A security audit is a practice to hire an external professional company to evaluate and review token economy, smart contracts design, and code implementation. Auditors use automatic security scanning tools and manual penetration testing to produce a thorough report of the smart contracts. The security scan of smart contracts can reveal static security errors in syntax and programming styles. More in-depth review of smart contracts will require experts to go through each smart contract in UML diagrams and figure out the relationship between functions and inspect potential vulnerabilities. Sometimes, meetings are held by the project team and audit team to go through the smart contract design to figure out if the end-to-end flow has security issues. Any issues found are labelled with severity levels, and critical issues will need to be fixed in order for the product to be released. A security audit can not only improve security of smart contracts from catastrophic failure, it is also required when the project team later decides to work with other partners or wants to license their smart contracts to other companies. Security audits have been a growing business in the blockchain industry, and there are often backlogs with audit requests . Expedited audit normally requires much higher fees; therefore, security audit time should be built into the project release schedule.

Readable Smart Contract Logic

We mentioned that smart contracts have high VLC (value per line of code). It is extremely important to make sure smart contract logic is straightforward and easy to read. If you read smart contract codes of good projects, you will probably find out that often there are more comments than source code itself. The comments are there to help readers to review and make sense of the source code. If you strip the code out of the Solidity file, you will find that the comments are actually good design and documentation for the smart contract functions. Good smart contracts are written and documented in a way that both technical and business experts can read it and get a good picture of the business logic.

Modularize the Smart Contract

Solidity is an object-oriented programming (OOP) language where you can use hierarchy, inheritance, and polymorphy mechanisms to define classes and functions similar to Java and JavaScript. A good practice of modularizing smart contracts is to mimic the real-world scenarios and build the smart contracts as the components of the corresponding business logic.

Using Well-Tested Libraries

Relevant to modularization, using well-tested libraries is another way to increase security. Since the majority of smart contracts are open source, there are many handy and secure libraries that have been built and available for use. For example, OpenZeppelin provides a good set of libraries such as SafeMath, ERC20, and ERC721, while Oraclable provides Oracle libraries to use.

Well-established library code normally has better boundary checking for their smart contract functions. For example, SafeMath libraries have checks on the arithmetic data type ranges and division checks for denominators equal to zero case. Using library code from a well-tested project decreases the uncertainty of the main code.

Use a Good Random Number Generator

In gaming applications, sometimes, smart contracts use a Random Number Generator (RNG) to generate a random number to pick a winner from a group of users. RNG is also used to enhance security by grouping actors randomly to prevent collusion. It is generally not a good idea to roll out your own RNG without a sound mathematical validation and thorough testing of the degree of randomness in RNG. For example, using the hash value of a blockchain block might seem to be random for some applications. However, if the smart contract of the dApp is handling large-scale and high-value gaming similar to Powerball, the randomness of blockchain hash is attack prone. A block producer can add or remove transactions in a proposed blockchain block and provide a manipulated hash. At this time, there is not a perfect RNG onchain, and full randomness has to be introduced through offchain computing and brought into blockchain by using Oracle.

Review Gas Consumption in Security Context

Gas usage and fees are designed as a way to compensate miners and increase the cost of deliberate attack on the Ethereum network. In a smart contract transaction, each function and storage will consume gas, and the gas cost is paid by the user who sends the transactions to the smart contract. There are several security factors to consider when dealing with gas consumptions in smart contracts. In a dApp application, if a proxy is used to send transactions for users, then it is important to review the functions to see if the gas consumption is a fixed value and if there is a potential for the function to get into an infinite or large loop and deprive the Ether of the sender’s account. In general, smart contracts should be designed and written in a way to minimize gas consumption. To achieve these, special attention should be given to avoid while-loops for long operations, large dynamic arrays for data storage, and complex function calls across smart contracts. When writing smart contracts, there are some gas estimate tools to help check the usage of gas in the code. There is also a gas consumption table published by the Ethereum Foundation as a guide to optimize gas performance for smart contracts.

Wisely Use Blockchain

Some people have misconceptions that blockchain can solve all problems that conventional IT technologies cannot solve today. To some extent, blockchains do solve challenging problems such as consensus, decentralization, permissionless, and token economy. However, today, there are still many drawbacks for blockchain technology . For example, when a smart contract is executed, it runs on thousands of machines simultaneously. In fact, the Bitcoin blockchain has over 20,000 mining nodes, and Ethereum has thousands of nodes. All Ethereum nodes will have the same deployed smart contract and will run smart contracts to process the transactions. With this scale of redundancy in the blockchain, it drastically decreases overall performance and increases risks when something actually goes wrong.

So from a security point of view, in a dApp architecture and design, it is a better practice to use blockchain for the system that requires decentralization, multiparty consensus, immutability, and transparency. For components such as UI (User Interface), dynamic content storage, temporary data, and heavy computations, these can be done offchain. Take the example of CryptoKitty ; the minting, gene generation, and management of kitty auctions are done onchain, while the UI and rendering of kitty are done offchain. Well-balanced onchain and offchain components of decentralized applications increase usability, upgradability, performance, and security.

Stay on Top of Security Breaches and Patches

Blockchain is far away from a stabilized state, and security breaches happen quite often. So it is helpful to subscribe to blockchain security news alerts and evaluate any hacks that might impact your projects. Blockchain hacks always get to the headline of the media. In the Ethereum community, workaround, security vulnerabilities are discussed and shared quite timely. It is important to have action plans if the security breaches impact your smart contracts deployed in the production network.

It is also best practice to upgrade the smart contract code to the latest version of Solidity as soon as possible. This is easy to say but is very difficult to actually do. Once the smart contracts are deployed, they cannot be patched due to immutability of blockchain. An upgrade will require abandoning the old smart contract and deploying a brand new one. Also there are various versions of Solidity programs coexisting in smart contract libraries and production codes. There are incompatibilities among different versions of Solidity compilers. Before deploying a smart contract, it is best to upgrade all source code for both main smart contracts and libraries to the latest version.

Also there are some good security analysis and visualization tools that can be used to help developers write secure smart contracts. Security scanning tools can help developers to spot static security vulnerabilities and follow good security coding practice. Visualization tools help developers and reviewers to see the whole picture of the smart contracts and analyze potential attacking points from hackers.

Blockchain Specific Security Tips

For programmers who used to develop stand-alone applications or web services , it should be noted that blockchains have some special properties and pitfalls to watch and avoid.

When doing cross smart contract function calls, the calling function will take in the address of another smart contract and call the bytecode of a target function. Sometimes, that target function might contain malicious codes and alter the control flow of the calling function. It is very important to inspect the source code of the target smart contract to ensure it is free of security vulnerability . If the address of the target smart contract is passed in from outside, it is vital to ensure that only privileged users can pass in the target address.

Ethereum blockchains are public, decentralized, and permissionless. If there is any function in a smart contract that is declared as public, anybody in any part of the world can call that function and pass in arbitrary parameters. So it is important to double-check the scope of function and have parameter check for all permutations that might cause security breach. Public functions in smart contracts are globally public and can be called in any order with any data. Therefore, it is extremely important to check the following attributes for a smart contract function:
  • Scope of function Declare whether it is public or private, or view.

  • Scope of access Check who can call the function, maybe only owner, or only a predefined user role.

  • Parameter permutation Check parameter range of data. Check validity of inputs.

Ethereum blockchain’s intrinsic security has some constraints. When a variable is declared in a smart contract, it can be a private variable. However, a private variable is really not private as the Ethereum Virtual Machine (EVM) installed on blockchain nodes can reveal it. To ensure privacy of data in smart contracts, the data should be encrypted before sending to blockchain and then decrypted after receiving from the blockchain. Because of the transparency of public blockchain, onchain data encryption and decryption are not secure in smart contracts. The execution steps and internal data are viewable with an EVM with debugger enabled. The encryption and decryption should be performed through offchain computing.

For decentralized applications that need to use time sequence in computing, it is important to know that timestamps in blockchain are not accurate because miners can manipulate the block time by delaying or accelerating block computation and proposal. It is not a good practice to use block timestamp to check for sequencing execution and ordering transaction steps. The timestamp of blockchain or transactions should not be used as a unique identifier for multiple events as there is no guarantee of block timestamp collision within the range of seconds.

Security needs to be considered in all life cycles of smart contract development, from conceptions, requirements, token design, architecture, to implementation and operations. One important security factor to consider is safe-guarding private keys in the deployment process. Crypto assets are stored in accounts, and each account is represented by a private and public keypair. Private keys are used to sign transactions to send assets from one user to another. Whoever has the private key of an account owns the asset of that account. When deploying a smart contract to a blockchain, there needs to be a user who sends the deployment transaction to the blockchain. To sign a transaction, the user needs to unlock the account with its private key. If an account is unlocked in a blockchain, its private key is open and can be stolen by a spoofer. This has happened many times in the cryptoworld.

There are several secure ways to deploy smart contracts. For example, users can use a hardware wallet or use an offline wallet for the deployment. In both cases, the private keys are kept in separate devices, and only signed transactions are copied to the online system to be sent out to the blockchain. Since a private key will never leave a dedicated device without network communication, it is completely secure unless the device is physically tempered.

Security Impact of Quantum Computing

The security impact of quantum computing has been a major concern of the blockchain community. People worry if the supremacy of quantum computing will nullify blockchain advantages and bring cryptocurrency value to zero. Quantum computing is a revolutionary technology that takes advantage of quantum physics’ amazing principles and phenomena such as superposition, entanglement, and measurement uncertainty. In quantum computing, a qubit is used to represent the “0” and “1” state of a quantum system , similar to bits in conventional computing. Multiple qubits can be built into a register to become a compute and storage unit for quantum computing. Quantum computing provides much higher computing power and is going to impact blockchain in the following areas.

The hashing algorithm of sha-256 or sha-3 will no longer be valid. A hashing algorithm is a one-way function that takes in an input string and produces a fixed length output string. One important requirement for hashing is that different inputs should generate different outputs. Also, there should not exist a way to reversely compute an input from its hash value. With quantum computing , these rules will be broken, and any system that relies on hashing such as SHA256 will need to be overhauled.

The asymmetric public key–private key signature algorithm such as ECDSA or DSA that uses elliptic curve cryptography will no longer be secure. Quantum computing can compute private keys from public keys or break a signed message from a private key.

The impact of quantum computing on cryptography will in turn impact the security of blockchain in areas as shown in Figure 8-3.

A branching diagram of the impacts of quantum computing. The divisions are Broken blockchain dash Block hash no longer uniquetralization nature of blockchain, Lost Assets dash private and public keys no longer safe, Invalid transactions dash message signature no longer valid, and Broken consensus dash Quantum computing supremacy in P O W.

Figure 8-3

Impact of quantum computing on blockchain security

The fundamental immutability of blockchain will be impacted. Blocks in blockchains are uniquely identified by their block hashes. If hashes are no longer secure and can be manipulated with quantum computing, then blockchain can be altered with data changed inside but still keeps its hashes on the chain.

The crypto assets are no longer secure because the private keys that control asset accounts can be hacked with a quantum computer.

The P2P network layer communication will no longer be secure. Ethereum uses secp255k1 for nodeKey and nodeId generation. As secp256k1 will no longer be secure, the client node identification and communication mechanism will need to be changed.

The smart contract of Ethereum blockchain is no longer valid because the owner of the smart contract can be hacked as well.

All transactions signed with private keys with ECDSA and SECP256 are no longer valid, and new algorithms will need to be used.

Even the proof-of-work (POW) consensus will be impacted. The POW is based on computing a matching hash to validate a miner who proposes a block. With quantum computing, the computation is so fast, and those with quantum computing power will build the longest chain, hence breaking the 51% computing power role.

To mitigate quantum computing supremacy , there are several key items to consider.

Firstly, Ethereum 2 is moving from POW to POS (proof of stake). This will mitigate the impact of quantum computing on consensus.

Secondly, there are quantum-resistant signature schemes developed already, including Lamport, XMSS, and SPHINCS.

Thirdly, the security compact of quantum computing is not just on blockchain, it is on all cryptography and network computing. The quantum solutions worked out in the general field can be ported to blockchain.

Fourthly, the solution for the impact of quantum computing on blockchain security might go beyond the technology side of blockchain. There might be some legal regulations to prohibit using quantum computing power to hack information and blockchain systems. Similar to the nuclear nonproliferation policy, there might be some restriction on quantum devices released to the public domain.

It is very important to follow the development of quantum computing and stay on top of the mitigation plans and get ready to make critical decisions. With IBM on the way to release 1000 qubit devices and Google making the leap jump on quantum computing, it is inevitable that computing will challenge and threaten the security of blockchain. It is highly recommended to learn about quantum computing technology and get ready to accept quantum-resistant technology for Ethereum blockchain.

Summary

In summary, we just cannot overemphasize the importance of security in blockchains. Security breaches and bad things have happened in the past, are happening now, and will happen in the future. So when you write Solidity smart contracts, make sure the security procedures are followed; always go above and beyond to let the community test the smart contracts out before rolling them out to the blockchain mainnet.

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

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