This guide explains how to work with a Script that rely on in-code signature validation. This is particularly useful when you need to verify that a transaction was authorized by a specific account.
Here's an example of a Sway script that validates signatures:
script;
use std::{b512::B512, ecr::ec_recover_address, tx::{tx_id, tx_witness_data}};
fn main(signer: b256, witness_index: u64) -> bool {
let witness_data: B512 = tx_witness_data(witness_index).unwrap();
let address: b256 = ec_recover_address(witness_data, tx_id()).unwrap().bits();
return address == signer;
}
This script:
true
or false
based on the validation result On Fuel, transaction signing involves using a wallet's private key to create a hash based on the transaction ID (which is the same as the transaction hash ). The transaction ID is generated by hashing the transaction bytes themselves.
Important considerations:
When working with Sway programs that have in-code signature validation, the estimation process becomes more complex because:
Here's how to properly implement a transaction with signature validation for this specific Sway script:
// Instantiate the script
const script = new ScriptSigning(signer);
/**
* Witness index in which we will add the signature, since there will only be
* one witness in this transaction request
*/
const witnessIndex = 0;
// Creating the scope invocation to be used later
const request = await script.functions
.main(signer.address.toB256(), witnessIndex)
.getTransactionRequest();
// Signing the transaction request before estimation
let signature = await signer.signTransaction(request);
// Adding the signature to the transaction request
request.addWitness(signature);
/**
* Uses `assembleTx` to estimate and fund the transaction request.
* Because the transaction only requires enough to cover the fee, there's no
* need to pass any `accountCoinQuantities` to the `assembleTx` function.
*/
const { assembledRequest } = await provider.assembleTx({
request,
feePayerAccount: signer,
});
// Signing the request again as the it was modified during estimation and funding
signature = await signer.signTransaction(assembledRequest);
// Updating the signature in the assembled request
assembledRequest.updateWitness(witnessIndex, signature);
// Sending the transaction request
const submit = await signer.sendTransaction(assembledRequest);
// Getting the result of the transaction
const { isStatusSuccess } = await submit.waitForResult();