Solidity

參數過多的呼叫數據

  • January 26, 2019

在閱讀https://solidity.readthedocs.io/en/v0.4.21/abi-spec.html#abi時,我只是在想當 calldata 包含比函式預期更多的參數/數據時會發生什麼(我知道第一個參數是 4 個字節函式簽名的 Keccak256,所以這不會偶然發生)。只是你可以使用任意的 msg.data。我相信那些額外的字節應該被默默地忽略(從不引用)還是我弄錯了?這意味著完全相同的函式呼叫可以以多種不同的方式進行編碼。

另外:如果動態數組“偏移”點超出給定參數(或大小大於提供值的實際數量),會發生什麼情況。你能想像所有未定義的東西都是 0,或者這樣的技巧會拋出異常嗎?

是的,額外的 calldata 字節將被忽略,是的,超過長度末尾的 calldata 讀取為 0。

添加到 smarx 的答案(額外的 calldata 被忽略):

另外:如果動態數組“偏移”點超出給定參數(或大小大於提供值的實際數量),會發生什麼情況。你能想像所有未定義的東西都是 0,或者這樣的技巧會拋出異常嗎?

對於字節/字元串/數組等動態大小對象,如果大小大於 calldata 中提供的值的數量,您將獲得 REVERT。

您可以使用以下程式碼在 Remix 中自行測試:

pragma solidity ^0.5.0;

contract X {
   event E(bytes data);

   function b(bytes memory _b) public {
       emit E(msg.data);
   }
}

contract Test {
   event E(bytes data);

   X x = new X();

   function b(bytes memory _b) public payable {

       emit E(msg.data);

       // shorten calldata by 30 bytes
       bytes memory callData = new bytes(msg.data.length-30);

       for(uint i=0; i<callData.length && i<msg.data.length; i++) {
           callData[i] = msg.data[i];
       }

       // this will work fine as long as _b.length <= 2
       (bool res, bytes memory ret) = address(x).call(callData);

       assert(res);
   }

}

引用自:https://ethereum.stackexchange.com/questions/66070