Solidity

“calldataload”中有哪些數據?

  • November 14, 2019

我想解析由下面顯示的契約生成的事件日誌,它將calldataload的不同部分分配給事件日誌的 4 個主題和數據部分。

主題 0 接收在 Solidity 中顯示的 FUNCTIONHASHES,但我不清楚其他 3 個主題和數據部分是如何分配的。

例如,以下函式使用note修飾符,它發出事件日誌。’ what ’ 和 ’ data ’ 的值將放在事件日誌中的什麼位置,以及事件日誌的 Data 部分中放置什麼?

function file(bytes32 what, uint256 data) external note {
   require(live == 1, "Pot/not-live");
   require(now == rho, "Pot/rho-not-updated");
   if (what == "dsr") dsr = data;
   else revert("Pot/file-unrecognized-param");
}

該合約發出事件日誌:

contract LibNote {
   event LogNote(
       bytes4   indexed  sig,
       address  indexed  usr,
       bytes32  indexed  arg1,
       bytes32  indexed  arg2,
       bytes             data
   ) anonymous;

   modifier note {
   _;
   assembly {
       // log an 'anonymous' event with a constant 6 words of calldata
       // and four indexed topics: selector, caller, arg1 and arg2
       let mark := msize                         // end of memory ensures zero
       mstore(0x40, add(mark, 288))              // update free memory pointer
       mstore(mark, 0x20)                        // bytes type data offset
       mstore(add(mark, 0x20), 224)              // bytes size (padded)
       calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
       log4(mark, 288,                           // calldata
            shl(224, shr(224, calldataload(0))), // msg.sig
            caller,                              // msg.sender
            calldataload(4),                     // arg1
            calldataload(36)                     // arg2
           )
      }
     }
   }

使用 remix.ethereum.org,這是一個可以提供幫助的範例。

在此處輸入圖像描述

input與 相同的calldata0x29ae811475944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1000000000000000000000000000000000000000000000000000000000000000f。(這是呼叫file( 0x75944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1, 15)

calldataload是用於獲取 32 個字節的 EVM 操作碼calldata

參數 tocalldataload是一個偏移量:通常前 4 個字節calldata是函式選擇器,因此calldataload(4)用於獲取從第 5 個字節開始的 32 個字節(在本例中為0x75944...)。

calldata(36)然後獲取下一個 32 字節,即 15 十六進制,填充uint到 32 字節,這就是它的樣子0x000...f

請參閱什麼是呼叫數據?以及calldata 如何儲存在記憶體中?的其他範例calldata

日誌是:

[
   {
       "from": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
       "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e029ae811475944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
       "topics": [
           "0x29ae811400000000000000000000000000000000000000000000000000000000",
           "0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c",
           "0x75944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1",
           "0x000000000000000000000000000000000000000000000000000000000000000f"
       ]
   }
]

最後兩個主題是what和的data論點file

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