<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Viral Sangani</title>
    <description>The latest articles on DEV Community by Viral Sangani (@viralsangani).</description>
    <link>https://dev.to/viralsangani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F395129%2Fbd295f79-c675-490b-8a06-720bc683c5f8.png</url>
      <title>DEV Community: Viral Sangani</title>
      <link>https://dev.to/viralsangani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viralsangani"/>
    <language>en</language>
    <item>
      <title>How to create an upgradeable smart contract in Celo</title>
      <dc:creator>Viral Sangani</dc:creator>
      <pubDate>Mon, 25 Jul 2022 10:41:00 +0000</pubDate>
      <link>https://dev.to/celo/how-to-create-an-upgradeable-smart-contract-in-celo-11ee</link>
      <guid>https://dev.to/celo/how-to-create-an-upgradeable-smart-contract-in-celo-11ee</guid>
      <description>&lt;h2&gt;
  
  
  What are upgradeable smart contracts?
&lt;/h2&gt;

&lt;p&gt;Usually, when we deploy a smart contract, it’s impossible to update or change the code since it’s on-chain, and that’s how it should be. This increases the safety and trust of users who interact with that contact.&lt;/p&gt;

&lt;p&gt;But there might be cases where you want to upgrade your smart contract, like fixing severe bugs and adding some critical features for the users. Traditionally doing this is not possible. The best one can deploy is a new smart contract with bug fixes with all the information migrated. This does not end here; one must update the references where the old contract address was used and inform existing users to use the new contract.&lt;/p&gt;

&lt;p&gt;This can be overwhelming, but there is a way to handle these cases by using Upgradeable contracts. An upgradeable smart contract can be updated and edited after the deployment. This can be achieved by a plugin/tool created by &lt;a href="https://www.openzeppelin.com/" rel="noopener noreferrer"&gt;OpenZeppelin&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  In a nutshell
&lt;/h3&gt;

&lt;p&gt;The plugin is used to deploy the contracts on &lt;a href="https://hardhat.org/" rel="noopener noreferrer"&gt;Hardhat&lt;/a&gt; or &lt;a href="https://trufflesuite.com/" rel="noopener noreferrer"&gt;truffle&lt;/a&gt;. Whenever in the future you wish to upgrade the smart contract, use the same address that you used to deploy the first contract via the plugin, and the plugin will handle the transferring of any state and data from the old contract while keeping the same contract address to interact with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rcyym8drmsh3ksqy2vl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rcyym8drmsh3ksqy2vl.png" alt="Proxy patter diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenZeppelin uses a proxy pattern where they deploy three smart contracts to manage the storage layer and implement smart contracts. Whenever a contract call is invoked, the user indirectly calls the proxy contract, and the proxy contract passes the parameters to the implemented smart contract before sending the output back to the user. Now since we have a proxy contract as a middle man, imagine how you want to change something in your implemented contract. All you have to do is deploy the new contract and tell your proxy contract to refer to the latest smart contract, and voila. All users are using the updated contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do upgradeable contracts work?
&lt;/h2&gt;

&lt;p&gt;When we use OpenZeppelin’s upgradeable plugin to deploy the contract, three contracts are deployed —&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implemented Contract&lt;/strong&gt; — The contract the developers create which contains all the logic and functionalities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy Contract&lt;/strong&gt; — The contract that the end-user interacts with. All the data and state of the contract are stored in the context of the Proxy contract. This Proxy Contract is an implementation of the &lt;a href="https://eips.ethereum.org/EIPS/eip-1967" rel="noopener noreferrer"&gt;EIP1967 standard&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ProxyAdmin Contract&lt;/strong&gt; — This contract links the Proxy and Implementation contract.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is ProxyAdmin? (According to OpenZeppelin docs)&lt;/strong&gt;&lt;br&gt;
A ProxyAdmin is a contract that acts as the owner of all your proxies. Only one per network gets deployed. When you start your project, the ProxyAdmin is owned by the deployer address, but you can transfer ownership of it by calling transferOwnership.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When a user calls the proxy contract, the call is &lt;a href="https://docs.soliditylang.org/en/v0.8.12/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries" rel="noopener noreferrer"&gt;delegated&lt;/a&gt; to the implementation contract. Now to upgrade the contract, what we have to do is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the updated Implementation Contract.&lt;/li&gt;
&lt;li&gt;Updating the ProxyAdmin so that all the calls are redirected to the newly implemented contract.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;OpenZeppelin has created a plugin for Hardhat and Truffle to handle these jobs for us. Let’s see step by step how to create and test the upgradeable contracts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing upgradeable smart contracts
&lt;/h3&gt;

