Icon SunFilledIcon MoonStars

Icon LinkCustom Transactions

There may be scenarios where you need to build out transactions that involve multiple program types and assets; this can be done by instantiating a ScriptTransactionRequest. This class allows you to a append multiple program types and assets to a single transaction.

Consider the following script that transfers multiple assets to a contract:

script;
 
use std::token::force_transfer_to_contract;
 
fn main(
contract_address: b256,
asset_a: AssetId,
amount_asset_a: u64,
asset_b: AssetId,
amount_asset_b: u64,
) -> bool {
let wrapped_contract = ContractId::from(contract_address);
 
force_transfer_to_contract(wrapped_contract, asset_a, amount_asset_a);
force_transfer_to_contract(wrapped_contract, asset_b, amount_asset_b);
true
}

This script can be executed by creating a ScriptTransactionRequest, appending the resource and contract inputs/outputs and then sending the transaction, as follows:

import type { BN, CoinQuantityLike, ScriptTransactionRequest } from 'fuels';
 
// 1. Create a script transaction using the script binary
const request = new ScriptTransactionRequest({
	...defaultTxParams,
	gasLimit: 3_000_000,
	script: scriptBin,
});
 
// 2. Instantiate the script main arguments
const scriptArguments = [contract.id.toB256(), assetIdA, new BN(1000), assetIdB, new BN(500)];
 
// 3. Get the resources for inputs and outpoints
const { gasPriceFactor } = contract.provider.getGasConfig();
const fee = request.calculateFee(gasPriceFactor);
const quantities: CoinQuantityLike[] = [[1000, assetIdA], [500, assetIdB], fee];
const resources = await wallet.getResourcesToSpend(quantities);
 
// 4. Populate the script data and inputs/outputs
request
	.setData(abiContents, scriptArguments)
	.addContractInputAndOutput(contract.id)
	.addResources(resources);
 
// 5. Send the transaction
const tx = await wallet.sendTransaction(request);
await tx.waitForResult();
 

Was this page helpful?