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

如何使用web3py在Polygon链上转账ERC1155代币?

问题分析与解决方案

核心问题

你遇到的错误本质是用错了ABI:当前使用的是透明代理合约的ABI,里面只有代理相关的函数(比如upgradeTo、admin等),完全没有ERC1155代币的转账函数;另外你代码里调用的transfer也不是ERC1155标准的转账方法,ERC1155的标准转账函数是safeTransferFrom。

修正步骤

  1. 替换为ERC1155标准ABI:使用包含ERC1155核心函数的ABI,比如标准ERC1155的ABI(或者从PolygonScan上获取目标合约的完整ABI)。
  2. 调用正确的转账函数:ERC1155的标准转账函数是safeTransferFrom,参数顺序为(from_address, to_address, token_id, amount, data)。
  3. 正确构建并签名交易:直接用transact()需要本地节点解锁账户,更安全的方式是用私钥构建交易、签名后发送,同时指定Polygon网络的必要参数(gasPrice、nonce等)。

完整正确代码示例

from web3 import Web3
import json

# Polygon RPC节点
rpc_polygon = "https://polygon-rpc.com"
web3 = Web3(Web3.HTTPProvider(rpc_polygon))

# 配置你的账户信息
account_1 = "FROM_ADDRESS"  # 替换为你的转出地址
account_2 = "TO_ADDRESS"    # 替换为转入地址
private_key = "PRIVATE_KEY_HERE"  # 替换为你的私钥
contract_address = "CONTRACT_ADDRESS"  # 替换为目标ERC1155合约地址
token_id = 7  # 注意:TOKEN_ID是整数,不是字符串
transfer_amount = 1  # ERC1155的amount不需要转wei,直接填实际数量

# 1. 使用标准ERC1155 ABI(可以从PolygonScan获取目标合约的完整ABI替换这里)
erc1155_abi = json.loads('''[
    {
        "inputs": [
            {"internalType": "address", "name": "_from", "type": "address"},
            {"internalType": "address", "name": "_to", "type": "address"},
            {"internalType": "uint256", "name": "_id", "type": "uint256"},
            {"internalType": "uint256", "name": "_value", "type": "uint256"},
            {"internalType": "bytes", "name": "_data", "type": "bytes"}
        ],
        "name": "safeTransferFrom",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [
            {"internalType": "address", "name": "account", "type": "address"},
            {"internalType": "uint256", "name": "id", "type": "uint256"}
        ],
        "name": "balanceOf",
        "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
        "stateMutability": "view",
        "type": "function"
    }
]''')

# 2. 初始化合约对象
checksum_contract = Web3.toChecksumAddress(contract_address)
contract = web3.eth.contract(address=checksum_contract, abi=erc1155_abi)

# 3. 获取必要的交易参数
nonce = web3.eth.get_transaction_count(account_1)
gas_price = web3.eth.gas_price  # 或者手动设置,比如web3.toWei("50", "gwei")

# 4. 构建交易
txn = contract.functions.safeTransferFrom(
    account_1,
    account_2,
    token_id,
    transfer_amount,
    b""  # 额外数据,不需要就传空字节
).buildTransaction({
    'chainId': 137,  # Polygon主网链ID
    'gas': 200000,  # 预估gas,可根据实际调整
    'gasPrice': gas_price,
    'nonce': nonce,
})

# 5. 用私钥签名交易
signed_txn = web3.eth.account.sign_transaction(txn, private_key=private_key)

# 6. 发送交易并等待回执
txn_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
txn_receipt = web3.eth.wait_for_transaction_receipt(txn_hash)

# 7. 验证结果
print(f"交易哈希: {web3.toHex(txn_hash)}")
if txn_receipt.status == 1:
    print("转账成功")
    # 可选:验证余额变化
    balance = contract.functions.balanceOf(account_2, token_id).call()
    print(f"账户2的代币{token_id}余额: {balance}")
else:
    print("转账失败")

关键细节说明

  • ABI获取:如果目标合约是代理合约(比如你的原始ABI是代理的),需要在PolygonScan上找到合约的"Implementation"地址,获取该实现合约的ABI,而不是代理合约的ABI。
  • ERC1155参数:safeTransferFrom的最后一个参数_data是可选的额外数据,不需要的话传空字节b""即可。
  • Gas设置:Polygon上的gas价格波动较大,你可以手动设置gasPrice为当前网络的推荐值,比如用web3.toWei("50", "gwei")。
  • Token ID类型:必须是整数,不能是字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 10:50:25