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.
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:
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.
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.