Hedera合约调用触发CONTRACT_REVERT_EXECUTED回滚问题
问题排查:Hedera合约调用触发
CONTRACT_REVERT_EXECUTED回滚 你代码里有3个直接导致交易回滚的硬错误,按影响优先级排序:
- 函数名不匹配:你JS调用代码里写的调用函数是
mintFungibleToken,但合约里实际定义的外部函数名是mintNonFungibleToken,EVM找不到匹配的函数选择器,直接触发回滚。 - HederaTokenService.mintToken传参完全错误:
HTS的mintToken预编译接口规则是: - 铸造同质化代币(FT)时,第二个参数传铸造数量,第三个参数传空字节数组
- 铸造非同质化代币(NFT)时,第二个参数固定传
0,第三个参数传每个NFT对应的metadata字节数组,数组长度就是本次铸造的NFT数量
你当前代码里NFT铸造场景下,第二个参数传了_amount,第三个参数传了全局未赋值的空metadata变量,完全没用到你前面生成的nftMetadatas数组,预编译调用必然返回错误码,触发你写的revert("Mint Failed")逻辑。 - 核心参数未初始化:合约里全局定义的
tokenAddress从来没有赋值,调用mintToken时传入的是零地址,HTS预编译找不到对应目标代币,直接返回失败。
修正方案
1. 合约代码修正
补全token地址初始化逻辑,修正mintToken传参:
pragma solidity ^0.8.11; import "./hip-206/HederaTokenService.sol"; import "./hip-206/HederaResponseCodes.sol"; contract Minting is HederaTokenService { address public tokenAddress; string public baseURI = "abc"; uint64 public mintPrice; // 构造函数初始化代币地址,也可以加权限控制方法后续更新地址 constructor(address _tokenAddress) { tokenAddress = _tokenAddress; } function mintNonFungibleToken(uint64 _amount) external payable { bytes[] memory nftMetadatas = generateBytesArrayForHTS( bytes(baseURI), _amount ); // NFT铸造:第二个参数传0,第三个参数传metadata数组 ( int256 response, uint64 newTotalSupply, ) = HederaTokenService.mintToken(tokenAddress, 0, nftMetadatas); if (response != HederaResponseCodes.SUCCESS) { revert("Mint Failed"); } } // @dev Helper function which generates array of addresses required for HTSPrecompiled function generateAddressArrayForHTS(address _address, uint256 _items) internal pure returns (address[] memory _addresses) { _addresses = new address[](_items); for (uint256 i = 0; i < _items; i++) { _addresses[i] = _address; } } // @dev Helper function which generates array required for metadata by HTSPrecompiled function generateBytesArrayForHTS(bytes memory _bytes, uint256 _items) internal pure returns (bytes[] memory _bytesArray) { _bytesArray = new bytes[](_items); for (uint256 i = 0; i < _items; i++) { _bytesArray[i] = _bytes; } } }
2. JS调用代码修正
把错误的函数名改成合约里实际定义的函数名:
const contractMint = await new ContractExecuteTransaction() .setContractId(contractId) .setGas(3000000) .setFunction( "mintNonFungibleToken", // 修正函数名 new ContractFunctionParameters().addUint64(1) ) .setMaxTransactionFee(new Hbar(2));
额外注意项
- 部署合约时必须传入正确的目标NFT地址作为构造参数
- 要确保当前合约地址被设置为该NFT的minter角色,持有铸造权限
- 发起调用的账户支付的HB要足够覆盖铸造费+gas费
内容的提问来源于stack exchange,提问作者Yasuo
相关产品推荐
相关产品推荐

