macro_rules! script_with_data_offset { ($offset:ident, $script:expr, $tx_offset:expr) => { ... }; }
Expand description
A utility macro for writing scripts with the data offset included. Since the script data offset depends on the length of the script, this macro will evaluate the length and then rewrite the resultant script output with the correct offset (using the offset parameter).
ยงExample
use fuel_asm::{op, RegId};
use fuel_types::{Immediate18, Word, canonical::Serialize};
use fuel_vm::prelude::{Call, TxParameters, ContractId, Opcode};
use fuel_vm::script_with_data_offset;
use itertools::Itertools;
// Example of making a contract call script using script_data for the call info and asset id.
let contract_id = ContractId::from([0x11; 32]);
let call = Call::new(contract_id, 0, 0).to_bytes();
let asset_id = [0x00; 32];
let transfer_amount: Word = 100;
let gas_to_forward = 100_000;
let script_data = [call.as_ref(), asset_id.as_ref()]
.into_iter()
.flatten()
.copied()
.collect_vec();
// Use the macro since we don't know the exact offset for script_data.
let (script, data_offset) = script_with_data_offset!(
data_offset,
vec![
// use data_offset to reference the location of the call bytes inside script_data
op::movi(0x10, data_offset),
op::movi(0x11, transfer_amount as Immediate18),
// use data_offset again to reference the location of the asset id inside of script data
op::movi(0x12, data_offset + call.len() as Immediate18),
op::movi(0x13, gas_to_forward as Immediate18),
op::call(0x10, 0x11, 0x12, 0x13),
op::ret(RegId::ONE),
],
TxParameters::DEFAULT.tx_offset()
);