Call response

You've probably noticed that you're often chaining .call().await.unwrap(). That's because:

  1. You have to choose between .call() and .simulate() (more on this in the next section).
  2. Contract calls are asynchronous, so you can choose to either .await it or perform concurrent tasks, making full use of Rust's async.
  3. .unwrap() the Result<CallResponse, Error> returned by the contract call.

Once you unwrap the CallResponse, you have access to this struct:

pub struct CallResponse<D> {
    pub value: D,
    pub receipts: Vec<Receipt>,
    pub gas_used: u64,
    pub log_decoder: LogDecoder,
    pub tx_id: Option<Bytes32>,
}

Where value will hold the value returned by its respective contract method, represented by the exact type returned by the FuelVM, E.g., if your contract returns a FuelVM's u64, value's D will be a u64. If it's a FuelVM's tuple (u8,bool), then D will be a (u8,bool). If it's a custom type, for instance, a Sway struct MyStruct containing two components, a u64, and a b256, D will be a struct generated at compile-time, called MyStruct with u64 and a [u8; 32] (the equivalent of b256 in Rust).

  • receipts will hold all receipts generated by that specific contract call.
  • gas_used is the amount of gas consumed by the contract call.
  • tx_id will hold the ID of the corresponding submitted transaction.

Error handling

You can use the is_ok and is_err methods to check if a contract call Result is Ok or contains an error. These methods will return either true or false.

let is_ok = response.is_ok();
let is_error = response.is_err();

If is_err returns true, you can use the unwrap_err method to unwrap the error message.

if response.is_err() {
    let err = response.unwrap_err();
    println!("ERROR: {:?}", err);
};