Coding Upgradable Smart Contracts
What is upgrading Smart Contracts meant for?
As Developers, we always wanted to upgrade our code to introduce new features and fixing bugs too. talking about blockchain, whatever is written on blockchain is immutable. even Smart contracts, once deployed on blockchain network we can’t alter or modify it. in the past few years, we have seen many attacks like DAO, Re-entrancy attacks, Parity Wallet hacks caused a loss of millions of ether only because of small bugs in smart contracts. So testing smart contracts tens of times before deploying is very essential to avoid these vulnerabilities. What if, we wanted to introduce new features to our deployed smart contract? since it is not even possible with blockchain, Right? but somehow, there is a way to upgrade our contracts. how? “A way of Upgrading without actually upgrading.” seems funny? yeah give me a minute, you might be aware of Call diversion feature in your Smartphone, once call diversion is activated for your mobile number with your preferred new number, every call that comes to your mobile number will be diverted to your preferred mobile number. in the same way, an upgradeable contract works. your old contract handles the data and redirects every function call that comes to your old contract address to the newly deployed contract ie.. an upgraded one.
for good reason, gochain provides a CLI protocol to Upgrading contracts. So what are you waiting for? let's go.
In the demonstration, I’m gonna upgrade the simple greeter contract from v1 to v2 .in the version v1, there is no getter method to return greeting. in v2, getter method is added as a bug fix or new feature whatever you call it is. code available here.
Environment
Ubuntu Desktop With gochain web3 library.
Pre-Requisites
1.gochain Web3 library
curl -LSs https://raw.githubusercontent.com/gochain-io/web3/master/install.sh | sh
2. Gochain wallet and some GO-tokens.
Go to https://explorer.gochain.io/wallet/create and store your privatekey somewhere else safe.
For doing any operations on network, you need tokens. so inorder to get testnet tokens, join their official telegram channel https://t.me/gochain_testnet and ask them to provide some testnet tokens by pasting your previously created wallet address**
Steps
1. Environment Setup
a). Export private key to your Env. variables (require root user privileges )
sudo -s
export WEB3_PRIVATE_KEY=0x...
Check if your private key is correct by this command $ web3 myaddress
if this command returns the wallet address that you created as in pre-requisites, then you are good to go.
b). Use the Go-Chain testnet
$ export WEB3_NETWORK=testnet
2. Deploying an Upgradeable Contract
a). Compiling Contract
copy greeter.sol file to your directory, then
web3 contract build greeter.sol
b). Deploying contract
web3 contract deploy --upgradeable greeter.bin
Once deployed, you will get contract address, add this address to env. variables
export WEB3_ADDRESS=0x...
Deploying upgradable contract actually deploy two contracts. original greeter contract and proxy contract which will redirect calls to upgraded contract. check where our proxy contract redirecting calls and storage with this command
web3 contract target
c). Writing Transaction (Greeting)
web3 contract call --abi greeter.abi --function greet "Hi Guys, This is from Old Contract"
Once transaction went through, we successfully added greeting on blockchain. but still, there is no option to return the added greeting. thats why we are trying to upgrade contract with the new code.
3. Upgrading Contract
Copy greeterv2.sol to your directory and then,
web3 contract build greeterv2.sol
web3 contract deploy greeter.bin
Once deployed, it will return the newly deployed contract address. using this address we can upgrade our old contract greeter
to greeterv2.
run below command to finish one last step
web3 contract upgrade --to 0x.... //add your newly deployed contract address here
Now you can call a new contract with the same address. in the old contract, there is no getter function for variable, in the new contract, we added getter function getGreeting
. now you can call it using this command.
web3 contract call --abi greeter.abi --function getGreeting>Hi Guys, This is from Old Contract
4. Pausing and Resuming Contracts
Upgradeable contracts also include the ability to pause & resume execution. if you found any bug in contract you can simply pause (or resume later) the contract with these commands
web3 contract pause
web3 contract resume
Once paused, if you call the function you will get unmarshalling empty output
string till you resume contract.
BOOM…