Abi
abi.decode 與 pragma 實驗性 ABIEncoderV2 使用嵌套數組還原
我有一個帶有字節 calldata 參數的函式,需要將其解碼為結構,但呼叫會在彙編中恢復。我相信這個問題與嵌套數組有關。我使用了一種類似的技術,只有一維數組,它似乎工作正常。
struct InputParams { address[] exchangeAddresses; address[][] exchangePoolOrPaths; address[] tokenAddresses; uint256 tokenStartAmount; uint256[] tokenAmountsExpected; } function execute(uint blockNumber, bytes calldata data, bool admin) external { InputParams memory params = abi.decode(data, (InputParams)); // this reverts in assembly }
檢查使用此函式進行交易的原始輸入並不能提供太多資訊。我在單獨的參數下面解析出來,它們似乎編碼正常:
0xb83775a0 // function signature 0000000000000000000000000000000000000000000000000000000000000000 // parameter "blockNumber" == 0 0000000000000000000000000000000000000000000000000000000000000060 // parameter bytes calldata "data" offset value 0000000000000000000000000000000000000000000000000000000000000001 // parameter "admin" == 1 00000000000000000000000000000000000000000000000000000000000002c0 // struct InputParams length 00000000000000000000000000000000000000000000000000000000000000a0 // offset of exchangeAddresses[] 0000000000000000000000000000000000000000000000000000000000000100 // offset of exchangePoolOrPaths[][] 00000000000000000000000000000000000000000000000000000000000001e0 // offset of tokenAddresses[] 0000000000000000000000000000000000000000000000004563918244f40000 // value of tokenStartAmount 0000000000000000000000000000000000000000000000000000000000000260 // offset of tokenAmountsExpected[] 0000000000000000000000000000000000000000000000000000000000000002 // number of items in exchangeAddresses[] 0000000000000000000000001cb3aca0179bc96cd9612d6c27285b0458a2500f // value of exchangeAddresses[0] 00000000000000000000000080d73310b92da08b230adf441a6352e8f9631a77 // value of exchangeAddresses[1] 0000000000000000000000000000000000000000000000000000000000000002 // number of items in exchangePoolOrPaths[*][] 0000000000000000000000000000000000000000000000000000000000000040 // offset of array at exchangePoolOrPaths[0] 0000000000000000000000000000000000000000000000000000000000000080 // offset of array at exchangePoolOrPaths[1] 0000000000000000000000000000000000000000000000000000000000000001 // number of items in array at exchangePoolOrPaths[0] 000000000000000000000000b5ffd0a221fc94de9255382e70ce1aec76b68c89 // value of exchangePoolOrPaths[0][0] 0000000000000000000000000000000000000000000000000000000000000001 // number of items in array at exchangePoolOrPaths[1] 0000000000000000000000003b3d4eefdc603b232907a7f3d0ed1eea5c62b5f7 // value of exchangePoolOrPaths[1][0] 0000000000000000000000000000000000000000000000000000000000000003 // number of items in tokenAddresses[] 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 // value of tokenAddresses[0] 0000000000000000000000000ae055097c6d159879521c384f1d2123d1f195e6 // value of tokenAddresses[1] 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 // value of tokenAddresses[2] 0000000000000000000000000000000000000000000000000000000000000002 // number of items in tokenAmountsExpected[] 0000000000000000000000000000000000000000000000039fe550f187a54000 // value of tokenAmountsExpected[0] 0000000000000000000000000000000000000000000000004563918244f40000 // value of tokenAmountsExpected[1]
有誰知道這裡可能出現什麼問題?
編輯:
我想我簡化了問題案例。我認為結構內的解碼和動態數組存在問題。
什麼有效:
struct InputParams { address[2] exchangeAddresses; } function execute(uint blockNumber, bytes calldata data, bool admin) external { InputParams memory params = abi.decode(data, (InputParams)); } with calldata: 0xb83775a0 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000060 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000040 000000000000000000000000b5ffd0a221fc94de9255382e70ce1aec76b68c89 0000000000000000000000003b3d4eefdc603b232907a7f3d0ed1eea5c62b5f7
什麼不起作用(在解碼期間恢復):
struct InputParams { address[] exchangeAddresses; } function execute(uint blockNumber, bytes calldata data, bool admin) external { InputParams memory params = abi.decode(data, (InputParams)); } with calldata: 0xb83775a0 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000060 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000080 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000002 000000000000000000000000b5ffd0a221fc94de9255382e70ce1aec76b68c89 0000000000000000000000003b3d4eefdc603b232907a7f3d0ed1eea5c62b5f7
有沒有人有任何想法,或者如果我實際上只是傳遞了不正確的呼叫數據……
問題在這裡解決:https ://github.com/ethereum/solidity/issues/9747#issuecomment-687833241
輸入的呼叫數據不正確