Solidity

Solidity:如何用彙編替換字節片?

  • July 20, 2022

我是組裝的新手,並且在使用它編寫我的第一個程式碼時,所以如果我對我想要完成的事情還有很長的路要走,請原諒我。

這是我的程式碼:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


contract Test {
   function starter() public pure returns(string memory, bytes memory) {
       bytes6 _id = '123456';
       bytes memory b = 'The input _id is ______ and it was replaced using assembly';

       assembly {
           mstore(add(b, 49), _id)
       }

       return (string(b), b);
   }
}

輸出如下所示:

0:
string: The input _id is 123456 assembly
1:
bytes: 0x54686520696e707574205f696420697320313233343536000000000000000000000000000000000000000000000000000020617373656d626c79

所以我可以看出它所做的是儲存 _id 的 6 個字節,加上另外 26 個空字節,總共替換了 32 個字節。

**如果沒有額外的 26 個空字節,是否可以做到這一點?**請注意,我不希望迭代地執行此操作,因為實際情況將是一個更大的字元串,並且有更多的替換。

如果沒有額外的 26 個空字節,是否可以做到這一點?請注意,我不希望迭代地執行此操作,因為實際情況將是一個更大的字元串,並且有更多的替換。

正如我在評論中所說,這是完全可能的。這是一個僅使用 bytes6 的簡單版本,如果您對處理各種長度的更通用的“切片分配”程式碼感興趣,請告訴我。

這個想法只是用and運算符和適當的遮罩(0x000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF在這種情況下,相當於not(shl(208, 0xFFFFFFFFFFFF)))清除現有數據的前 6 個字節,然後將您的 id (實際上是左對齊的 32 字節值)與結果相結合與操作員的先前操作or

簡單來說,就是將 at 的前 6 個字節替換為 的前 6 個add(b, 49字節_id。所有其他字節保持不變。

assembly {
   mstore(add(b, 49), or(and(mload(add(b, 49)), not(shl(208, 0xFFFFFFFFFFFF))), _id))
}

結果是0x54686520696e707574205f69642069732031323334353620616e6420697420776173207265706c61636564207573696e6720617373656d626c79,在 ASCII 中:“輸入 _id 是 123456,它是使用程序集替換的”。

我希望這回答了你的問題。

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