2

This is related to this question here: Solidity: how to replace slices of bytes with assembly?

Although with one extra part: I'd like to be able to replacement with a slice and not the entire input bytes array. The closest I've been able to get is the following:

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


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

        assembly {
            let dst := add(b, 49)
            mstore(dst, or(and(mload(dst), not(shl(208, 0x0000FFFF0000))), _id))
        }

        return (string(b), b);
    }

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

        assembly {
            let dst := add(b, 49)
            mstore(dst, or(and(mload(dst), not(shl(224, 0xFFFF))), _id))
        }

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

Both output the following:

"0": "string: The input _id is 34 and it was replaced using assembly"

But I want it to output:

"0": "string: The input _id is __34__ and it was replaced using assembly"

So you can see that the underscores were cleared out. I've tried playing around with _id and trying to mask it, although almost anything I try results in a out of gas error. Any help on this one would be much appreciated - thanks!

1 Answer 1

1

I'm going answer this as I found a solution. I based on it what was done in the slice method here: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol, along with a combination of the prior post mentioned in the question.

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


        assembly {
            let src := add(_id, 32)
            let dest := add(b, 49)

            let mask := shl(208, 0x0000FFFF0000)

            let srcpart := and(src, mask)
            // let srcpart := and(mload(src), mask) <--- causes out of gas
            let destpart := and(mload(dest), not(mask))

            mstore(dest, or(destpart, srcpart))
        }

        return (string(b), b);
    }

Outputs:

"0": "string: The input _id is __34__ and it was replaced using assembly"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.