如何调用ABI未收录的ERC1155合约totalSupply及相关疑问
问题解答
1. 能否调用ABI未包含的函数?如何实现?
可以调用。以太坊合约调用的核心是向合约地址发送包含函数签名+参数编码的calldata,ABI只是简化calldata生成的工具,并非必要条件。你已经在用正确的实现方式:通过Solidity的低级call方法,配合abi.encodeWithSignature手动生成目标函数的calldata。关键要保证函数签名完全匹配,包括参数类型、大小写,比如totalSupply(uint256)不能写错参数类型或函数名。
2. 为什么bal函数调用失败?
你的bal函数失败大概率是以下原因:
- 函数签名不匹配:目标合约的
totalSupply函数参数可能不是uint256,或者函数名拼写错误。比如部分自定义ERC1155的totalSupply可能定义有误,需要确认目标合约的实际函数签名。 - 未处理调用失败场景:代码里没有判断
successA是否为true,如果目标合约不存在该函数、调用出错,resultA会是空值或包含revert信息,直接执行abi.decode会导致整个函数revert。建议添加失败判断:function bal(address erc1155_address, uint256 nft_id) public { (bool successA, bytes memory resultA) = erc1155_address.call(abi.encodeWithSignature("totalSupply(uint256)", nft_id)); require(successA, "Call to totalSupply failed"); // 调用失败时直接抛出错误 hasilBal = abi.decode(resultA, (uint256)); } - 目标合约函数权限问题:如果目标合约的
totalSupply是internal或private修饰的,外部无法直接调用,自然会触发失败。
3. 为什么调用balanceOf查询数据仍需支付gas?
因为你是通过链上部署的合约发起调用,属于链上交易范畴:你的TotSup合约执行balanceOf函数时,会向目标ERC1155合约发起call,同时修改自身合约的hasil变量,整个过程需要矿工打包执行、消耗链上计算资源,因此需要支付gas。
如果直接用钱包、etherscan的「Read Contract」功能调用目标ERC1155的balanceOf,属于eth_call只读调用,不会写入链上状态,无需支付gas。但你的方式是发起交易触发自身合约的函数执行,本质是链上状态变更操作,所以必须支付gas。
内容的提问来源于stack exchange,提问作者user1034754
相关产品推荐
相关产品推荐

