Ethers.js

如何在 Ethers 中使用代理?

  • April 18, 2022

我正在嘗試在乙太坊中使用代理。

我的 Solidity 文件:

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; // to use via getContractFactory()

contract Test {
   string public constant message = "Hello, world!";
}

我將嘗試message從代理讀取。

我看到 2 個選項:

  1. 呼叫(不起作用)message()的實例TransparentUpgradeableProxy
  2. 呼叫附加到代理地址message()的實例Test(不起作用)

我的腳本:

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Test", function () {

 it("Should be able to read message from proxy", async function () {

   // Get Signer
   const signer = await hre.ethers.getSigner();

   // Get Contract Factories
   const Test = await ethers.getContractFactory("Test");
   const Proxy = await ethers.getContractFactory("TransparentUpgradeableProxy");

   // Deploy Contract
   const test = await Test.deploy();
   await test.deployed();

   // Deploy Proxy
   const proxy = await Proxy.deploy(test.address, signer.address, []);
   await proxy.deployed();

   // Attach Contract ABI to Proxy Address
   const proxy2 = await Test.attach(proxy.address);

   console.log(await test.message()); // to make sure it works
   try { console.log(await proxy.message()) } catch (err) { console.log(err.message) } // option 1
   try { console.log(await proxy2.message()) } catch (err) { console.log(err.message) } // option 2
 });
});

輸出: 在此處輸入圖像描述

幫助?

這裡發生了幾件事。

  1. 要部署代理,您必須logic在建構子中實際初始化地址。因此,您應該按照以下方式做一些事情
contract Test is TransparentUpgradeableProxy {
  constructor(
     address _logic,
     address _admin_,
     bytes memory _data
  ) payable TransparentUpgradeableProxy(_logic, _admin, _data) {}
}

_logic是您嘗試代理的合約的地址。這應該讓您開始實際部署代理

  1. 至於await test.message()它不起作用,因為合約本身沒有message功能。我不認為solidity提供預設的getter和setter,所以你需要自己實現它們。

我想到了。

選項 2(將合約附加到代理的地址)是正確的方法。

由於這條線,我失敗了:https ://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/proxy/transparent/TransparentUpgradeableProxy.sol#L122

現在,我從非管理員地址呼叫消息,如下所示:

await proxy2.connect(nonAdmin).message()

它有效。

引用自:https://ethereum.stackexchange.com/questions/126402