Be sure to read the prerequisites to decoding.
Decoding is done via the ABIDecoder
:
use fuels::{
core::{
codec::ABIDecoder,
traits::{Parameterize, Tokenizable},
},
macros::{Parameterize, Tokenizable},
types::Token,
};
#[derive(Parameterize, Tokenizable)]
struct MyStruct {
field: u64,
}
let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];
let token: Token = ABIDecoder::default().decode(&MyStruct::param_type(), bytes)?;
let _: MyStruct = MyStruct::from_token(token)?;
First into a Token
, then via the Tokenizable
trait, into the desired type.
If the type came from abigen!
(or uses the ::fuels::macros::TryFrom
derivation) then you can also use try_into
to convert bytes into a type that implements both Parameterize
and Tokenizable
:
use fuels::macros::{Parameterize, Tokenizable, TryFrom};
#[derive(Parameterize, Tokenizable, TryFrom)]
struct MyStruct {
field: u64,
}
let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];
let _: MyStruct = bytes.try_into()?;
Under the hood, try_from_bytes
is being called, which does what the preceding example did.
The decoder can be configured to limit its resource expenditure:
use fuels::core::codec::ABIDecoder;
ABIDecoder::new(DecoderConfig {
max_depth: 5,
max_tokens: 100,
});
For an explanation of each configuration value visit the DecoderConfig
.
The default values for the DecoderConfig
are:
impl Default for DecoderConfig {
fn default() -> Self {
Self {
max_depth: 45,
max_tokens: 10_000,
}
}
}
You can also configure the decoder used to decode the return value of the contract method:
let _ = contract_instance
.methods()
.initialize_counter(42)
.with_decoder_config(DecoderConfig {
max_depth: 10,
max_tokens: 20_00,
})
.call()
.await?;
The same method is available for script calls.