Smart contracts are contracts that automatically execute transactions following predetermined rules. Thus, transactions are encrypted and stored on a distributed ledger and are intended to be immutable. As per a report by Verified Market Research, the global smart contracts market size was valued at ~ $145 million in the year 2020 and is projected to reach ~$771 million by the year 2028, growing at a CAGR of 24.55% during this period.
Smart contracts are superior to traditional contracts since they exist on the blockchain and remove all the intermediaries involved in the process. Smart contracts provide benefits like making transactions more efficient, seamless, and cheaper. Smart Contracts have found their applications in healthcare, real estate, supply chain, and financial services.
Smart contracts in Solidity
The code of Solidity is encapsulated in contracts. Thus, a contract in Solidity is a collection of codes (its functions) and data (its state) that resides on the Ethereum blockchain at a specific address.
Features of Smart contracts in Solidity
Contracts are enabled to execute literally through Solidity programming. Thus, in case of any ambiguity in the contract can block the transactions, unlike traditional contracts where parties can work together and reach an agreement. This is impossible on blockchain since transactions are irreversible.
Smart contracts are automated and thus are self-verifying. Smart contracts are self-enforcing once all the rules are met and they are tamper-proof as once programmed it cannot be changed.
Smart Contracts in Solidity for Ethereum are immutable by default. Once the smart contract is created there is no way to alter or change them. The code of the smart contract cannot be changed once it has been deployed. This makes them act as an unbreakable contract among participants.
Are smart contracts upgradeable?
Smart contracts are pieces of software existing on the blockchain and they can execute actions as per a set of pre-programmed parameters. The entire process of smart contracts is done in an immutable, transparent, and secure way.
Smart contracts are distributed across thousands of machines and that adds the following features to them –
- Transparency – The data on the blockchain can be seen by everyone
- Inexpensive – As middlemen are removed the cost of deployment and implementation is reduced significantly
- Efficiency – There is no room for misinterpretation of information or lost documents
- Security – The transactions are secured using cryptography and this helps prevent any kind of attacks
How to upgrade smart contract in solidity if required
Since smart contracts are immutable it is almost impossible to alter them once deployed. If the smart contracts are redeployed, they generate new addresses which results in the loss of the former smart contracts’ data.
There can be cases when there can be a requirement to alter the smart contract to fix a bug or add additional features or change the rules enforced by it.
Here are some ways the bug can be fixed for smart contracts that cannot be upgraded –
- A new version of the smart contract can be deployed
- All states can be migrated from the old contract to the new one manually
- All contracts that interacted with the old contract can be updated to use the address of the new one
- All the users of the smart contract can be contacted and convinced to start using the new deployment
- The above solutions are cumbersome, time-consuming, and expensive to execute. There are some plugins developed by OpenZeppelin that can build contract upgrades directly. These plugins allow changing the contract code while preserving the state, balance, and address of the smart contract.
- The immutability of smart contract technology has many benefits but a certain degree of mutability is required to fix bugs and make some potential improvements to the product. The upgrades provided by OpenZeppelin are an easy-to-use, robust, and opt-in upgrade mechanism for smart contracts.
What are proxy contracts?
A proxy contract is a contract that calls to another contract that is called the implementation contract. The basic idea of proxy contracts is that a caller which is an external or contract address makes a function call to the proxy. This proxy delegates the call to the location of the function code known as the delegate. The proxy then receives the result and forwards it to the caller.
The proxy contract redirects call to other contract implementations using a custom fallback function. It works in a way whenever contract A delegates a call to another contract B, the code of the contract is executed in the context of contract A.
Build upgradeable smart contracts in Solidity using Proxy contracts
Upgrades are made to smart contracts using proxy contracts.
There are two contracts –
- The first contract is the simple wrapper or proxy
- The second contract is the logic
The users interact directly with the first contract or the proxy and it is in charge of exchanging transactions with the second contract which contains the logic. The proxy or the access point can never be altered or changed while the logic contract can be replaced. Both these contracts are immutable since their codes cannot be changed. But the logic contract can be swapped for another one.
The software is upgraded when the proxy can point to a different logic implementation.
OpenZeppelin provides plugins that allow upgrading the smart contracts easily.
Two contracts are being deployed when the implementation contract is being deployed with the Upgrades plugin. The two contracts are The Proxy Contract and the ProxyAdmin Contract.
The Proxy contract holds only the state and not any logic and thus does not need to be updated. It is the contract that the clients will connect to. The Implementation contract holds the logic and will need to be updated in case any bugs need to be fixed or features need to be added.
The proxy contract is not upgraded instead it is made to point to a new V2 contract that has the bug fixes or new features. The clients do not need to switch to the new V2 contract because they are connected to the Proxy contract.
When the upgrade happens the ProxyAdmin contract is also deployed. The responsibility of the ProxyAdmin contract is to change the Proxy Contract to point to the newer Implementation contract.
How do upgrades for smart contracts work?
When a new upgradeable contract instance is created, the OpenZeppelin Upgrades Plugins deploy three contracts –
- The contract that has been written is known as the implementation contract and contains the logic
- A ProxyAdmin is an admin to the Proxy contract
- A proxy to the implementation contract with which the client interacts
The proxy delegates all calls to the execution contract. A delegate call is similar to a regular call, the only difference being that all code is executed in the context of the caller and not the callee. Thus, the “transfer” command in the implementation contract’s code will transfer the proxy’s balance. Any reads or writes to the contract storage will do it from the proxy’s storage.
The proxy of the contract holds the contract and the implementation contract provides the code. This allows us to change or alter the code by making the proxy of the contract delegate to a different implementation contract.
Then the upgrade involves the following steps –
- Deployment of the new implementation contract
- The proxy updates its implementation address to the new one once the transaction is sent to it
- The client always interacts with the proxy of the contract which never changes its address. This allows the rollout of an upgrade or bug to be fixed without asking the clients to change anything on their end. They continue interacting with the same address as always.
Limitations of smart contract upgrades
All smart contracts can be upgradable but some limitations of the Solidity language need to be worked around. These issues with Solidity language come up while writing the initial version of the contract as well as the version it is upgraded to.
Due to the technical limitations of Solidity, when a contract is upgraded to its new version the storage layout of the contract cannot be changed. This means that if a state has been declared variable in the contract it cannot be removed, its type changed or another variable declared before it.
This limitation only affects the state variables and thus the contract’s functions and events can be changed easily.
We have observed that the smart contracts deployed on the Ethereum blockchain are immutable and thus not upgradeable. However, the code of the smart contracts can be rearchitected into different contracts. This allows for upgrades in logic while the storage remains the same.
Upgradeable smart contracts have become a desirable and necessary design practice in today’s important and ever-changing landscape for smart contract security.