I brand new to assembly, and just at the point of writing my first code using it, so please excuse me if I am way off on what I am trying to accomplish.
Here is my code:
// 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);
}
}
The output looks like this:
0:
string: The input _id is 123456 assembly
1:
bytes: 0x54686520696e707574205f696420697320313233343536000000000000000000000000000000000000000000000000000020617373656d626c79
So I can tell that what it did was store the 6 bytes of _id, plus another 26 null bytes for a total of 32 bytes replaced.
Is it possible to do this without those additional 26 null bytes? Note I am not looking to do this iteratively as the real case will be a much larger string with many more replacements.
Best Answer
As I said in the comments, it's totally possible. Here is a simple version working only with bytes6, let me know if you are interested in a more generic "slice assignment" piece of code handling various lengths.
The idea is simply to clear the leading first 6 bytes of the existing data with the
and
operator and the appropriate mask (0x000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
in this case, equivalent tonot(shl(208, 0xFFFFFFFFFFFF))
) and then combining your id (which is actually a left aligned 32 bytes value) with the result of the previous operation with theor
operator.To put it simply, it replace the first 6 bytes at
add(b, 49
by the first 6 bytes of_id
. All other bytes are left unchanged.The result is
0x54686520696e707574205f69642069732031323334353620616e6420697420776173207265706c61636564207573696e6720617373656d626c79
, in ASCII : "The input _id is 123456 and it was replaced using assembly".I hope this answers your question.