How can I transform b256 into [u8; 32]?

I’m getting a b256 as a result of hashing and I need to manipulate the output data.

Can’t really find any way to “use” b256 (masking, shifting so I can pull out a byte or something), so now I came up with the solution to just transform it into the byte array. How can I do that?

If there are other (better) ways to use the separate bytes of the b256 that would be interesting too.

The sway-lib-core library has the following function which is not pub but can be copied into your own project for now:

fn decompose(val: b256) -> (u64, u64, u64, u64) {
    asm(r1: __addr_of(val)) { r1: (u64, u64, u64, u64) }
}

This is not exactly what you need here though but close enough as you now have the 4 u64s that compose the b256. You can then modify them with bit shifts and masks and then compose a new b256 using:

fn compose(words: (u64, u64, u64, u64)) -> b256 {
    asm(r1: __addr_of(words)) { r1: b256 }
}

Now the above can probably be extended to return an array of u8 but arrays are not packed which means that each u8 in the array is represented as a word, which makes this a bit more complicated. Instead, we now have the Bytes type in the standard library which can be used instead. We could do things like (credit to @furnic for Add the `Packable` trait by nfurfaro · Pull Request #3630 · FuelLabs/sway · GitHub which inspired the code below):

    fn from_bytes(bytes: Bytes) -> b256 {
        let mut b = 0x0000000000000000000000000000000000000000000000000000000000000000;
        let ptr = __addr_of(b);
        bytes.buf.ptr().copy_to::<b256>(ptr, 1);

        b
    }

    fn into_bytes(b: b256) -> Bytes {
        let mut bytes = Bytes::with_capacity(32);
        bytes.len = 32;

        // Copy bytes from contract_id into the buffer of the target bytes
        __addr_of(b).copy_bytes_to(bytes.buf.ptr, 32);

        bytes
    }

With the into_bytes function, you can convert your b256 into Bytes which is packed, then make your changes, and then call from_bytes to generate a new b256.

Note that all the above will be made possible in the future directly in the standard library.

4 Likes

Also, std::sway-lib-core does have bitwise operations (&, |, ^, << and >>) implemented for b256, but as @mohammadfawaz said, converting b256 to Bytes will most likely be more ergononmic, depending on what you need to do with the values.

2 Likes

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.