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

Node.js调用智能合约无输出:async/await使用问题排查

问题分析与修复方案

核心问题

你的代码执行后无输出,主要有两个关键原因:

  1. 合约函数调用缺少必要参数:check_If_Address_Already_Signed()和check_Database_Verified_Address()这类合约函数通常需要传入要检查的地址(比如签名者地址),你直接调用未传参,大概率返回false,导致签名逻辑不执行,也没有任何提示。
  2. 异步错误未捕获:sign_jeton()是异步函数,调用时未处理Promise拒绝(比如合约连接失败、函数调用出错),错误会静默抛出,程序直接终止,无输出。

修复步骤

1. 补全合约函数的必要参数

先通过私钥生成钱包实例获取签名者地址,再传入合约函数:

const wallet = new ethers.Wallet(PRIVATE_KEY, provider); // 用ethers创建钱包获取地址
async function sign_jeton() {
  try {
    // 传入签名者地址到合约函数
    const isSigned = await contract.check_If_Address_Already_Signed(wallet.address);
    const isVerified = await contract.check_Database_Verified_Address(wallet.address);
    
    if (isSigned && isVerified) {
      // 统一用ethers签名,避免混用web3和ethers
      const signature = await wallet.signMessage(Jeton);
      console.log("签名结果:", signature);
      // 这里可添加发送交易的逻辑
    } else {
      console.log("地址未满足签名条件");
    }
  } catch (error) {
    console.error("执行出错:", error);
  }
}

2. 添加错误捕获逻辑

用try/catch包裹所有异步操作,确保错误能被捕获输出,避免静默失败:

async function sign_jeton() {
  try {
    const isSigned = await contract.check_If_Address_Already_Signed(wallet.address);
    const isVerified = await contract.check_Database_Verified_Address(wallet.address);
    
    if (isSigned && isVerified) {
      const signature = await wallet.signMessage(Jeton);
      console.log("签名成功:", signature);
    } else {
      console.log("条件不满足,拒绝签名");
    }
  } catch (err) {
    console.error("程序出错:", err.message);
  }
}

3. 统一使用ethers库(可选)

同时混用ethers和web3易造成混淆,建议统一用ethers完成所有操作,比如签名用wallet.signMessage(),更贴合当前合约实例环境。

4. 验证合约ABI正确性

检查abi.json中两个函数的定义,确认参数个数、类型与合约一致,若ABI里函数需要参数但未传,调用会失败。

完整修复后的代码示例

/*
签名者仅在already_Signed_Addresses()和check_If_Address_Already_Signed()均为true时,才对消息签名。
导入智能合约,调用两个函数,若均为true则用签名者私钥签名,否则终止。
编写签名者到用户(msg.sender)的交易,附带签名后的Jeton数据
*/
const crypto = require("crypto");
const ethers = require("ethers");
const ABI = require("./abi.json");
require("dotenv").config();

function getRandomJeton(Choix_Vote, N_V) {
  let randomAnonymeNumber1 = crypto.getRandomValues(new Uint32Array(1))[0];
  let randomAnonymeNumber2 = crypto.getRandomValues(new Uint32Array(1))[0];
  let uniqueNumber = "12345678910";
  let uniqueRandomValue = `${uniqueNumber}${randomAnonymeNumber2}${randomAnonymeNumber1}`;
  let unhashedJeton = `${Choix_Vote}${uniqueRandomValue}${N_V}`;
  const Jeton = crypto.createHash("sha256").update(unhashedJeton).digest("hex");
  return Jeton;
}

const Jeton = getRandomJeton(1, 2);
console.log("生成的Jeton:", Jeton);

const contractAddress = "0x2A6b9Dd8B2581FbCf2b8a54D6ACf278802C168E4";
const provider = new ethers.providers.WebSocketProvider(
  `wss://polygon-mumbai.g.alchemy.com/v2/${process.env.ALCHEMY_PRIVATE_KEY}`
);
const contract = new ethers.Contract(contractAddress, ABI, provider);
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new ethers.Wallet(PRIVATE_KEY, provider); // 创建ethers钱包实例

async function sign_jeton() {
  try {
    // 调用合约函数时传入签名者地址
    const isSigned = await contract.check_If_Address_Already_Signed(wallet.address);
    const isVerified = await contract.check_Database_Verified_Address(wallet.address);

    console.log("合约检查结果:", { isSigned, isVerified });

    if (isSigned && isVerified) {
      const signature = await wallet.signMessage(Jeton);
      console.log("Jeton签名结果:", signature);
      
      // 这里可以添加发送交易的逻辑,比如向用户地址发送带签名数据的交易
      // const tx = await wallet.sendTransaction({
      //   to: "用户地址",
      //   data: ethers.utils.toUtf8Bytes(signature)
      // });
      // console.log("交易发送成功,哈希:", tx.hash);
    } else {
      console.log("地址未通过合约检查,不执行签名");
    }
  } catch (error) {
    console.error("执行过程出错:", error);
  }
}

sign_jeton();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:05:56