General Philosophy of Programming Smart Contracts
Coding smart contracts on a public blockchain like Ethereum is different from coding “normal” software. Some people even say coding smart contracts is more like hardware design than software development. The reason is that once a smart contract is deployed, it can be attacked by everyone at low costs, and fixing bugs is difficult as it requires good preparation. As soon as a bug has been found, it is usually exploited, and the loss is high. This makes it necessary to prepare for both known vulnerabilities and unknown vulnerabilities.
Here are some general principles of coding smart contracts.
Keep it Simple
The more complex software becomes, the more bugs and vulnerabilities will find their way into it. This is normal as people cannot deal with high complexity. That’s why it is a good practice to keep contracts as simple as possible.
Keeping something simple means that the logic should be clear and easy to understand. Everything that is not necessary should be left out of the contract. The off-chain user interface should take care of that. Only those parts that really require decentralization should be part of the contract.
Modularity helps to keep the overview and functions small and concise. It is also advisable to use existing code (libraries) instead of writing everything again from scratch. Re-used code should be open source so that there was enough time to find vulnerabilities.
Understand the Blockchain Properties
Compared to “normal” networks, blockchains have some peculiarities. What exactly these are, depends on the particular blockchain. If you use public blockchains like Bitcoin or Ethereum, all transactions and data are public. Thus, it is impossible to store secrets in a smart contract.
It is also important to remember that block producers can (and do!) influence the order of a transaction. They can also delay transactions if it appears beneficial for them. A good starting point to dig a bit deeper into this field is the keyword “Miner Extractable Value (MEV)”.
Another issue is that randomness is very hard to achieve due to the decentralized nature and the public data.
Auditing
Before you deploy your smart contract to the mainnet, let other skilled people look over it. This helps to identify issues you haven’t seen or even thought about. But be aware that audits do not guarantee a 100% error-free smart contract.
If you have an active community, you can make your smart contract open source and invite your community members to inspect the code. An additional bug bounty program can create further incentives to check the security of your code and reveal the findings to you before they were exploited.