Hedera Hashgraph上ERC-20代币转账报错33相关问题咨询
Hedera网络ERC-20合约部署转账报错问题解答
操作流程与报错现象
操作步骤如下:
- 编写基于OpenZeppelin标准实现的极简ERC-20合约,初始铸造1000枚(精度18位)代币给部署者地址:
pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract Coins is ERC20 { constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) { _mint(msg.sender, 1000000000000000000000); } }
- 通过Hedera Go SDK完成合约上链部署:
tx, err := hedera.NewContractCreateFlow(). SetBytecode(bytecode). SetGas(1_000_000). SetConstructorParameters( hedera.NewContractFunctionParameters(). AddString("Coins"). AddString("coin"), ). Execute(client)
- 部署成功后调用合约
transfer函数向账户0.0.34937758转账1 wei代币,执行代码如下:
ps, _ := hedera.NewContractFunctionParameters(). AddAddress(hedera.AccountID{Account: 34937758}.ToSolidityAddress()) ps.AddUint256(big.NewInt(1).Bytes()) contractExecTx, err := hedera.NewContractExecuteTransaction(). SetContractID(newContractID). SetGas(1000000). SetFunction("transfer", ps). Execute(client)
执行上述转账交易时返回错误:StatusContractRevertExecuted (33)。
问题答疑
1. Hedera网络是否支持常规ERC-20代币使用,是否必须通过HTS发行/转账代币?
Hedera为全EVM兼容网络,完全支持像以太坊链上一样部署、流转自定义Solidity ERC-20代币,不存在强制要求使用HTS(Hedera Token Service)才能发行、转账代币的规则。
本次转账触发合约回滚的直接原因是transfer函数的金额参数编码错误:Solidity ABI要求uint256类型参数必须为32字节定长、左补零格式,代码中手动调用big.NewInt(1).Bytes()生成的是无补位的大端序字节数组,长度仅1字节,合约解码参数时得到异常金额值,触发余额校验逻辑导致交易回滚。
HTS是Hedera提供的原生代币发行模块,通过HTS发行的代币不需要独立部署合约,具备交易手续费更低、确认速度更快、支持原生账户转账无需调用合约的特性,属于可选优化方案,不是强制要求。
2. 自行通过Solidity部署的合约能否注册为Hedera网络官方认可代币?
Hedera链上层面不存在“官方认可代币”的准入注册机制:
- 自主部署的标准ERC-20代币只要合约逻辑合规,即可在链上正常流转,可与所有EVM兼容DApp、钱包交互,不需要额外的链上注册流程。
- 如果需要让区块浏览器、多链钱包展示代币名称、符号、logo等元信息,可自主向对应生态工具的运营方提交通证信息录入申请,这类操作不属于链上共识范畴。
- 如果需要让自主发行的代币具备HTS原生代币的同等性能,可通过Hedera预编译合约直接调用HTS接口发行代币,不需要独立编写ERC-20合约逻辑,这类代币即为Hedera原生代币。
修复方案
修正转账交易的参数传值逻辑,AddUint256方法直接传入big.Int类型对象即可,SDK会自动完成符合Solidity ABI规范的参数编码,不需要手动调用Bytes()方法转字节数组,修正后代码如下:
ps, _ := hedera.NewContractFunctionParameters(). AddAddress(hedera.AccountID{Account: 34937758}.ToSolidityAddress()). AddUint256(big.NewInt(1)) // 直接传入big.Int对象,移除手动Bytes()转换 contractExecTx, err := hedera.NewContractExecuteTransaction(). SetContractID(newContractID). SetGas(1000000). SetFunction("transfer", ps). Execute(client)
内容的提问来源于stack exchange,提问作者Alexey Seliverstov
相关产品推荐
相关产品推荐

