Are smart contracts really immutable? Learn about Upgradeable Smart Contract.
Smart contracts are immutable when they are deployed on-chain. No one can alter the logic in the contracts so that the contracts can be trustable and unbreakable.
But… It might not be immutable in the way you think of.
The need of updating the smart contracts
If the smart contracts are all unchangeable, what to do if you spot a bug in the contracts? How to add the new features into the contracts iteratively? What if you just have to update the logic as the requirement changed?
It is really difficult for the software engineers to launch a flawless smart contract in one shot. When there is a will, there is a way. There are few methods to change the smart contracts.
1. Migrate to a new smart contract manually
The traditional contract between two parties can be changed when both of the parties agreed to do so. In blockchain, it is common to tell the community that you deployed a new smart contract and try to convince every user to adopt the new contract. The user may need to manually withdraw the fund from the original smart contract and interact with the new version of the smart contract.
This is great because the users are aware of the version changes and their funds are migrated to the new contract only when they agree and manually migrate it.
2. Upgrade using proxy pattern
Isn’t it great if we can replace the logic without changing the smart contract address that users interact with? This is where proxy pattern comes in handy.
A proxy contract acts as a single access point that users can interact with directly. Proxy contract can forward the transaction to an implementation contract that contains the logic. When we want to change the logic, all we have to do is deploy a new contract and replace the implementation contract address to the new contract address. Users can access the latest version of logic using the same proxy contract.
The amazing part of the proxy pattern is both of the contracts remain immutable but we are now able to swap the implementation contract with a new one!
How to preserve state between different versions
When proxy forwards the transaction to the implementation contract using
delegatecall opcode, it executes the implementation contract’s code in the context of the proxy’s state. The states are preserved when replacing the logic contract because the states are always in the proxy.
How to use it
You can write the proxy contract by yourself or use the OpenZeppelin Upgrades Plugins. The guide is clear and simple so I won’t dive deep into the hands-on tutorial.
Few concepts to understand before using upgradeable contract:
- Why can’t we use
constructorin the implementation contract and what
- Storage Collisions and Function Clashes
- Different proxy patterns