Are smart contracts really upgradable?
“TL;DR” Not exactly.
Smart Contracts are pieces of software that exist in blockchains. They can execute actions according to a series of pre-programmed parameters. All of this is done in an immutable, transparent, and completely secure way. The fact that these smart contracts are distributed across thousands of machines makes them censorship-resistant, transparent, efficient, secure, and inexpensive.
What is OpenZeppelin?
OpenZeppelin is a company that offers a variety of services for developing distributed applications. It also offers some free standard-base smart contracts that are audited for security reasons, and are some of the most-used smart contracts among developers. When building a new smart contract you often have to follow standards like ERC20 or EC721. Instead of reinventing the wheel, you can just inherit your contract from one of the openZeppelin contracts to save time and start programming your specific business rules right away.
Why upgrade a Contract?
By design, smart contracts are immutable. On the other hand, the quality of software depends heavily on the ability to upgrade and patch source code in order to produce iterative releases. Even though blockchain-based software benefits significantly from the immutability of the technology, a certain degree of mutability is still required to fix bugs and make potential improvements to the product. OpenZeppelin Upgrades solves this apparent catch-22 by providing an easy-to-use, robust, and opt-in upgrade mechanism for smart contracts that can be controlled by any type of governance, be it a multi-sig wallet, a simple address or a complex DAO.
How do I upgrade a Contract?
The basic idea is to use a proxy to make upgrades. The first contract is a simple wrapper or “proxy” which users interact with directly and is in charge of forwarding transactions to and from the second contract, which contains the logic. The key concept to understand is that the logic contract can be replaced while the proxy or the access point is never changed. Both contracts are still immutable in the sense that their code cannot be changed, but the logic contract can simply be swapped for another one. The wrapper can thus point to different logic implementations and, in doing so, the software is “upgraded”.
When we deploy our implementation contract with the Upgrades plugin we are also deploying 2 further contracts: The Proxy Contract and the ProxyAdmin Contract. The Proxy Contract is the contract that your clients will connect to. You will not need to update this contract since it does not hold any of the logic, just the state. The Implementation Contract holds the logic (that you can later upgrade if you find bugs or want to add features).
The ProxyAdmin Contract is also deployed, the only responsibility of which is to change the Proxy Contract to point to a newer Implementation Contract. Only an admin owner can pull off this trick.
There is a special function in Solidity called DELEGATECALL that allows you to call another contract using the context of the caller, not the callee. This allows for the distinction between state and logic which makes the “upgrade” possible.
About the Author
Javier Acrich a multi-talented .NET Developer capable of managing both front-end and back-end development. Successfully creates and modifies web features to improve functioning for clients. Skilled in architecture and design of web applications and solutions.