Bytes

如何在彙編中獲取 bytes32 的最後 n 個字節?

  • May 4, 2020

我有以下程式碼:

function getBytes5() public returns (bytes5) {
   uint256 x = now;        
   bytes memory inBytes = new bytes(32);
   bytes5 outBytes5;
   assembly {
        mstore(add(inBytes, 32), x)
        outBytes5 := mload(add(add(inBytes, 27), 5))
   }
   return outBytes5;
}

它首先將區塊鏈時間戳儲存nowinBytes變數中,然後嘗試將其bytes32bytes5. 但是,我得到的結果是:

{
   "0": "bytes5": 0x0000000000
}

我的理解是mload載入給定地址的值並將返回變數add(add(inBytes, 27), 5)的最後 5 個字節。inBytes但也許那裡的某個地方有缺陷?

您的問題在於您要傳遞到的位置mload。的記憶體定址inBytes長度為32字節,其餘為數據。由於您在長度後的 32 個字節處儲存 uint256,因此記憶體映射將如下所示:

0x00 00 00 00 00 00 00 00 
0x00 00 00 00 00 00 00 20
0x00 00 00 00 00 00 00 00
0x00 00 00 00 5C 6E 24 39

當你呼叫 時mload,你傳入了add(add(inBytes, 27), 5),它只是 inBytes+32,它載入了上面十六進制的整個最後兩行。但是,強制轉換的工作方式是佔用最重要的字節。這就是為什麼outBytes5最終全為 0 的原因。它將這部分載入到變數中:

0x00 00 00 00 00 00 00 00

0x00 00 00 00 00 00 00 20

0x 00 00 00 00 00 00 00 00

0x00 00 00 00 5C 6E 24 39

要解決此問題,只需更改mload位置,使 5 個字節成為最重要的字節。這應該有效:

outBytes5 := mload(add(add(inBytes, 32), 27))

outBytes5在上面的範例中,這應該將 0x005C6E2439 載入到。

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