How to deploy a contract with only abi & bytecode to hardhat node

I have a proxy contract and would like to replace the underlying implementation contract.

I already have the abi & bytecode of a smart contract(retrieved from artifacts folder), so here is what I did:

const NFTv2 = await ethers.getContractFactory(upgradedContract.abi, upgradedContract.bytecode);
contract = await upgrades.upgradeProxy(proxyContract.address, NFTv2);

It works fine, but I don't want the contract to exist in my contracts folder, so I've deleted it and run npx hardhat compile again.

Now when I try to run this deploy script again, hardhat keep throwing this error:

Error: The requested contract was not found. Make sure the source code is available for compilation
      at getContractNameAndRunValidation (node_modules/@openzeppelin/upgrades-core/src/validate/query.ts:46:11)
      at Object.getStorageLayout (node_modules/@openzeppelin/upgrades-core/src/validate/query.ts:54:41)
      at Object.deployImpl (node_modules/@openzeppelin/hardhat-upgrades/src/utils/deploy-impl.ts:30:18)
      at Proxy.upgradeProxy (node_modules/@openzeppelin/hardhat-upgrades/src/upgrade-proxy.ts:36:22)

After some try & error, it seems to be related to the cache folder, once the related metadata inside the cache folder disappeared, then this error will pop out, otherwise no.

Can someone guide me on this problem and how can I deploy contract with only abi & bytecode without leaving the contract inside the contracts folder?

Thank you! :slight_smile:

Here's the code of my upgraded contract:

// SPDX-License-Identifier: Apache2.0
pragma solidity ^0.8.4;

import "@openzeppelin/contracts-upgradeable/token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol";

contract Test is ERC1155PresetMinterPauserUpgradeable {
    string private _uri;

    event upgradeEvent(string);

    function uri(uint256) public view virtual override returns (string memory) {
        return string(abi.encodePacked(_uri, "/new"));
    }

    function seturi(string memory uri) public {
        emit upgradeEvent("this is an upgraded contract");
        _uri = uri;
    }
}

Although I am not sure why you want to do like so.
I think when you run npx hardhat compile, it will compile your contracts when the file has some changes, so if you remove the contracts file, it means there is no contracts to compile, so you will get an empty file, and then when you run your scripts, you will get the error just like you pasted above The requested contract was not found.

Emmmm, I do not think so, I think when you run npx hardhat compile, the contract ABI and bytescode are in the file named artifacts/contracts.

Finally, I think in your case, you can create a file to store these data: ABI and bytescode, I just make a test project, maybe you can have a look: https://gist.github.com/Skyge/4dacb549af7d73bc0f2e728d7dd7744a

1 Like

For deploying the contract using OpenZeppelin Upgrades for Hardhat, you basically need the source code in the contracts directory. ABI and bytecode are not enough because we need to extract storage layout and check for errors in the source code.

If for some reason you don't want the contract in your contracts directory, what you can do is first deploy the contract, then make sure to commit to git the .openzeppelin/mainnet.json file (or whatever network you use), and only then you can delete the contract source code.

1 Like

thank you for the example, I'll give it a try.
sorry for the late reply and thank you so much!

Got it, that make sense to me.
Thank you! :slight_smile:

1 Like