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

web3.py调用合约mint方法被Etherscan识别为ETH转账问题排查

问题根因

核心错误是实例化合约对象时传错了地址参数:你代码中address变量存储的是个人钱包地址,初始化w3.eth.contract()时直接把这个地址作为合约地址传入,导致最终生成的交易to字段指向你自己的外部持有地址(EOA钱包),而非目标智能合约地址。这类交易即使data字段携带了合约方法编码,因为接收方不是合约地址,Etherscan只会判定为普通ETH转账,不会识别为合约交互。

问题验证

你可以对比两笔交易的链上数据确认:

  • 正常手动交互生成的交易,To字段为目标NFT合约地址
  • 你代码生成的交易,To字段为你自己的个人钱包地址,和上述错误特征完全匹配
修正方案
  1. 分开定义个人钱包地址、目标合约地址两个变量,避免混用
  2. 构建交易时显式补全chainId、from、gas、gasPrice字段,避免不同版本web3.py自动填充参数时出现异常
  3. 你当前使用的Rinkeby测试网已于2022年合并后正式废弃,节点返回数据存在异常风险,建议迁移到Sepolia测试网完成测试

修正后的可运行代码参考:

import os
import json
from web3 import Web3
from web3.middleware import geth_poa_middleware

# 替换为Sepolia测试网节点地址
infura_url = "https://sepolia.infura.io/v3/<替换为你的Infura节点Key>"
w3 = Web3(Web3.HTTPProvider(infura_url))
# POA共识网络需注入对应中间件
w3.middleware_onion.inject(geth_poa_middleware, layer=0)

# 两个地址分开定义,禁止混用
my_wallet_address = w3.toChecksumAddress("<替换为你的个人钱包地址>")
nft_contract_address = w3.toChecksumAddress("<替换为你要交互的NFT合约地址>")
abi = json.loads("<替换为合约对应的ABI内容>")

# 初始化合约时传入正确的合约地址
contract = w3.eth.contract(address=nft_contract_address, abi=abi)

# 构建交易时显式传入所有必要参数
mint_tx = contract.functions.mint(my_wallet_address, 1).buildTransaction({
    'chainId': w3.eth.chain_id,
    'nonce': w3.eth.getTransactionCount(my_wallet_address),
    'from': my_wallet_address,
    'gas': 300000,
    'gasPrice': w3.eth.gas_price
})

signed_txn = w3.eth.account.sign_transaction(mint_tx, private_key=os.environ['private_key'])
txhash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(f'Transaction hash: {txhash.hex()}')
额外注意事项
  • 保持当前用环境变量存储私钥的写法,禁止将私钥硬编码在代码中
  • 签名广播交易前,可以先打印mint_tx['to']字段,确认输出为目标合约地址再发送,避免浪费测试网Gas
  • 如果使用EIP-1559交易类型,可以将gasPrice字段替换为maxFeePerGas、maxPriorityFeePerGas两个参数适配新的手续费机制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:03:18