Solidity,字節解碼問題
回到關於solidity Guru的另一個問題。我正在嘗試呼叫一個將字節數組作為輸入的方法,但要麼我錯誤地編碼了這個參數,要麼錯誤地解碼了它。關於此事的 Solidity 文件相當模糊,因此我按照範例中所寫的方式實現了。函式回調接收到所述參數,但是每當我在測試網中呼叫它時都會失敗。關於字節函式,我缺少什麼
abi.decode()
,或者只是錯誤地編碼了我的數據?任何幫助將不勝感激,謝謝!這是相關的 kovan 測試網交易: https ://kovan.etherscan.io/tx/0xc4a158d99f78dcf68ad8a3e9e26e4b8bad8b8a631dd09661ea09fdac23a0729a
傳入的數據的預期打包結構如下:
ff - operId ffffffffff - txId 6bc84f6a0fabbd7102be338c048fe0ae54948c2e - forwardAddress 6bc84f6a0fabbd7102be338c048fe0ae54948c2e - refundAddress
從我在上面連結的交易中可以看到,以精確順序和預期順序接收的參數。
contract StoForwarder is Controllable { constructor(address _controller, address _controllerAgent) public Controllable(_controller, _controllerAgent) {} event NewTask(bytes5 txId, address forwardAddress, address refundAddress, address tokenContract, bytes32 partition, uint256 amount); struct Task { bytes5 txId; address forwardAddress; address refundAddress; IERC1410 tokenContract; bytes32 partition; uint256 amount; } mapping (bytes5 => Task) public pendingTasks; function callback(IERC1410 _stoContract, bytes32 _partition, uint256 _amount, bytes calldata _data) external { require(_data.length >= 46, "Insufficient data provided"); byte operCode; bytes5 txId; address forwardAddress; address refundAddress; (operCode, txId, forwardAddress, refundAddress) = abi.decode(_data, (byte, bytes5, address, address)); require(txId != "", "TransactionId not specified"); require(_partition != "", "Bad Partition"); require(forwardAddress != address(0), "Bad Forward Address"); require(refundAddress != address(0), "Bad refund Address"); pendingTasks[txId].txId = txId; pendingTasks[txId].forwardAddress = forwardAddress; pendingTasks[txId].refundAddress = refundAddress; pendingTasks[txId].tokenContract = _stoContract; pendingTasks[txId].partition = _partition; pendingTasks[txId].amount = _amount; emit NewTask(txId, forwardAddress, refundAddress, address(_stoContract), _partition, _amount); } function controllerTransfer(bytes5 txId, bool forward) onlyController external { require(pendingTasks[txId].txId != ""); Task storage task = pendingTasks[txId]; address targetAddress; if (forward) { targetAddress = task.forwardAddress; } else { targetAddress = task.refundAddress; } task.tokenContract.transferByPartition(task.partition, targetAddress, task.amount, ""); } }
PS 一個完全的菜鳥問題:如何
require()
在區塊鏈上發生錯誤消息後讀取它?這部分讓我有點難以理解。
您的輸入不是 ABI 編碼的。這些值的正確 ABI 編碼如下:
0xff00000000000000000000000000000000000000000000000000000000000000ffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000006bc84f6a0fabbd7102be338c048fe0ae54948c2e0000000000000000000000006bc84f6a0fabbd7102be338c048fe0ae54948c2e
在 ABI 編碼中,幾乎所有內容都被編碼為 32 個字節的長度。固定長度的字節序列(如
byte
和bytes5
)右填充零,數字類型(如address
)左填充零。數組類型有點複雜,但在這個例子中你沒有這些類型。