Solidity:如何用彙編替換字節片?
我是組裝的新手,並且在使用它編寫我的第一個程式碼時,所以如果我對我想要完成的事情還有很長的路要走,請原諒我。
這是我的程式碼:
// 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,它是使用程序集替換的”。我希望這回答了你的問題。