You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ethers库时如何获取代理合约及对应基础合约的ABI

代理合约ABI获取与逻辑合约定位方案

定位代理合约绑定的基础(逻辑)合约

  • 优先使用Etherscan内置代理识别能力:调用Etherscan合约查询接口时传入module=proxy相关参数,接口会自动返回该代理合约当前绑定的实现合约地址,已适配透明代理、UUPS等绝大多数主流可升级代理模式,无需额外处理。
  • 非标准代理手动读取方案:如果Etherscan无法识别代理类型,可直接通过链上存储读取实现地址,通用存储槽规则如下:
    • 符合EIP-1967标准的代理:实现地址存储在0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc槽位
    • 旧版OpenZeppelin透明代理:实现地址存储在0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3槽位
      直接通过ethers的provider.getStorageAt(代理合约地址, 对应槽位)读取存储值,截掉前导12字节的0值,解析后得到的就是基础合约地址。

获取完整可用ABI的方法

  • 分别拉取两份ABI做合并去重:第一份是代理合约本身的ABI(包含代理升级、权限管理等代理层方法),第二份是定位到的基础合约的ABI(包含mint等业务逻辑方法),将两个ABI数组合并,去除重复的函数/事件定义,得到的就是可完整交互的ABI。
  • 注意:不要仅使用基础合约的ABI初始化实例,否则无法调用代理层自带的管理方法,会出现调用报错。

ethers库中的使用示例

合并完ABI后,直接使用代理合约地址初始化合约实例即可,所有调用会自动通过代理委托执行到逻辑合约,无需指向基础合约地址:

// 初始化provider/signer
const provider = new ethers.JsonRpcProvider(RPC_ENDPOINT)
const signer = await provider.getSigner()
// 合并去重后的完整ABI
const fullAbi = [...proxyAbi, ...implementationAbi]
// 初始化合约实例,地址填代理合约地址
const nftContract = new ethers.Contract(PROXY_CONTRACT_ADDRESS, fullAbi, signer)
// 直接调用mint等业务方法即可正常执行
const tx = await nftContract.mint(mintParams)
await tx.wait()

如果本地有合约源码编译产物,也可以直接用基础合约的ContractFactory连接到代理地址生成实例,再手动补充代理层的方法定义即可,不需要手动拼接ABI。


内容的提问来源于stack exchange,提问作者Webby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:24:08