Encoding
Be sure to read the prerequisites to encoding.
Encoding is done via the ABIEncoder
:
use fuels::{
core::{codec::ABIEncoder, traits::Tokenizable},
macros::Tokenizable,
types::unresolved_bytes::UnresolvedBytes,
};
#[derive(Tokenizable)]
struct MyStruct {
field: u64,
}
let instance = MyStruct { field: 101 };
let encoded: UnresolvedBytes = ABIEncoder::default().encode(&[instance.into_token()])?;
let load_memory_address: u64 = 0x100;
let _: Vec<u8> = encoded.resolve(load_memory_address);
Note that the return type of encode
is UnresolvedBytes
. The encoding cannot be finished until we know at which memory address this data is to be loaded. If you don't use heap types (::std::vec::Vec
, ::fuels::types::Bytes
, ::std::string::String
), then you can safely .resolve(0)
to get the encoded bytes.
There is also a shortcut-macro that can encode multiple types which implement Tokenizable
:
use fuels::{core::codec::calldata, macros::Tokenizable};
#[derive(Tokenizable)]
struct MyStruct {
field: u64,
}
let _: Vec<u8> = calldata!(MyStruct { field: 101 }, MyStruct { field: 102 })?;
Note: The above example will call
.resolve(0)
. Don't use it if you're encoding heap types.
Configuring the encoder
The encoder can be configured to limit its resource expenditure:
use fuels::core::codec::ABIEncoder;
ABIEncoder::new(EncoderConfig {
max_depth: 5,
max_tokens: 100,
max_total_enum_width: 10_000,
});
The default values for the EncoderConfig
are:
impl Default for EncoderConfig {
fn default() -> Self {
Self {
max_depth: 45,
max_tokens: 10_000,
max_total_enum_width: 10_000,
}
}
}
Configuring the encoder for contract/script calls
You can also configure the encoder used to encode the arguments of the contract method:
let _ = contract_instance
.with_encoder_config(EncoderConfig {
max_depth: 10,
max_tokens: 2_000,
max_total_enum_width: 10_000,
})
.methods()
.initialize_counter(42)
.call()
.await?;
The same method is available for script calls.