Skip to content

v0.25.0

Compare
Choose a tag to compare
@digorithm digorithm released this 03 Oct 21:44
· 432 commits to master since this release
2ce1ceb

What's Changed

Full Changelog: v0.24.0...v0.25.0

New features

Logs and events parsing

The SDK can now parse logs and events with all types (including custom types), as opposed to only binary data.

We’ve introduced two ways to get these typed logs/events:

First, with type-specific log fetching, contract_instance.logs_with_type::<T>:

setup_contract_test!(
    contract_instance,
    wallet,
    "packages/fuels/tests/test_projects/logged_types"
);

let contract_methods = contract_instance.methods();
let response = contract_methods.produce_logs_values().call().await?;

let log_u64 = contract_instance.logs_with_type::<u64>(&response.receipts)?;
let log_u32 = contract_instance.logs_with_type::<u32>(&response.receipts)?;
let log_u16 = contract_instance.logs_with_type::<u16>(&response.receipts)?;
let log_u8 = contract_instance.logs_with_type::<u8>(&response.receipts)?;

This way, you’ll retrieve all logs that happened in that contract_instance that match the type <T>.

Second, if you want to retrieve all logs, in a stringified way, you can use fetch_logs():

let contract_methods = contract_instance.methods();
let response = contract_methods.produce_multiple_logs().call().await?;
let logs = contract_instance.fetch_logs(&response.receipts);

Vec support (input only)

The long waited Vec support is finally here, partially at least. You can now pass Vec to ABI methods that take dynamically-sized vectors. For instance:

let methods = contract_instance.methods();
{
    // vec of u32s
    let arg = vec![0, 1, 2];
    methods.u32_vec(arg).call().await?;
}
{
    // vec of vecs of u32s
    let arg = vec![vec![0, 1, 2], vec![0, 1, 2]];
    methods.vec_in_vec(arg.clone()).call().await?;
}
{
    // vec of structs
    let arg = vec![SomeStruct { a: 0 }, SomeStruct { a: 1 }];
    methods.struct_in_vec(arg.clone()).call().await?;
}

However, we don’t yet support Vec as return values; this will be coming up very soon!

New script crafting interface

Manually creating scripts just became a bit easier with the new API for crafting scripts:

ScriptBuilder::new()
        .set_gas_price(tx_parameters.gas_price)
        .set_gas_limit(tx_parameters.gas_limit)
        .set_maturity(tx_parameters.maturity)
        .set_script(script)
        .set_script_data(script_data)
        .set_inputs(inputs.to_vec())
        .set_outputs(outputs.to_vec())
        .set_amount(amount)
        .build(&wallet)
        .await?
        .call(wallet.get_provider()?)
        .await?;

Support for script’s main arguments are coming up soon.

Breaking changes

The new methods() interface

TLDR:

  1. Remove .build() from your contract instantiation statement (MyContractBuilder::new(…).build()MyContractBuilder::new(...))
  2. Chain .methods() before accessing the desired method from your contract (contract_instance.my_method().call()contract_instance.methods().my_method().call())

Longer explanation motivation behind this change:

Before this release, users relied on the builder .build() method when constructing a new contract instance. For instance:

let contract_instance = MyContractBuilder::new(contract_id.to_string(), wallet).build();

Access to contract_instance methods was done directly:

let transaction_cost = contract_instance
            .initialize_counter(42)
            .call()
            .await?;

This was causing one big problem: conflict between ABI methods and contract instance specific methods generated by the SDK (_get_wallet(), _get_contract_id(), and so on.)

Notice how, to mitigate the issue, the SDK was prepending _ before the method name, but this isn’t sustainable for too long.

To resolve this problem, we’ve removed the need to chain .build() when creating a contract instance, and now, when accessing ABI methods, you must chain .methods() to access all the ABI methods. To get SDK generated methods bound to the contract instance, you can do it directly. For instance:

abigen!(
        SimpleContract,
        "packages/fuels/tests/takes_ints_returns_bool-abi.json",
    );

    let wallet = launch_provider_and_get_wallet().await;

    // `SimpleContract` is the name of the contract.
    // No more `.build()` here.
    let contract_instance = SimpleContract::new(null_contract_id(), wallet);
	
		// `.methods()` before accessing the actual method. The rest
    // follows as usual.
    let call_handler = contract_instance.methods().takes_ints_returns_bool(42);