2

Let's say I have a string list of parameters

["Example String", "vitalikbuterin", "1000"]

How can I encode this list into a bytes object, and then decode the bytes to get the exact same list?

4 Answers 4

1

You could convert string arrays to bytes where each byte is a character and you can use byte 0x00 as a separator.

Here's a contract with the 2 methods you need to pack or unpack a string[] memory to/from a bytes memory

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.18;

contract StringsAndBytes {
    function packString(string[] memory list) external pure returns (bytes memory){
        bytes memory packedArray;
        if (list.length == 0) {
            return packedArray;
        }
        packedArray = abi.encodePacked(list[0]);
        for (uint i = 1; i < list.length; i++) {
            packedArray = abi.encodePacked(packedArray, hex"00", list[i]);
        }
        return packedArray;
    }

    function unpackString(bytes memory pack) external pure returns (string[] memory) {
        if (pack.length == 0) {
            string[] memory emptyArray;
            return emptyArray;
        }
        uint256 elementCount = 1;
        for (uint i = 0; i < pack.length; i++) {
            if (pack[i] == 0x00) {
                elementCount++;
            }
        }
        string[] memory list = new string[](elementCount);
        uint256 arrayIndex = 0;
        string memory element = "";
        for (uint i = 0; i < pack.length; i++) {
            if (pack[i] == 0x00) {
                list[arrayIndex] = element;
                element = "";
                arrayIndex++;
                continue;
            }
            element = string(abi.encodePacked(element, pack[i]));
        }
        list[arrayIndex] = element;
        return list;
    }
}

Now if I call

packString(["Example String", "vitalikbuterin", "1000"])

I get: 0x4578616d706c6520537472696e6700766974616c696b6275746572696e0031303030

Then i can call

unpackString("0x4578616d706c6520537472696e6700766974616c696b6275746572696e0031303030")

I get ["Example String", "vitalikbuterin", "1000"]

Edit: Simpler but non-packed

I had never used abi.decode before in my life. I made this answer, then I thought I'd ask an AI that shall not be named, it gave me a much simpler almost working code (that I fixed) but the resulting bytes end up with a lot of zeroes:

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

contract StringsAndBytesByAI {
    function encodeStringList(string[] memory stringList) public pure returns (bytes memory) {
        return abi.encode(stringList);
    }

    function decodeStringList(bytes memory encodedList) public pure returns (string[] memory) {
        string[] memory decodedList = abi.decode(encodedList, (string[]));
        
        return decodedList;
    }
}

calling

encodeStringList(["Example String", "vitalikbuterin", "1000"])

gives the following result:

0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000e4578616d706c6520537472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e766974616c696b6275746572696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043130303000000000000000000000000000000000000000000000000000000000

And it can be reversed:

decodeStringList("0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000e4578616d706c6520537472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e766974616c696b6275746572696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043130303000000000000000000000000000000000000000000000000000000000")

Result: ["Example String", "vitalikbuterin", "1000"]

If you need to optimize for storage, use the first one, if you need to optimize for computation, use the second one.

0

Hello you can use this website to encode https://www.rapidtables.com/convert/number/hex-to-decimal.html

0

Batching a list into a single bytes object can be done by using the encode_abi() function from Solidity. This function takes a list of elements and returns a bytes object with the data stored in the proper format.

1
  • Are you confusing it with _abi_encode() from Vyper? It's called abi.encode() in Solidity.
    – cameel
    Mar 26 at 19:25
0

To batch list into a single bytes object, you can use the "bytearray" function in Python. This function takes a list of values and returns a bytes object.

For example, if you have a list of numbers such as [1,2,3,4], you can create a bytes object using this code:

bytearray([1,2,3,4])

This will return a bytes object containing the values 1,2,3,4.

Your Answer

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

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