DEV Community

Dmitry Zakharov
Dmitry Zakharov

Posted on

How to Change the Bytecode of an Already Deployed Smart Contract

Intro

Developing smart contracts with the Solidity or Vyper programming language always leads to creating some tests in a special environment. Currently, in order to deploy newly created smart contracts in testnet several tools exist, the most popular of which are hardhat, Ape, Boa, and foundry. In this note, we will discuss how you can change the bytecode of a smart contract already deployed on mainnet and, therefore in testnet. This can be useful if you want to change some logic for test purposes or if you want to change prices in oracles, as in a case that will be discussed below.

Updating bytecode of an already deployed smart contract

To prepare these tests, we used this article as an example. First of all, you need to install hardhat > 2.4.0 via npm or yarn. Next, you must add a copy of the smart contract code you want to change in your project repo. A little tip before we start discussing the code: if you use blockGasLimit in hardhat config, you must tune it right so that tests would execute (in our case, we simply removed this parameter from config). Add all necessary changes to this code and deploy it to testnet via ethers.getContractFactory() like this:

const oracles = await ethers.getContractFactory("AaveOracle");
const oracle = await oracles.deploy(
      ["0x6B175474E89094C44Da98b954EedeAC495271d0F"], 
      ["0x773616E4d11A78F511299002da57A0a94577F1f4"], 
      "0x5B09E578cfEAa23F1b11127A658855434e4F3e09", 
      WETH.address,
    );
Enter fullscreen mode Exit fullscreen mode

In the code above, we have AaveOracle, which contains all code from Aave Oracle with small additions, and WETH.address, which is simply a string with wrapped ETH in Ethereum mainnet (0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2). The first parameter in the deploy function is an array of assets, which is used in oracle (in our case, it is an array of 1 asset == DAI address 0x6B175474E89094C44Da98b954EedeAC495271d0F). The second parameter is an array of data feeds (in our case, it is chainlink's data feed for DAI/ETH 0x773616E4d11A78F511299002da57A0a94577F1f4). The third parameter is a fallback oracle (in our case, it is simply Aave fallback oracle 0x5B09E578cfEAa23F1b11127A658855434e4F3e09). After all these steps are taken, you can use the hardhat function eth_getCode() to get the bytecode of your newly deployed smart contract, and after that, you must use eth_setCode() to add this code to the contract address in testnet:

const code = await hre.network.provider.send("eth_getCode", [
        oracle.address,
    ]);
await hre.network.provider.send("hardhat_setCode", [
      "0xA50ba011c48153De246E5192C8f9258A2ba79Ca9",
      code,
    ]);
Enter fullscreen mode Exit fullscreen mode

In the code above, we get the bytecode of our deployed contract and set it to Aave Oracle, which has the address 0xA50ba011c48153De246E5192C8f9258A2ba79Ca9.

Top comments (0)