I am serious—think twice before deploying smart contracts on production!
Before deploying smart contracts on the mainnet (production), you must ensure that all of the unit tests and other test cases that you have for the smart contract are passing. Your code is reviewed by some other developer to ensure that the logic of the contract is correct and is going to behave as per your expectations in production. Ensure that the code coverage reports are reviewed, and the maximum possible coverage of the code is ensured.
You might be wondering why I am mentioning these normal things—as a developer, you would think that these are the processes we follow on a daily basis during software development, so what's new and special about this?
To date, as a software developer, you have been writing software/applications and following best practices to ensure that no errors/bugs are in the system. But, at the back of your mind, you also think that if something goes wrong with the script/code, we can apply a patch and re-deploy the software/application again, with no issues. Since the beginning of software development, this has been the practice.
Now, as a software developer, you need to understand that smart contracts are not like your existing software/applications, where you can apply a patch and change the code at any time. As smart contract code becomes immutable once deployed, only states/variables can be changed via allowed methods that are present in smart contracts. As a developer, you need to mentally prepare yourself for the fact that the smart contracts you are writing cannot ever be changed once deployed on the Ethereum blockchain. If you have experience of writing device drivers for hardware, then you can understand this easily as device drivers have limited changeability/upgradability.
If you are planning to upgrade smart contracts in the future, then you need to be prepared for it when deploying the first version of the contracts. For example, you should be able to stop an existing version of a smart contract and move on to the new upgraded version. You also need to think about how existing users will migrate to a new upgraded version of contracts.
There are some design patterns available to provide upgradability to smart contracts. We will cover those in Chapter 11, Upgradable Contracts Using ZeppelinOS.
The preceding summary is not intended to threaten you about how smart contracts could go wrong, but to inform you about the consequences it could cause if the code is not well tested and reviewed with multiple iterations.