&lt;p&gt;We will be using Hardhat’s localhost to test the contract locally and Celo Alfajores test network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialize project and install dependencies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;upgradeable-contract &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;upgradeable-contract
yarn init &lt;span class="nt"&gt;-y&lt;/span&gt;
yarn add hardhat
yarn hardhat // choose typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add plugin and update &lt;code&gt;hardhat.config.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @openzeppelin/hardhat-upgrades
// hardhat.config.ts
import &lt;span class="s1"&gt;'@openzeppelin/hardhat-upgrades'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand the flow, we will be using &lt;code&gt;Greeter.sol&lt;/code&gt; a contract. We will create and deploy several versions of this contract.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Greeter.sol&lt;/li&gt;
&lt;li&gt;GreeterV2.sol&lt;/li&gt;
&lt;li&gt;GreeterV3.sol&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; — The big difference between a normal contract and an upgradeable smart contract is upgradeable smart contracts do not have a constructor.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//contracts/Greeter.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
contract Greeter {
    string public greeting;
    // Emitted when the stored value changes
    event ValueChanged(string newValue);
    function greet() public view returns (string memory) {
        return greeting;
    }
    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
        emit ValueChanged(_greeting);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very simple Greeter contract that returns the value of &lt;code&gt;greeting&lt;/code&gt; whenever we call &lt;code&gt;greet()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Unit testing for &lt;code&gt;Greeter.sol&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;1.Greeter.test.ts&lt;/code&gt; and add the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/1.Greeter.test.ts
import { expect } from "chai";
import { Contract } from "ethers";
import { ethers } from "hardhat";
describe("Greeter", function () {
  let greeter: Contract;
beforeEach(async function () {
    const Greeter = await ethers.getContractFactory("Greeter");
    greeter = await Greeter.deploy();
    await greeter.deployed();
  });
it("should greet correctly before and after changing value", async function () {
    await greeter.setGreeting("Celo to the Moon");
    expect(await greeter.greet()).to.equal("Celo to the Moon");
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat &lt;span class="nb"&gt;test test&lt;/span&gt;/1.Greeter.test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Greeter
    ✔ should greet correctly before and after changing value
1 passing (334ms)
✨  Done in 1.73s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s write a deploy script and deploy &lt;code&gt;Greeter.sol&lt;/code&gt; it to Hardhat’s local node. Create a file named &lt;code&gt;Greeter.deploy.ts&lt;/code&gt; in &lt;code&gt;scripts&lt;/code&gt; directory and paste the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/Greeter.deploy.ts
import { ethers, upgrades } from "hardhat";
async function main() {
  const Greeter = await ethers.getContractFactory("Greeter");
  console.log("Deploying Greeter...");
  const greeter = await upgrades.deployProxy(Greeter);
console.log(greeter.address, " greeter(proxy) address");
  console.log(
    await upgrades.erc1967.getImplementationAddress(greeter.address),
    " getImplementationAddress"
  );
  console.log(
    await upgrades.erc1967.getAdminAddress(greeter.address),
    " getAdminAddress"
  );
}
main().catch((error) =&amp;gt; {
  console.error(error);
  process.exitCode = 1;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the local node and deploy the &lt;code&gt;Greeter.sol&lt;/code&gt; contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat node
yarn hardhat run scripts/Greeter.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploying Greeter...
0x9A676e781A523b5d0C0e43731313A708CB607508  greeter(proxy) address
0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0  getImplementationAddress
0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82  getAdminAddress
✨  Done in 2.74s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you run the deployment command several times you can notice that adminAddress does not change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we need to implement the &lt;code&gt;increment&lt;/code&gt; feature in the existing contract. Instead of replacing the current contract we will create a new contract and change the proxy to refer to the new contract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating &lt;code&gt;GreeterV2.sol&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/GreeterV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Greeter.sol";
contract GreeterV2 is Greeter {
    uint256 public counter;
    // Increments the counter value by 1
    function increment() public {
        counter++;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Writing unit tests for GreeterV2 before deploying.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BigNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter V2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;greeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should retrieve value previously stored&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Celo to the Moon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Celo to the Moon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should increment value correctly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BigNumber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BigNumber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat &lt;span class="nb"&gt;test test&lt;/span&gt;/2.GreeterV2.test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Greeter V2
    ✔ should retrieve value previously stored
    ✔ should increment value correctly
2 passing (442ms)
✨  Done in 6.43s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above test was designed to only test &lt;code&gt;GreeterV2.sol&lt;/code&gt; not the upgraded version of &lt;code&gt;Greeter.sol&lt;/code&gt;. Let’s write and deploy the &lt;code&gt;GreeterV2&lt;/code&gt; in proxy patter and test if &lt;code&gt;GreeterV2&lt;/code&gt; works correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test/3.GreeterV2Proxy.test.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter (proxy) V2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// setting the greet value so that it can be checked after upgrade&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WAGMI&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;greeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should retrieve value previously stored correctly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WAGMI&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Celo to the Moon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Celo to the Moon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are setting the &lt;code&gt;greeting&lt;/code&gt; value to &lt;strong&gt;WAGMI&lt;/strong&gt; in &lt;code&gt;Greeter&lt;/code&gt; (V1) and after upgrading, checking the &lt;code&gt;greeting&lt;/code&gt; value in &lt;code&gt;GreeterV2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run the test —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat &lt;span class="nb"&gt;test test&lt;/span&gt;/3.GreeterV2Proxy.test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Greeter (proxy) V2
    ✔ should retrieve value previously stored correctly
1 passing (521ms)
✨  Done in 6.45s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Writing a script to update &lt;code&gt;Greeter&lt;/code&gt; to &lt;code&gt;GreeterV2&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note that the greeter proxy address is &lt;code&gt;0x9A676e781A523b5d0C0e43731313A708CB607508&lt;/code&gt; that we got when we deployed &lt;code&gt;Greeter.sol&lt;/code&gt;. We need a proxy address to deploy &lt;code&gt;GreeterV2.sol&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;GreeterV2.deploy.ts&lt;/code&gt; and add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// scripts/2.upgradeV2.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x9A676e781A523b5d0C0e43731313A708CB607508&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; original Greeter(proxy) address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;upgrade to GreeterV2...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; GreeterV2 address(should be the same)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;erc1967&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getImplementationAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; getImplementationAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;erc1967&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAdminAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; getAdminAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Running deployment script for &lt;code&gt;GreeterV2.sol&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We need to start from the beginning, i.e., deploy Greeter.sol first, get the proxy address, and use that to deploy &lt;code&gt;GreeterV2.sol&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat node
yarn hardhat run scripts/Greeter.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we got &lt;code&gt;0x9A676e781A523b5d0C0e43731313A708CB607508&lt;/code&gt; as a proxy address. (Update the proxy address in &lt;code&gt;scripts/GreeterV2.deploy.ts&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat run scripts/GreeterV2.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x9A676e781A523b5d0C0e43731313A708CB607508  original Greeter(proxy) address
upgrade to GreeterV2...
0x9A676e781A523b5d0C0e43731313A708CB607508  GreeterV2 address(should be the same)
0x0B306BF915C4d645ff596e518fAf3F9669b97016  getImplementationAddress
0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82  getAdminAddress
✨  Done in 2.67s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Overriding the existing methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let’s say you want to add a custom name field in with the greeting such that when &lt;code&gt;greet()&lt;/code&gt; is called, the name is added to the returned string.&lt;/p&gt;

&lt;p&gt;Create a new file called &lt;code&gt;GreeterV3.sol&lt;/code&gt; in &lt;code&gt;contracts&lt;/code&gt; directory and add the following code —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/GreeterV3.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./GreeterV2.sol";
contract GreeterV3 is GreeterV2 {
    string public name;
    function setName(string memory _name) public {
        name = _name;
    }
    function greet() public view override returns (string memory) {
        return string(abi.encodePacked(greeting, " ", name));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s write test cases to deploy and test &lt;code&gt;GreeterV3&lt;/code&gt; . Create a file called &lt;code&gt;4.GreeterV3Proxy.test.ts&lt;/code&gt; and add the following test cases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test/.GreeterV3Proxy.test.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BigNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter (proxy) V3 with name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// setting the greet value so that it can be checked after upgrade&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WAGMI&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;greeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;greeterV3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should retrieve value previously stored and increment correctly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WAGMI &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BigNumber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BigNumber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should set name correctly in V3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Viral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`WAGMI &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note 1&lt;/strong&gt; — Since all the data and state is stored in Proxy contract you can see in the test cases that we are calling &lt;code&gt;increment()&lt;/code&gt; method in &lt;code&gt;GreeterV2&lt;/code&gt; and checking if the value is incremented or not in &lt;code&gt;GreeterV3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt; — Since in our &lt;code&gt;GreeterV3.sol&lt;/code&gt; the contract, we have added space and name to the &lt;code&gt;greeting&lt;/code&gt; If the name is null, then the &lt;code&gt;greet&lt;/code&gt; the call will return the &lt;code&gt;greeting&lt;/code&gt; with an extra space appended to it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run the tests —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat &lt;span class="nb"&gt;test test&lt;/span&gt;/4.GreeterV3Proxy.test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Greeter (proxy) V3 with name
    ✔ should retrieve value previously stored and increment correctly
    ✔ should set name correctly in V3
2 passing (675ms)
✨  Done in 2.38s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deployment script for GreeterV3.sol&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;GreeterV3.deploy.ts&lt;/code&gt; in &lt;code&gt;scripts&lt;/code&gt; and paste the following code —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// scripts/3.upgradeV3.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; original Greeter(proxy) address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;upgrade to GreeterV3...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; GreeterV3 address(should be the same)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;erc1967&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getImplementationAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; getImplementationAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;erc1967&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAdminAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; getAdminAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deploy the &lt;code&gt;GreeterV3&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat run scripts/GreeterV3.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note —&lt;/strong&gt; If you get “Error: Proxy admin is not the one registered in the network manifest” when you try to deploy &lt;code&gt;GreeterV3&lt;/code&gt;, you need to run &lt;code&gt;Greeter.deploy.ts&lt;/code&gt; and &lt;code&gt;GreeterV2.deploy.ts&lt;/code&gt; again and copy the new proxy address to be used to deploy the upgraded contracts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1  original Greeter(proxy) address
upgrade to GreeterV3...
0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1  GreeterV3 address(should be the same)
0x3Aa5ebB10DC797CAC828524e59A333d0A371443c  getImplementationAddress
0x59b670e9fA9D0A427751Af201D676719a970857b  getAdminAddress
✨  Done in 2.63s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deploying the upgraded contract manually&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s write a new contract — &lt;code&gt;GreeterV4&lt;/code&gt; where we need to —&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the state variable &lt;code&gt;name&lt;/code&gt; from public to private.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;getName&lt;/code&gt; method to fetch &lt;code&gt;name&lt;/code&gt; value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a file called &lt;code&gt;GreeterV4.sol&lt;/code&gt; in &lt;code&gt;contracts&lt;/code&gt; directory and add the following code —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/GreeterV4.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./GreeterV2.sol";
contract GreeterV4 is GreeterV2 {
    string private name;
event NameChanged(string name);
function setName(string memory _name) public {
        name = _name;
    }
function getName() public view returns (string memory) {
        return name;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we need to inherit from &lt;code&gt;GreeterV2&lt;/code&gt; instead of &lt;code&gt;GreeterV3&lt;/code&gt; because &lt;code&gt;GreeterV3&lt;/code&gt; already has a state variable called name and we cannot change the visibility but what we can do is inherit from &lt;code&gt;GreeterV3&lt;/code&gt; which does not have &lt;code&gt;name&lt;/code&gt; variable and set the visibility as we want.&lt;/p&gt;

&lt;p&gt;Let’s write test cases for &lt;code&gt;GreeterV4.sol&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test/5.GreeterV4Proxy.test.ts&lt;/span&gt;
&lt;span class="cm"&gt;/* eslint-disable no-unused-vars */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter (proxy) V4 with getName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeterV4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Greeter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;greeterV2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;greeterV3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;greeterV4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upgradeProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GreeterV4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should setName and getName correctly in V4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greetername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Celo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greetername&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;greeterV4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greetername&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat &lt;span class="nb"&gt;test test&lt;/span&gt;/5.GreeterV4Proxy.test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Greeter (proxy) V4 with getName
    ✔ should setName and getName correctly in V4
1 passing (608ms)
✨  Done in 6.18s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Preparing for the upgrade, but not really upgrading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we call &lt;code&gt;upgrades.upgradeProxy()&lt;/code&gt; there are a couple of things happening —&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your contract is deployed first,&lt;/li&gt;
&lt;li&gt;ProxyAdmin called the &lt;code&gt;upgrade()&lt;/code&gt; method and link the proxy to the newly implemented contract’s address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To do these steps manually, we can call &lt;code&gt;upgrades.prepareUpgrade()&lt;/code&gt; which only deploys your contract but does not link it with the proxy YET. This is left for the developers to link manually. This is useful when you want to test in production before wanting all the users to use the new contract.&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;GreeterV4Prepare.deploy.ts&lt;/code&gt; in &lt;code&gt;scripts&lt;/code&gt; directory and add the following code —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xc5a5C42992dECbae36851359345FE25997F5C42d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; original Greeter(proxy) address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GreeterV4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreeterV4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Preparing upgrade to GreeterV4...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greeterV4Address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;upgrades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepareUpgrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;proxyAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;GreeterV4&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeterV4Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; GreeterV4 implementation contract address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note —&lt;/strong&gt; You might want to run all the deployment scripts again if you face any issues while running this script.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run the script —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat run scripts/GreeterV4Prepare.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xc5a5C42992dECbae36851359345FE25997F5C42d  original Greeter(proxy) address
Preparing upgrade to GreeterV4...
0x9E545E3C0baAB3E08CdfD552C960A1050f373042  GreeterV4 implementation contract address
✨  Done in 2.56s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploying all the contracts to Celo’s Alfajores Network
&lt;/h2&gt;

&lt;p&gt;First, we need to add Alfajores RPC details in &lt;code&gt;hardhat.config.ts&lt;/code&gt;. Refer to this site for the latest RPC details — &lt;a href="https://docs.celo.org/getting-started/wallets/using-metamask-with-celo/manual-setup" rel="noopener noreferrer"&gt;https://docs.celo.org/getting-started/wallets/using-metamask-with-celo/manual-setup&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;alfajores:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;url:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://alfajores-forno.celo-testnet.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;accounts:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;process.env.PRIVATE_KEY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;!==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;undefined&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;process.env.PRIVATE_KEY&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the script and deploy &lt;code&gt;Greeter.sol&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwm6euqx0lxnu65cdam6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwm6euqx0lxnu65cdam6c.png" alt="Three contracts are deployed."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefckym39i2p1zpz1l5le.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefckym39i2p1zpz1l5le.png" alt="Implementation Contract"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffoer2pvnzfshk9wf0r7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffoer2pvnzfshk9wf0r7o.png" alt="Admin Contract"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63pqx4a7uj5ki5mp06fp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63pqx4a7uj5ki5mp06fp.png" alt="Proxy Contract"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For your reference, here are the three deployed contracts —&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0xeE5Dc1234Cdb585F54cc51ec08d67f6f43d0183B&lt;/code&gt; — Implementation Contract&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0xc2E6c44e9eA569C6D1EfF7Ce0229Fb86a4A1d2d1&lt;/code&gt; — ProxyAdmin Contract&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0xd15100A570158b7EEbE196405D8a456d56807F2d&lt;/code&gt; — Proxy Contract&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Upgrade &lt;code&gt;Greeter&lt;/code&gt; to &lt;code&gt;GreeterV2&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command to deploy the &lt;code&gt;GreeterV2&lt;/code&gt;. Make sure before running update the &lt;code&gt;proxyAddress&lt;/code&gt; in &lt;code&gt;GreeterV2.deploy.ts&lt;/code&gt; with your deployed proxy contract address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat run scripts/GreeterV2.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; alfajores
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we called &lt;code&gt;upgrades.upgradeProxy&lt;/code&gt; in the deploy script, it did two things, deployed the new implementation contact and called &lt;code&gt;proxyAdmin.upgrade()&lt;/code&gt; the method to link proxy and new implementation contract.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpw5f1bwfqmluvf0bpwzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpw5f1bwfqmluvf0bpwzw.png" alt="Greeter -&amp;gt; GreeterV2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upgrading &lt;code&gt;GreeterV2&lt;/code&gt; to &lt;code&gt;GreeterV3&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat run scripts/GreeterV3.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; alfajores
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hppwfrco5gkflcbk61z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hppwfrco5gkflcbk61z.png" alt="GreeterV2 -&amp;gt; GreeterV3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upgrading &lt;code&gt;GreeterV3&lt;/code&gt; to &lt;code&gt;GreeterV4&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;GreeterV4Prepare.deploy.ts&lt;/code&gt; we had only called &lt;code&gt;prepareUpgrade&lt;/code&gt; which only deploys the implementation contract. We will use a hardhat console to manually call &lt;code&gt;update()&lt;/code&gt; the method to link the proxy with the implementation contract. Run the following command to deploy the implementation contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat run scripts/GreeterV4Prepare.deploy.ts &lt;span class="nt"&gt;--network&lt;/span&gt; alfajores
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xd15100A570158b7EEbE196405D8a456d56807F2d  original Greeter(proxy) address
Preparing upgrade to GreeterV4...
0x8843F73D7c761D29649d4AC15Ee9501de12981c3  GreeterV4 implementation contract address
✨  Done in 5.81s.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use a hardhat console to link the proxy with the implementation contract. Run the following command to start the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn hardhat console &lt;span class="nt"&gt;--network&lt;/span&gt; alfajores
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For linking, we need two things —&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ProxyAdmin address&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GreeterV4&lt;/code&gt; contract factory instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following commands in the console —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; const GreeterV4 &lt;span class="o"&gt;=&lt;/span&gt; await ethers.getContractFactory&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"GreeterV4"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; await upgrades.upgradeProxy&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0xd15100A570158b7EEbE196405D8a456d56807F2d"&lt;/span&gt;, GreeterV4&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will point the proxy contract to the latest &lt;code&gt;GreeterV4&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Congratulations 💪 on making it to the end. I know this article is a bit long, but now you know how upgradeable smart contracts work under the hood. You have built and deployed proxy contracts in the local testnet and Alfajores testnet. If you have doubts or just fancy saying Hi 👋🏻, you can reach out to me on &lt;a href="https://twitter.com/viral_sangani_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or Discord[0xViral (Celo)#6692].&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.gg/6yWMkgM" rel="noopener noreferrer"&gt;Celo Discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/CeloOrg" rel="noopener noreferrer"&gt;Celo Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web3</category>
      <category>solidity</category>
      <category>celo</category>
    </item>
    <item>
      <title>Polygon explained without jargon</title>
      <dc:creator>Viral Sangani</dc:creator>
      <pubDate>Thu, 30 Sep 2021 00:13:44 +0000</pubDate>
      <link>https://dev.to/viralsangani/polygon-explained-without-jargon-2dj3</link>
      <guid>https://dev.to/viralsangani/polygon-explained-without-jargon-2dj3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6ul8BW6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npx7xjjpe2qljakvda11.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ul8BW6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npx7xjjpe2qljakvda11.jpg" alt="Polygon Explained"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;We will learn what Polygon (aka Matic) is, what it does, how it does it, and what makes it a better alternative to Etherium. In short, I will try to explain the Polygon blockchain without any jargon in the most straightforward manner possible.&lt;/p&gt;

&lt;p&gt;Before understanding Polygon, it's essential to understand Ethereum and the problems we are facing with Ethereum. &lt;/p&gt;

&lt;h2&gt;
  
  
  An intro to Ethereum
&lt;/h2&gt;

&lt;p&gt;In simplest terms, &lt;strong&gt;Ethereum is a system that enforces property rights&lt;/strong&gt;. Ethereum introduced an &lt;a href="https://www.merriam-webster.com/dictionary/axiom"&gt;axiom&lt;/a&gt; - &lt;strong&gt;Code is Law&lt;/strong&gt;. This idea is to create a law that can be translated into a simple mathematical equation - &lt;strong&gt;If X, then Y&lt;/strong&gt;. For example - If you break traffic rules, you pay Y amount of fine. If you give X amount of collateral, you can borrow Y amount of money. These examples are real-world scenarios, and Ethereum provides us a way to enforce these rules on the internet with a feature called Smart Contracts. Smart contracts essentially are Ethereums way of implementing &lt;strong&gt;If X, then Y&lt;/strong&gt; law. These contracts are a piece of code that will automatically execute when a specific condition meets. &lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Ethereum
&lt;/h2&gt;

&lt;p&gt;Ethereum was founded in 2013, and since then, it has attracted an enormous number of developers and investors. As we all know, with great attention comes significant responsibilities. As of writing this, 361 Billion dollars are locked in Ethereum, and around 1.2 Million transactions are happing in 1 day. Because of this much amount of traffic, the Ethereum network is getting congested. As more and more people onboard Ethereum and start using it, the Ethereum network gets slow, due to which the cost of using the network is increasing. Due to congestion on the network, the cost of a single transaction on Ethereum was around $100 in early 2021. Ethereum can solve these issues but at the expense of security. &lt;/p&gt;

&lt;p&gt;Polygon is trying to solve all these problems and retaining the high security of Ethereum.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Polygon
&lt;/h1&gt;

&lt;p&gt;Polygon is a solution to all Ethereum problems. Polygon blockchain is connected to Ethereum blockchain and is taking heavy work off Ethereum. Think of Ethereum as National Highway and Polygon as service roads or connecting roads that lead to different cities and states. Many people live in cities, and they cause a lot of traffic on the road; city roads can handle this traffic, and once the traffic gets cleared, people can quickly join the main Highway using connecting roads. &lt;/p&gt;

&lt;p&gt;There is no need for Ethereum to handle so many transactions; if some other blockchain(Polygon) can handle those transactions, bundle them up, and update those transactions on Ethereum, then Ethereum would have less congestion and work more efficiently.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Polygon Analogy
&lt;/h1&gt;

&lt;p&gt;Assume Ethereum is a metropolitan city, like New York, and Polygon is the suburbs of New York City. Suburbs has their own things going on. They have their restaurants, buildings, markets, malls, and police, and people can constantly communicate with the city. Certainly, suburbs are not as secure as cities, but it's easy to communicate within suburbs, and suburbs are comparatively cheaper than cities. Suburbs have their government authorities and their security forces moreover can interact with the city for more security. &lt;/p&gt;

&lt;p&gt;Similarly, Polygon has its own token, its own smart contracts, its own governance, and its own security and can communicate with Ethereum and rely on its security as well.&lt;/p&gt;

&lt;p&gt;Since Polygon is running parallelly with Ethereum, its also referred to as a &lt;strong&gt;side chain&lt;/strong&gt;. Considering that Polygon is connected with Ethereum, all the transactions on Polygon will eventually be written on to Etherum. With Polygon, developers can create decentralized applications without worrying about transaction fees.&lt;/p&gt;

&lt;p&gt;All in all, Polygon did resolve most of the issues that Ethereum currently has. Considering that only 65% of the earth's population has access to the internet and Web3 is still adopting, Polygon has a lot of room to grow in the future.&lt;/p&gt;

</description>
      <category>blockchain</category>
    </item>
    <item>
      <title>Getting started with weird parts of VIM</title>
      <dc:creator>Viral Sangani</dc:creator>
      <pubDate>Thu, 02 Jul 2020 08:04:28 +0000</pubDate>
      <link>https://dev.to/viralsangani/getting-started-with-weird-parts-of-vim-part-2-pg6</link>
      <guid>https://dev.to/viralsangani/getting-started-with-weird-parts-of-vim-part-2-pg6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was originally posted on - &lt;a href="https://blog.viralsangani.me/posts/getting-started-with-weird-parts-of-vim/"&gt;https://blog.viralsangani.me/posts/getting-started-with-weird-parts-of-vim/&lt;/a&gt;&lt;br&gt;
You can read more blogs at - &lt;a href="https://blog.viralsangani.me/"&gt;https://blog.viralsangani.me/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are new to VIM, you might want to read my &lt;a href="https://blog.viralsangani.me/posts/vim-is-tough-or-is-it/"&gt;previous post&lt;/a&gt; on VIM. This is the 2nd part of the five-part series on VIM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5lubc2nh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/obwgxetrm7l6bmsq53gk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5lubc2nh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/obwgxetrm7l6bmsq53gk.png" alt="Vim Joke" width="500" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Taste of VIM Editor
&lt;/h3&gt;

&lt;p&gt;Those who are not a regular VIM user, they might use some normal text editor like, VSCode, Atom, Sublime, etc.. (unless you are some freak using &lt;code&gt;emacs&lt;/code&gt;), and the main aim of those normal text editor is to insert the text, and that's what they are made for. I don't know about others but 75% of my time while coding and programming I tend to edit the code rather than inserting the code. That's what most developers do, they write the code once, then they spend most of the time editing and customizing that code. Now, when it comes to VIM, VIM is not like other text editors whose main aim is to insert the code, rather VIM focuses more on the editing part. With vim, you can edit the code like a wizard.&lt;br&gt;
For example, let's say you want to make similar changes in 15 lines of a file. If you are using a normal text edit, you scroll the mouse, find each line, and make the change. But with VIM, you make the change in one line, and VIM remembers it, then all you have to do is press &lt;code&gt;.&lt;/code&gt; (period), and VIM repeats its last set on command and BAMM, you get the changes in another line with just a keystroke. But it's hard to write commands which work well with &lt;code&gt;.&lt;/code&gt; but you can learn it with some practice.&lt;/p&gt;

&lt;p&gt;Let's starts with some basics and build our way up.&lt;/p&gt;

&lt;p&gt;First thing first, if you are stuck anywhere in VIM, just call for &lt;code&gt;: help&lt;/code&gt; and help will come for rescue. VIM's &lt;code&gt;: help&lt;/code&gt; command is very well documented. Get help with &lt;code&gt;:help {whatever}&lt;/code&gt; or with a shorter version &lt;code&gt;:h {whatever}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;-&amp;gt; With vim, you don't have to move your hand to arrow keys to move around a file, you can simply use, letters &lt;code&gt;hjkl&lt;/code&gt;. When you type on a keyboard, your hand rests firmly on these keys, hence it's a faster way to move around a file.&lt;br&gt;
These keys move the cursor left, down, up, and right respectively.&lt;/p&gt;

&lt;p&gt;You can also move left to right by words with &lt;code&gt;w&lt;/code&gt; (goto starting of the word) or &lt;code&gt;e&lt;/code&gt; (goto end of the word). you can use &lt;code&gt;b&lt;/code&gt; to do the same but in right to left direction.&lt;/p&gt;

&lt;p&gt;In the world of VIM, with great keys comes great power. In normal mode, just type &lt;code&gt;daw&lt;/code&gt; and you just deleted a word, press &lt;code&gt;das&lt;/code&gt; and you deleted a sentence, press &lt;code&gt;dap&lt;/code&gt; and you just deleted a whole paragraph with 3 keystrokes.&lt;/p&gt;

&lt;p&gt;Or you can be less of a devil who deletes stuff and can use &lt;code&gt;caw&lt;/code&gt;, &lt;code&gt;cas&lt;/code&gt;, or &lt;code&gt;cap&lt;/code&gt; to change a word, sentence, or a paragraph. It's not the end, you can type &lt;code&gt;ctb&lt;/code&gt; to change until first &lt;code&gt;b&lt;/code&gt; in the current line, or use &lt;code&gt;c$&lt;/code&gt; to change everything till the end of the line. You can use &lt;code&gt;ci{&lt;/code&gt; to change the text between curly brackets or use &lt;code&gt;ci"&lt;/code&gt; to change content between quotes.&lt;/p&gt;

&lt;p&gt;Let's see an example, imagine you have a variable in python,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello World"&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"How you doing?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can change the text between those quotes with &lt;code&gt;f"ci"WHAT&amp;lt;ESC&amp;gt;&lt;/code&gt;. By typing this you'll get this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WHAT"&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"How you doing?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, VIM remembers your last command, so if you press &lt;code&gt;j.&lt;/code&gt;, you'll get,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WHAT"&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WHAT"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WQvxEEjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5apc98xz2tv1vl0soafk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WQvxEEjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5apc98xz2tv1vl0soafk.gif" alt="Whattt" width="430" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's break down these commands, in 1st one &lt;code&gt;f"&lt;/code&gt; finds the &lt;code&gt;"&lt;/code&gt;, then &lt;code&gt;ci"&lt;/code&gt; change the content between those quotes and put you in insert mode, with &lt;code&gt;WHAT&amp;lt;ESC&amp;gt;&lt;/code&gt;, it inserts the WHAT word and &lt;code&gt;&amp;lt;ESC&amp;gt;&lt;/code&gt; put you back in normal mode.&lt;/p&gt;

&lt;p&gt;In 2nd command, &lt;code&gt;j&lt;/code&gt; put your cursor down one line, and &lt;code&gt;.&lt;/code&gt; repeats your last command, which was to change content between quotes and insert &lt;code&gt;WHAT&lt;/code&gt; in between.&lt;/p&gt;

&lt;p&gt;With VIM you can copy the content in the same way, but in VIM copy is called yank. It's just a jargon VIM people use.&lt;br&gt;
So now, just like delete use &lt;code&gt;d&lt;/code&gt;, change use &lt;code&gt;c&lt;/code&gt;, you can use &lt;code&gt;y&lt;/code&gt; to yank the content. To yank a word press &lt;code&gt;yaw&lt;/code&gt;, to yank a sentence press &lt;code&gt;yas&lt;/code&gt; and to yank a paragraph press &lt;code&gt;yap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To make it simple you can press &lt;code&gt;dd&lt;/code&gt; to delete your present line, press &lt;code&gt;cc&lt;/code&gt; to change current line, and press &lt;code&gt;yy&lt;/code&gt; to yank your current line.&lt;/p&gt;

&lt;p&gt;With the power of these commands, you can do a lot more, like the previous example, you can press &lt;code&gt;kJ&lt;/code&gt;, and you'll get this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WHAT"&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WHAT"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and now press &lt;code&gt;c3w+&amp;lt;ESC&amp;gt;&lt;/code&gt;, you'll get something like this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WHAT"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"WHAT"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not at all useful examples, but hey you get the idea of what you can do in VIM.&lt;br&gt;
In the previous example, I have used &lt;code&gt;count {3}&lt;/code&gt; to get the longer motion. For example, if you want to go 13 lines up, press &lt;code&gt;13k&lt;/code&gt;. It follows a syntax &lt;code&gt;{count}{command}&lt;/code&gt;, which means you can add the count to any command, even to &lt;code&gt;.&lt;/code&gt; which is a repeater command, so if you press &lt;code&gt;10.&lt;/code&gt;, it will run the last command 10 times.&lt;/p&gt;

&lt;p&gt;One thing you will miss most in VIM is the freedom to navigate freely with a mouse scroll. You don't want to be that person who presses &lt;code&gt;j&lt;/code&gt; 30 times to reach the desired line. But hey, VIM has way around for that too, press &lt;code&gt;D&lt;/code&gt; to move a few lines down at a time and press &lt;code&gt;U&lt;/code&gt; to move a few lines up, that ease up the pain of pressing the same key multiple times. You can even you &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt; for a paragraph up or down respectively. If you are coding you can use &lt;code&gt;%&lt;/code&gt; to find the matching ending parentheses.&lt;/p&gt;

&lt;p&gt;You can enter insert mode by pressing &lt;code&gt;i&lt;/code&gt;, if you want to insert in the new line, press &lt;code&gt;o&lt;/code&gt;, and if you want new above the current line press &lt;code&gt;O&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My favorite command id &lt;code&gt;/&lt;/code&gt;, you can use &lt;code&gt;/{patter}&lt;/code&gt;, to move to any place in the document you want. Once you find your matching patter, press &lt;code&gt;n&lt;/code&gt; to find the next matching pattern.&lt;/p&gt;

&lt;p&gt;So much at your fingertip, and you have barely left normal mode. There is much much more like there are splits, there's a regex, there are tabs, there's is access to hundreds of community-based extensions for VIM, there is spell checking, word count, file tree, everything coming in next posts. So excited?&lt;/p&gt;

&lt;p&gt;One last thing, you might be thinking, how can someone remember so many commands there is &lt;code&gt;caw&lt;/code&gt; there is &lt;code&gt;ciw&lt;/code&gt;, &lt;code&gt;10j&lt;/code&gt;, &lt;code&gt;dd&lt;/code&gt; &lt;code&gt;d3w&lt;/code&gt;, etc.. See that's the beauty of VIM, you don't have to remember it. The operators and command make incredible sense. VIM use mnemonics like &lt;code&gt;c&lt;/code&gt; means change, &lt;code&gt;d&lt;/code&gt; means delete, &lt;code&gt;cl&lt;/code&gt; means change letter, &lt;code&gt;daw&lt;/code&gt; means &lt;strong&gt;d&lt;/strong&gt;elete &lt;strong&gt;a&lt;/strong&gt; &lt;strong&gt;w&lt;/strong&gt;ord, &lt;code&gt;ciw&lt;/code&gt; means &lt;strong&gt;c&lt;/strong&gt;hange &lt;strong&gt;i&lt;/strong&gt;nner &lt;strong&gt;w&lt;/strong&gt;ord. &lt;code&gt;cta&lt;/code&gt; means &lt;strong&gt;c&lt;/strong&gt;hange &lt;strong&gt;t&lt;/strong&gt;ill you find &lt;code&gt;a&lt;/code&gt; and so on.&lt;/p&gt;

&lt;p&gt;VIM is like programming I guess, where you are in control, and change the core mechanism of file editing and writing text. If you are familiar with git and how it works with source control of your project, you can think of VIM as a git of text editing. Once you have experience with VIM, you will no longer see the text as normal text, you will see the text as an infinite number of possibilities to change that text being applied just like Neo awakening to the matrix. (Got that ref?? let me know in the comment...)&lt;/p&gt;

&lt;p&gt;To learn more about vim, you can watch this really awesome &lt;a href="https://www.youtube.com/watch?v=wlR5gYd6um0"&gt;talk&lt;/a&gt; by Chris Toomey. In the talk, he explained how to think in VIM language and do all those crazy stuff more efficiently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h4ckgcbc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qctktj0fxj7v2ar3tv5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h4ckgcbc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qctktj0fxj7v2ar3tv5h.png" alt="Vim Joke" width="500" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I just wanted to end with a Joke. 😇&lt;/p&gt;

</description>
      <category>vim</category>
      <category>linux</category>
      <category>ubuntu</category>
      <category>vscode</category>
    </item>
    <item>
      <title>VIM is tough, or is it???</title>
      <dc:creator>Viral Sangani</dc:creator>
      <pubDate>Tue, 09 Jun 2020 17:08:09 +0000</pubDate>
      <link>https://dev.to/viralsangani/vim-is-tough-or-is-it-51f</link>
      <guid>https://dev.to/viralsangani/vim-is-tough-or-is-it-51f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This post was originally posted on - &lt;a href="https://blog.viralsangani.me/posts/vim-is-tough-or-is-it/" rel="noopener noreferrer"&gt;https://blog.viralsangani.me/posts/vim-is-tough-or-is-it/&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;You can read more blogs at - &lt;a href="https://blog.viralsangani.me/" rel="noopener noreferrer"&gt;https://blog.viralsangani.me/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the past, I am stuck with this idea of making more with less, in the context of refactoring the line of code in the most efficient way possible. Recently I am exploring the use of VIM to &lt;a href="https://www.youtube.com/watch?v=kNS4t5UCBfI" rel="noopener noreferrer"&gt;unleash unlimited power&lt;/a&gt; of a text editor. VIM enables me to achieve more with every keystroke and with every hour I invest in programming.&lt;/p&gt;

&lt;p&gt;This is the 1st part of the five-part series on VIM.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Let's talk about &lt;a href="https://www.vim.org/" rel="noopener noreferrer"&gt;VIM&lt;/a&gt;.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;VIM is a text editor who has a keyboard-centric design, unlike other text editors. VIM promises ultimate productivity to those who dare to face its steep learning curve and survive till the end to tell the tale.&lt;/p&gt;

&lt;p&gt;I have been learning VIM for the past 2 months. To be honest, it was tough for the first week, but if you make it through the first week, trust me it's worth it. My first encounter with VIM was a year ago, when I saw my brother typing a bunch of command in vim to do some editing in one line and then he played the recorded command 100 times, and BOOM, 100 lines of code were changed with just a keystroke. That was fascinating. Since then I tried to use VIM as my primary text editor, but just because of the steep learning curve, I always gave up. But a couple of months ago, I came up with this &lt;a href="https://www.youtube.com/playlist?list=PL8tzorAO7s0jy7DQ3Q0FwF3BnXGQnDirs" rel="noopener noreferrer"&gt;YouTube playlist&lt;/a&gt; by &lt;a href="https://www.youtube.com/channel/UCUR1pFG_3XoZn3JNKjulqZg" rel="noopener noreferrer"&gt;ThoughtBot&lt;/a&gt;. When I suggest someone to use VIM, their first question is CAN IT DO THIS.... And the answer is YES. Just go through this playlist and all your questions will be answered.&lt;/p&gt;

&lt;p&gt;Till this time, I haven't used 50% of the functionalities VIM offers, or that know about. However, I never completely shifted to VIM, instead, I use VIM extension for popular text editors like VSCode or PyCharm, etc. This will give you the flavor of both. You have you VSCode shortcuts + the power of VIM at your fingertip. Although using VIM with other text editors is not as good as the real thing, but for beginners, this is the best bet to get used to VIM quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Answering, what is VIM?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Vi" rel="noopener noreferrer"&gt;VI&lt;/a&gt; is the ancient text editor created in 1976. The main purpose of creating VI is to make a text editor that works perfectly on a terminal. Later came the VIM(Vi IMproved) which has support for both text and graphical interfaces. It comes as the improved version of VI which technically supports all the operating systems known to mankind.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why VIM but?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You might be thinking why should I care about some ancient text editor in 2020? VIM is a text editor that provides a different method of writing code. If text editors are compared to planets, VS Code, Sublime, ATOM, Jetbrains, Eclipse all are on the same planet and VIM is a different galaxy. It provides a way to interact with your code as no other editors can.&lt;/p&gt;

&lt;p&gt;Now you might be thinking, what is there for me in learning VIM? See, VIM removes the dependency of MOUSE. Yes no more using a mouse, if you choose to go with VIM. Using VIM will make you a code surgeon. A code surgeon who can make precise code insertion whenever and wherever they want. If you are using one of those text editors other than VIM, you will be using a mouse to navigate in the code. But with VIM you can navigate into your code and codebase with lightning speed just using your keyboard. You don't even have to move your hand from keyboard to mouse. This is what you get from learning VIM, the speed, and the power of changing whatever you want with just a couple of keystrokes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What makes VIM such a great text editor?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are this things called modes in VIM. There are primarily three modes in VIM, Normal Mode, Inset Mode, and Visual Mode. Each mode has it's own significance we will see in further posts. All the keystroke have different functionalities in every mode. For example, &lt;code&gt;d&lt;/code&gt; key is used to delete and copy the text in Normal mode, were as if you are in Inset mode, &lt;code&gt;d&lt;/code&gt; is just the letter &lt;code&gt;d&lt;/code&gt;, which will be typed if you press &lt;code&gt;d&lt;/code&gt; key. This helps VIM to provide more functionalities with limited numbers of keys.&lt;/p&gt;

&lt;p&gt;VIM is extremely customizable. You can change your key binding However it suites you, and whatever works for you. There are no restrictions like many text editors where you can't help it. If you want to copy the selected text by just pressing &lt;code&gt;c&lt;/code&gt;, instead of pressing two keys =&amp;gt;&lt;code&gt;Ctrl+z&lt;/code&gt;, you can in vim, but it might be too hard or not possible in other text editors.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why VIM is hard?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let's goto a darker side of VIM, or at least what some people think.&lt;/p&gt;

&lt;p&gt;Let's see the learning curve of VIM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhuz6riw1gndvcoc4njng.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhuz6riw1gndvcoc4njng.jpg" alt="vim learning curve"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, VIM is consistently hard to learn, because learning never ends in VIM. Every day you google something about VIM, and you'll get some exciting new stuff related to VIM and it's plugins.&lt;/p&gt;

&lt;p&gt;And then comes this,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgzhrvtx1ea9xj1cvv4ts.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgzhrvtx1ea9xj1cvv4ts.jpg" alt="Meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But according to me, what makes VIM sooooo HARD is it's Horrible first impression.&lt;/p&gt;

&lt;p&gt;So in the next few posts, I will try to make leaning VIM not that difficult and providing you basics and resources to learn advanced VIM.&lt;/p&gt;

&lt;p&gt;Just a friendly advice, if you take the courage of learning VIM, don't stop in between, I know it will be painful at the start, but trust me there will come a day when you will be saving hours in a day just by using VIM.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>linux</category>
      <category>ubuntu</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Be anonymous, create your own proxy server with AWS EC2</title>
      <dc:creator>Viral Sangani</dc:creator>
      <pubDate>Tue, 09 Jun 2020 04:19:46 +0000</pubDate>
      <link>https://dev.to/viralsangani/be-anonymous-create-your-own-proxy-server-with-aws-ec2-2k63</link>
      <guid>https://dev.to/viralsangani/be-anonymous-create-your-own-proxy-server-with-aws-ec2-2k63</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was originally posted on &lt;a href="https://blog.viralsangani.me" rel="noopener noreferrer"&gt;https://blog.viralsangani.me&lt;/a&gt;.&lt;br&gt;
Checkout this post at - &lt;a href="https://blog.viralsangani.me/posts/be-anonymous-create-your-own-proxy-server-with-aws-ec2/" rel="noopener noreferrer"&gt;https://blog.viralsangani.me/posts/be-anonymous-create-your-own-proxy-server-with-aws-ec2/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are living in 2020, and both users and internet applications can take the benefit of cybersecurity. One of the best ways to be secure while browsing the Internet is by using &lt;em&gt;proxy servers&lt;/em&gt;. The proxy server is an important thing to know about nowadays. Let's see what makes proxy servers an essential aspect of cybersecurity support.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop?redirectlocale=en-US&amp;amp;redirectslug=enable-and-disable-cookies-website-preferences" rel="noopener noreferrer"&gt;traking cookies&lt;/a&gt;, &lt;a href="https://robertheaton.com/2017/10/17/we-see-you-democratizing-de-anonymization/" rel="noopener noreferrer"&gt;browser fingerprinting&lt;/a&gt; and &lt;a href="https://www.privacypolicies.com/blog/isp-tracking-you/" rel="noopener noreferrer"&gt;Internet Service Providers (ISPs) selling our browsing logs to advertisers&lt;/a&gt;, online anonymity is out like COVID 19 virus, everybody knows about it, but few are doing something about it. While your next-door-neighbour might not know where to find you online, but there is at least one large corporation (you know whom I am indicating G..... 😅), which has a series of 0's and 1's stored in their database&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;which represents you&lt;/strong&gt;, specific details of what you buy, what you like, what you don't, including your favourite ice cream flavour.&lt;/p&gt;

&lt;p&gt;There are few ways to stop this, like using a corporate firewall, using Tor, or maybe a VPN. But in this blog, we'll see a free and effective way to stay secure online.&lt;br&gt;
What's a proxy server, anyway?&lt;/p&gt;

&lt;p&gt;A proxy, in the English definition, is the "authority or power to act for another." A proxy server, in the computing context, is a server that acts on behalf of another server, or a user's machine.&lt;/p&gt;

&lt;p&gt;By using a proxy to browse the Internet all of the user's Internet traffic appears to come from the proxy server instead of their machine. To set up a free high-speed proxy server all you need is a free tier AWS account.&lt;/p&gt;

&lt;p&gt;Follow the steps below to create a proxy server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Go to the AWS console and select EC2 from the services.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqu16zfh85orl9dgg6daw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqu16zfh85orl9dgg6daw.png" alt="AWS Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Select Instances from the left panel and then click in Launch instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffp4f7sz5l30eio9617y6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffp4f7sz5l30eio9617y6.png" alt="EC2 Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: From the list, select Ubuntu Server 18.04 LTS, and click in next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fto4wtqilq93gnxanxcfv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fto4wtqilq93gnxanxcfv.png" alt="Ubuntu Instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: Click on continue and keep default configuration until you reach the Security Group configuration. Create a new security group, add a security group name and a small description. Then add a new rule, set Type to Custom TCP, and set Port Range to 8888. In source, choose My IP from the dropdown. Click on Review and launch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzlbkdjrxbhug9rn4dccq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzlbkdjrxbhug9rn4dccq.png" alt="Security Group Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to &lt;em&gt;create new SSH keys and download it&lt;/em&gt; from the popup after clicking on Review and launch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;: Once your instance is created, click on the Connect button, and copy the ssh command as shown in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzlbkdjrxbhug9rn4dccq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzlbkdjrxbhug9rn4dccq.png" alt="Connect to EC2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;: Open a terminal, and run this the following command. If you are on the windows machine, I highly suggest you &lt;a href="https://linuxacademy.com/guide/17385-use-putty-to-access-ec2-linux-instances-via-ssh-from-windows/" rel="noopener noreferrer"&gt;use Putty&lt;/a&gt; for connecting to the EC2 server.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Goto the directory where the key is download.&lt;/span&gt;

&lt;span class="nb"&gt;chmod &lt;/span&gt;400 proxy-server.pem

&lt;span class="c"&gt;# Paste the code copied from AWS.&lt;/span&gt;

ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"proxy-server.pem"&lt;/span&gt; @ec2-12-345-678-90.ap-south-1.compute.amazonaws.com


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, you'll get a shell in the AWS EC2 server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;tinyproxy


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will get you all the dependency needed. We will use TinyProxy to setup our Ubuntu Server as the Proxy. By default, TinyProxy operates on Port &lt;em&gt;8888&lt;/em&gt;. Now we need to modify the configuration file of TinyProxy to allow the only IP address of your machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8&lt;/strong&gt;: For this step, you should be familiar with the VIM text editor. If you are not, I'll soon write a detailed blog for VIM too.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/tinyproxy/tinyproxy.conf


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Look for Allow &lt;code&gt;127.0.0.1&lt;/code&gt; line and add your public IP, as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fporty2oy5zlsbxozgq7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fporty2oy5zlsbxozgq7m.png" alt="Tiny Proxy Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To know your IP, run this in a new terminal.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl ifconfig.co


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will get your public IP there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9&lt;/strong&gt;: The final step is to restart the tinyproxy to reflect the changes we made.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; /etc/init.d/tinyproxy restart&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  How to use this Proxy?&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fodafaqbc9b9f9ocizs26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fodafaqbc9b9f9ocizs26.png" alt="Firefox Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To browse the Internet via this Proxy, we &lt;em&gt;need to set up our browser to use this Proxy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the firefox browser goto preferences from right top corner options, and search for Proxy. Choose manual proxy configuration, and in HTTP proxy add your AWS EC2 public IP(you can get the public IP from AWS EC2 dashboard), in Port add 8888. Make sure to check the Also use this Proxy for FTP and HTTPS checkbox. Click, OK, and you are good to go.&lt;/p&gt;

&lt;p&gt;To verify go to Google, and search what is my IP. You will see your AWS EC2 IP, that means all your data is routed via AWS servers.&lt;br&gt;
This means there is no more restriction on which site you can access. All sites are unlocked for you😁. Enjoy!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>linux</category>
      <category>security</category>
    </item>
  </channel>
</rss>
