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

Remix IDE与Ethers.js调用合约firstStage返回值不一致问题

问题分析与解决方案:Ethers.js调用firstStage返回challenge为0的原因

问题根源

你在JavaScript代码里用callStatic调用registerDevice方法,但callStatic是模拟调用——它只会计算函数返回值,不会向区块链发送交易,也不会修改合约的状态(比如你的devChals映射)。所以哪怕registerDevice返回了正确值,链上根本没存储设备的challenge和response数据,后续调用firstStage自然读不到,只能返回0。

而在Remix里调用时,你是直接发送了写入交易,合约状态被正常更新,所以firstStage能拿到正确的challenge值。

修复方案

把registerDevice的调用从callStatic改成正常的交易调用,等交易上链后再调用firstStage。另外注意signer.getAddress()是异步方法,必须用await获取实际地址。

修改后的JavaScript代码:

const {ethers} = require('ethers');

const provider = new ethers.providers.JsonRpcProvider(`HTTP://127.0.0.1:7545`);
const signer = new ethers.Wallet("<wallet private key>", provider);

const address = '<hex address>'; // smart contract address

const ERC20_ABI =
[
    "function registerDevice(address, uint256, uint256) public returns(uint256, uint256)",
    "function firstStage(address) public returns(uint256, uint256, string)"
]

const contract = new ethers.Contract(address, ERC20_ABI, provider);
const contractWithSigner = contract.connect(signer);

const main = async() => {
    var challenge = 103697318762117;
    var response = 83968343435925;

    // 改为正常交易调用,等待交易上链确认状态更新
    const tx = await contractWithSigner.registerDevice(await signer.getAddress(), challenge, response);
    await tx.wait();

    // 可选:用callStatic验证注册结果
    const regDev = await contractWithSigner.callStatic.registerDevice(await signer.getAddress(), challenge, response);
    const {0: challengeReg, 1: responseReg} = regDev;
    console.log(`${challengeReg} ${responseReg}\n\n`);
    
    const firstStage = await contractWithSigner.callStatic.firstStage(await signer.getAddress());
    const {0: challengeFirstStage, 1: MnodeFirstStage, 2: HnodeFirstStage} = firstStage;
    
    console.log(firstStage, challengeFirstStage, MnodeFirstStage.toNumber(), HnodeFirstStage);
}

main();

额外提醒

  • callStatic只适合只读函数或者需要提前算返回值但不修改状态的场景,对会改合约状态的写入函数,必须用正常交易调用(不带callStatic)。
  • 调用signer.getAddress()一定要加await,不然会传入Promise对象而非实际地址,可能导致后续操作异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:25:38