Best practices in the development of Smart Contracts
Smart contracts are one of the key tools when developing decentralized applications. The problem is that once implemented and deployed on the blockchain, they are immutable and cannot be changed or corrected. That is why there is a base of vulnerabilities to be taken into account during their development and testing, as well as good practices.
Best development practices
In this article we will focus on the best practices for the development of a smart contract and due to its length, in the following article we will point out the most common vulnerabilities. During the development of a Smart Contract, before its release to the main network, certain aspects must be considered, but we must be very sure how we are protecting the critical data that we are entrusting to the code. The use of tools such as OpenZeppelin, which we will explain later, allows a development with a security guarantee seal.
You should keep in mind that your smart contract will be exposed from the very first moment you publish it on the Mainnet and that is why you need to consider a number of best practices to ensure that it can cope with existing vulnerabilities and possible bugs. The practices are subjective and also depend on the developer's approach.
Ethereum is a very complex project and that is why it is constantly changing and new bug discoveries must be fixed as they are discovered. Therefore, it is extremely necessary to have continuous good practices that allow to adapt to new bugs and first we can focus on the most general and are the main phases of software development.
Design: the process flow, functions, attributes and operations that the system will perform will be detailed. In addition, in this phase the threats and vulnerabilities to which our smart contract can be exposed must be considered and a threat modeling design as well as a security design must be made. All the threats that have been exposed afterwards must be verified in the testing, auditing and monitoring phase.
Development: this phase is the implementation of the code for the development of the smart contract with all the functions and flows previously defined in the design phase. In this phase is where tools such as 'listing' and 'OpenZeppelin' can be used, taking into account at all times the vulnerabilities to which the contract is exposed. This is why templates, OpenZeppelin standards, libraries and contract interfaces that have been previously audited can be used.
Testing: it is time to test our contract to verify its correct functioning and to discover new vulnerabilities in case they exist. Security frameworks such as Hardhat, Mythrill, Truffle, Mocca, etc. can be used. In addition, it is highly recommended to use NatSpec' comments to specify side effects, as well as the parameter is and expected return values. Finally, both internal and external reviews should be done, consulting ConsenSys and OpenZeppelin guides that provide checklists of considerations and you can resort to user pages that are dedicated to try to attack our smart contract to find vulnerabilities.
Deployment: this is the phase in which the project/contract goes into production.
Maintenance: the Smart contract should be evaluated and modified for a period of time before being launched on the mainnet to ensure that everything is working properly.
General practices for smart contracts on Ethereum.
This is not a bible to be followed to the letter as each developer will also have his own criteria.
First of all, prepare for failure. Every smart contract will have bugs at any time, either during the production phase, testing or once it is deployed, which is why you must prepare the contract for emergencies and be able to respond to problems. On the other hand, you must perform unit tests and exhaustive tests of the contracts, making an incremental scaling and deployment that allows a modular development and is able to solve all vulnerabilities. In fact, as mentioned above, you can even offer rewards for the discovery of bugs in the smart contract during its publication on the alpha test network.
Simplicity and upgrade: Simplicity in the development of smart contracts is important, because if they are made very complex there will be more likelihood of errors and it will be more complicated to find them or even fix them. On the other hand, Blockchain technology and the development of smart contracts are constantly evolving and more so in public networks such as Ethereum with its Solidity programming language that is being improved every few years and the Ethereum network will continue to make changes as shown in its roadmap. It is important to be updated on new development techniques as they emerge.
External callsWhen developing code for smart contracts it can be common to make use of external libraries or make calls to external sources, either other contracts or oracles, which can execute malicious code back to our Smart Contract and if we are not prepared to prevent such attacks they can enter our flow and cause a loop to empty the contract. From a software engineering point of view a smart contract must be modular, allow code reuse to avoid duplication and support components that are upgradeable. However, if we focus on the security architecture view, the same principles are not shared and that is why a balance must be maintained between the two approaches.
Meeting standardsThe contract must comply with a series of norms and standards in order to be published on certain platforms and it would be convenient to be sure that previously tested protocols and contract interfaces have been followed. On the other hand, the transfer of tokens to address 0x00 and that of the contract itself should be avoided.
It consists of a project that provides a set of tools for a developer to build smart contracts using a complete set of security products and auditing services provided by OpenZeppelin. It offers an SDK with a set of development, testing and update tools for smart contracts, as well as a library of smart contracts that have been tested against risks and vulnerabilities, as well as being reusable and secure for the network
Having errors in the code during the development phase is inevitable and in web applications3, they can become very serious problems, either at the user experience (UX) level or compromising the security of the system. This is why lint-type tools are used nowadays. Programs that analyze other programs for possible problems with both their syntax and semantics (in contrast to unit tests). In other words, it is a process of checking the code for possible errors. It is usually performed by a tool that looks for problems in the code, such as missing semicolons, missing brackets, etc.