How to convert B512 type to u64 type

  • I want to convert B512 type to u64 , I can convert B512 to u256 succesfully , But I am getting issues while converting B512 to u64
 fn b512_to_u64(value: B512) -> Option<u64> {
    // Extract the lower 256 bits from the B512 value
    let b_256 = value.bits()[0];
    let u_256 = b_256.as_u256();
    let u_64 = <u64 as TryFrom<u256>>::try_from(u_256);
    u_64
}
  • This is the error
 /home/divy/fuel-lync/Fuel-Contracts/lootbox/src/main.sw:165:49
    |
163 | 
164 |     let u_256 = b_256.as_u256();
165 |     let u_64 = <u64 as TryFrom<u256>>::try_from(u_256);
    |                                                 ^^^^^ This parameter was declared as type u64, but argument of type u256 was provided.
166 |     u_64
167 | }

Is there any way to convert B512 to u64?

  • fuelup show output
   Default host: x86_64-unknown-linux-gnu
fuelup home: /home/divy/.fuelup

Installed toolchains
--------------------
latest-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu
testnet-x86_64-unknown-linux-gnu (override)

active toolchain
----------------
testnet-x86_64-unknown-linux-gnu (override), path: /home/divy/fuel-lync/Fuel-Contracts/lootbox/fuel-toolchain.toml
 forc : 0.61.2
   - forc-client
     - forc-deploy : 0.61.2
     - forc-run : 0.61.2
   - forc-crypto : 0.61.2
   - forc-debug : 0.61.2
   - forc-doc : 0.61.2
   - forc-fmt : 0.61.2
   - forc-lsp : 0.61.2
   - forc-tx : 0.61.2
   - forc-wallet : 0.8.1
 fuel-core : 0.31.0
 fuel-core-keygen : 0.31.0

fuels versions
--------------
forc : 0.64.0
forc-wallet : 0.64.0

1 Like

To convert a B512 type to u64 , you would need to extract the bytes and then convert those bytes to u64 .

Here’s how you can extract the lower 64 bits from the B512 type and convert it to u64

fn b512_to_u64(value: B512) -> Option<u64> {
    // Extract the lower 256 bits from the B512 value
    let b_256 = value.bytes[0];
    let u_256 = b_256.0; // Extract the inner [u8; 32] array

    // Convert the first 8 bytes to u64
    let mut bytes = [0u8; 8];
    bytes.copy_from_slice(&u_256[0..8]);
    Some(u64::from_le_bytes(bytes))
}

Here, I have adjusted slice value to convert the first 8 bytes of the lower b256 value to u64 . Adjust the slice accordingly if you need a different part of the b256 value.

Please check this out and lmk how it goes.

1 Like
  • I think bytes[0] is not a valid function is sway-lib-std
let b_256 = value.bytes[0];

but I can find this in sway-std-lib to convert B512 to bytes

let b_256 = value.bits()[0];

as mentioned HERE

  • Also copy_from_slice() is is there in rust but I cannot find that function in sway
bytes.copy_from_slice(&u_256[0..8]);

This compiles for me on forc v0.61.2

fn b512_to_u64(b512: B512) -> Option<u64> {
    // Loss of precision
    if b512.bits()[0] != b256::zero() {
        return None;
    }

    // Extract the lower 256 bits from the B512 value
    let lower_u_256 = b512.bits()[1].as_u256();
    <u64 as TryFrom<u256>>::try_from(lower_u_256)
}

#[test]
fn convert() {
    let my_b512 = B512::zero();

    let my_u64 = b512_to_u64(my_b512);
    assert(my_u64.is_some());
}
 // Loss of precision
    if b512.bits()[0] != b256::zero() {
        return None;
    }

  • Why do we need this ?
  • I am trying to use this solution for converting the B512 random number I got from VRF to u64
Transaction Id(request):  0x18fe0a3ec7fe10f49e1aa78c0c9cc9258325a3a8258a8c361bc9b435f9c0e7de
random number (seed1):  0xed608a702150f07b52924bd7021358040c5e8d7925db8c31121e569b9892168cbd56a63638dc78eacabc1cf13f6afe8bb74f8e75623f2ae28f7118bb7a935d29
Number is  undefined
  • As u can see above , I cannot convert this random number to u64 using this code
fn convert(num :B512) -> Option<u64> {
        // Loss of precision
        if num.bits()[0] != b256::zero() {
            return None;
        }

        // Extract the lower 256 bits from the B512 value
        let lower_u_256 = num.bits()[1].as_u256();
        <u64 as TryFrom<u256>>::try_from(lower_u_256)
    }
const random_number :any= await contract.functions.get_random_number(seed1)
  .addContracts([Vrf])
  .get();
  console.log(`random number (seed1):  ${random_number.value}`);

  const num = await contract.functions.convert(random_number.value).get();

  console.log("Number is ",num.value);


You are trying to downsize a type with 512 bits to 64 bits. A u64 cannot hold nearly as much data as a B512 for this reason. As such you need to make sure you’ve not exceeded u64::max() by using any of the upper 256 bits with the if statement and the lower 256 bits are handled in the TryFrom statement.