# \[Question\] \[Hardhat\] Best Way Call OpenZeppelin's Upgradeable Contract

**URL:** <https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300>\
**Category:** Upgrades\
**Tags:** proxies\
**Created:** [May 13, 2021, 9:56am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300 "2021-05-13T09:56:56Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bao1018](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/bao1018/32/5714_2.png) [@bao1018](https://forum.openzeppelin.com/u/bao1018)\
**Post date:** [May 13, 2021, 9:56am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/1 "2021-05-13T09:56:57Z")

</div>

**💻 Environment**

- Private Quorum Network with Raft Consensus
- “devDependencies”: {  
“@nomiclabs/hardhat-ethers”: “^2.0.2”,  
“@openzeppelin/hardhat-upgrades”: “^1.7.0”,  
“ethers”: “^5.1.4”  
},  
“dependencies”: {  
“@openzeppelin/contracts-upgradeable”: “^4.1.0”  
}

**📝Details**  
I am very new to OpenZeppelin and thanks for building such a awesome tool. my questions is  
I use hardhat-upgrades plugin to deploy a upgradable contract:MyToken.sol and I believe the deployment is working since I can use the deployed proxy instance to trigger function (below code works for me):

```
const MyTokenContract = await ethers.getContractFactory("MyToken");
const contract = await upgrades.deployProxy(MyTokenContract);
await contract.deployed();
const contractName = await contract.name();

```

Also I can get below info from this deployment:

1. Proxy contract’s address
2. ABI of upgradable contract (MyToken.sol)

After that, I store the proxy address and contract abi in a database b/c for my case, I need to use a nodeJS application leverage that proxy contract address, MyToken’s abi and user’s keystore to call that upgradable contract’s function through the proxy contract.

I try the ethers’s` new ethers.Contract( address , abi , signerOrProvider)` to init that upgradable contract instance and call the function, but it looks like I failed to use proxy contract address and MyToken.sol 's abi to do it. I get a error when I trigger the contract(MyToken.sol) function:

```
Error: call revert exception (method="name()", errorSignature=null, errorArgs=[null], reason=null, code=CALL_EXCEPTION, version=abi/5.1.2)
at Logger.makeError (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/logger/src.ts/index.ts:205:28)
at Logger.throwError (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/logger/src.ts/index.ts:217:20)
at Interface.decodeFunctionResult (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/abi/src.ts/interface.ts:326:23)
at Contract.<anonymous> (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/src.ts/index.ts:321:44)
at step (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/lib/index.js:48:23)
at Object.next (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/lib/index.js:29:53)
at fulfilled (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/lib/index.js:20:58)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at runNextTicks (internal/process/task_queues.js:62:3)
at listOnTimeout (internal/timers.js:523:9) {

```

reason: null,

So the questions is

1. is that the right way to implement call a upgradeable contract via proxy address ,abi and signer ?
2. For my current approach, I feel like I should get the proxy’s abi rather than the implementation contract’s abi, please suggest how to fix it.

**🔢 Code to reproduce**

1. Token.sol

2. deploy contract

3. Call contract via ethers

---

<div class="post-metadata">

**Author:** ![bao1018](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/bao1018/32/5714_2.png) [@bao1018](https://forum.openzeppelin.com/u/bao1018)\
**Post date:** [May 13, 2021, 1:56pm UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/2 "2021-05-13T13:56:56Z")

</div>

I just try to use below code to get the the proxy contract’s abi and test this abi with

```
const MyTokenContract = await ethers.getContractFactory(“MyToken”);
const contract = await upgrades.deployProxy(MyTokenContract);
await contract.deployed();
const abi = contract.interface.format(FormatTypes.json) // get proxy contract abi

```

but got same error with below code

```
const contract = new ethers.Contract(proxyContractAddress, abi, signer) // use the abi from proxy
const name = await contract.name(); // not work
```

---

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [May 14, 2021, 11:41am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/3 "2021-05-14T11:41:41Z")

</div>

> [@bao1018](#):
>
> Call contract via ethers
> 
> const contract = new ethers.Contract(proxyContractAddress, abi, signer)  
> const name = await contract.name(); // not work

Is your ABI in this step correct, or associated to the old contract?

---

<div class="post-metadata">

**Author:** ![bao1018](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/bao1018/32/5714_2.png) [@bao1018](https://forum.openzeppelin.com/u/bao1018)\
**Post date:** [May 15, 2021, 1:44am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/4 "2021-05-15T01:44:31Z")

</div>

@Yoshiko Thanks for the help, actually In my case, I have not upgraded the contract yet so just only 1 version contract and abi and I am not sure if my abi is correct or not, just let you know I tried the abi from compiled json file and` contract.interface.format(FormatTypes.json)`, same result.

Also my latest update is

If I use below code, I can get the contract instance and make it work:

```
async function deploy() {    
    const MyTokenContract = await ethers.getContractFactory("DropToken");
    const contractProxy = await upgrades.deployProxy(MyTokenContract);
    console.log(MyTokenContract.signer.address);
    await contractProxy.deployed();

  }
  async function call() {
    const MyTokenContract = await ethers.getContractFactory("DropToken");
    const contract = MyTokenContract.attach('0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0');
    console.log("Say hi,:", await contract.name());
  }

  async function main() {
    await deploy();
    await call();
  }

```

But if I break the execution of deploy() and call() function into 2 times, it will NOT work  
run below code to deploy contract first:

```
async function deploy() {    
    const MyTokenContract = await ethers.getContractFactory("DropToken");
    const contractProxy = await upgrades.deployProxy(MyTokenContract);
    console.log(MyTokenContract.signer.address);
    await contractProxy.deployed();

  }
  async function main() {
    await deploy();
  }

```

Then run below to call the functions

```
  async function call() {
    const MyTokenContract = await ethers.getContractFactory("DropToken");
    const contract = MyTokenContract.attach('0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0');
    console.log("Say hi,:", await contract.name());
  }

  async function main() {
    await call();
  }

```

Then got `call revert exception` error:

```auto
Error: call revert exception (method="name()", errorSignature=null, errorArgs=[null], reason=null, code=CALL_EXCEPTION, version=abi/5.1.2)
    at Logger.makeError (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/logger/src.ts/index.ts:205:28)
    at Logger.throwError (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/logger/src.ts/index.ts:217:20)
    at Interface.decodeFunctionResult (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/abi/src.ts/interface.ts:326:23)
    at Contract.<anonymous> (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/src.ts/index.ts:321:44)
    at step (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/lib/index.js:48:23)
    at Object.next (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/lib/index.js:29:53)
    at fulfilled (/Users/mbao010/Documents/gitbase/pwc/drip/drip-contract-v2/node_modules/@ethersproject/contracts/lib/index.js:20:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at runNextTicks (internal/process/task_queues.js:62:3)
    at listOnTimeout (internal/timers.js:523:9) {
  reason: null,
  code: 'CALL_EXCEPTION',
  method: 'name()',
  errorSignature: null,
  errorArgs: [null],
  address: '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0',
  args: [],
  transaction: {
    data: '0x06fdde03',
    to: '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0',
    from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
    gasLimit: BigNumber { _hex: '0xaf09a8', _isBigNumber: true }
  }
}

```

I compare above 2 cases, the difference is the `contract.signer.provider` from those 2 cases are a little different, but I have no idea what that mean to me.

Also do you have any success sample code snippet for my case (also I believe this is a very generic usecase) for me to reference ? Thanks in advance.

---

<div class="post-metadata">

**Author:** ![Skyge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/skyge/32/343_2.png) [@Skyge](https://forum.openzeppelin.com/u/Skyge)\
**Post date:** [May 15, 2021, 2:26am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/5 "2021-05-15T02:26:34Z")

</div>

Hi, welcome! 👋

I think maybe you can have a look at this tutorial:

- [OpenZeppelin Upgrades: Step by Step Tutorial for Hardhat](https://forum.openzeppelin.com/t/openzeppelin-upgrades-step-by-step-tutorial-for-hardhat/3580)

---

<div class="post-metadata">

**Author:** ![Yoshiko](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/yoshiko/32/6858_2.png) [@Yoshiko](https://forum.openzeppelin.com/u/Yoshiko)\
**Post date:** [May 15, 2021, 5:02am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/6 "2021-05-15T05:02:31Z")

</div>

Agree with Skyge, this tutorial will help you understand how to use proxies.

---

<div class="post-metadata">

**Author:** ![bao1018](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/bao1018/32/5714_2.png) [@bao1018](https://forum.openzeppelin.com/u/bao1018)\
**Post date:** [May 17, 2021, 8:46am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/7 "2021-05-17T08:46:26Z")

</div>

Thanks @Yoshiko and @Skyge I have figured out this problem.  
The root cause is when I deploy the contract I did not specify the network parameter in my command which make my deployment happened on Hardhat’s built-in network([https://hardhat.org/hardhat-network/#hardhat-network](https://hardhat.org/hardhat-network/#hardhat-network)) rather than my quorum network, I got it working after I change deployment point to local quorum network. Many thanks for the help!

But a follow up concern is: does the OpenZeppelin‘s hardhat plugin work well with Hardhat Network ?

---

<div class="post-metadata">

**Author:** ![Skyge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/skyge/32/343_2.png) [@Skyge](https://forum.openzeppelin.com/u/Skyge)\
**Post date:** [May 17, 2021, 9:37am UTC](https://forum.openzeppelin.com/t/question-hardhat-best-way-call-openzeppelins-upgradeable-contract/8300/8 "2021-05-17T09:37:25Z")

</div>

> [@bao1018](#):
>
> I got it working after I change deployment point to local quorum network.

Glad to hear that.

> [@bao1018](#):
>
> But a follow up concern is: does the OpenZeppelin‘s hardhat plugin work well with Hardhat Network ?

Yes, I think so.
