In the previous example we demonstrated how you can instantiate a ScriptTransactionRequest
to customize and build out a more complex transaction via a script. The same can be done using contracts, but this allows us to utilize functions available in the contract and access on-chain state. Allowing us to harness all of the power from an invocation scope and a transaction request.
This cookbook demonstrates how we can utilize a contract call to build out a custom transaction, allowing us to update on-chain state and transfer assets to a recipient address.
// #import { bn, Contract, buildFunctionResult };
const amountToRecipient = bn(10_000); // 0x2710
// Connect to the contract
const contractInstance = new Contract(contract.id, contract.interface, senderWallet);
// Create an invocation scope for the contract function you'd like to call in the transaction
const scope = contractInstance.functions.increment_counter(amountToRecipient).addTransfer({
amount: amountToRecipient,
destination: receiverWallet.address,
assetId: provider.getBaseAssetId(),
});
// Build a transaction request from the invocation scope
const transactionRequest = await scope.getTransactionRequest();
// Add coin output for the recipient
transactionRequest.addCoinOutput(
receiverWallet.address,
amountToRecipient,
provider.getBaseAssetId()
);
const txCost = await senderWallet.getTransactionCost(transactionRequest);
transactionRequest.gasLimit = txCost.gasUsed;
transactionRequest.maxFee = txCost.maxFee;
await senderWallet.fund(transactionRequest, txCost);
// Submit the transaction
const response = await senderWallet.sendTransaction(transactionRequest);
await response.waitForResult();
// Get result of contract call
const { value } = await buildFunctionResult({
funcScope: scope,
isMultiCall: false,
program: contract,
transactionResponse: response,
});
// <BN: 0x2710>