确认Solidity中含uint与struct参数的函数选择器创建方式是否正确
问题
我编写了一段Solidity代码,试图生成目标函数的选择器,代码如下:
function getMyFunctionSignature( uint256 dbId, launchpadLib.IDOInfo memory _idoInfo, launchpadLib.IDOInfoTwo memory _IDOInfoTwo ) public pure returns (bytes memory) { return ( abi.encodeWithSignature( "createClone(uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint8,address,address),(uint64,uint64,address,uin64,bool,bool))", dbId, _idoInfo.tokenToBeSold, _idoInfo.softcap, _idoInfo.hardcap, _idoInfo.minBuyLimit, _idoInfo.maxBuyLimit, _idoInfo.price, _idoInfo.buyType, _idoInfo.FounderAddress, _idoInfo.tokenAddress, _IDOInfoTwo.startTime, _IDOInfoTwo.endTime, _IDOInfoTwo.receiverAddress, _IDOInfoTwo.VestingTime, _IDOInfoTwo.isWhiteEnabled, _IDOInfoTwo.isActive ) ); }
我想确认用abi.encodeWithSignature创建包含uint类型与struct类型参数的函数选择器的方式是否正确。
回答
你的实现存在几个关键问题,直接整理如下:
签名字符串拼写错误:签名里的
uin64是笔误,应该改成uint64,否则会直接导致编码失败。参数传递方式错误:如果目标函数
createClone的参数是两个struct(对应签名里的tuple类型),你应该直接传递整个_idoInfo和_IDOInfoTwo变量,而非把struct的成员逐个拆分传入。abi.encodeWithSignature会根据签名中的tuple类型自动处理struct编码,拆分成员传递会导致参数数量和签名不匹配,生成错误的calldata。混淆了函数选择器与完整calldata:
abi.encodeWithSignature返回的是完整的函数调用calldata(包含4字节选择器+编码后的参数),不是单纯的函数选择器。如果只需要获取选择器,应该用bytes4(keccak256("目标函数签名字符串"))直接计算。
修正后的代码示例
如果你的目标是生成完整的createClone调用calldata,修正后的代码如下:
function getMyFunctionCallData( uint256 dbId, launchpadLib.IDOInfo memory _idoInfo, launchpadLib.IDOInfoTwo memory _IDOInfoTwo ) public pure returns (bytes memory) { return abi.encodeWithSignature( "createClone(uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint8,address,address),(uint64,uint64,address,uint64,bool,bool))", dbId, _idoInfo, _IDOInfoTwo ); }
如果只是要获取函数选择器,代码如下:
function getCreateCloneSelector() public pure returns (bytes4) { return bytes4(keccak256("createClone(uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint8,address,address),(uint64,uint64,address,uint64,bool,bool))")); }
内容的提问来源于stack exchange,提问作者Vikas Gupta
相关产品推荐
相关产品推荐

