Skip to main content

Create a restoration footprint manually to restore archived data using the JavaScript SDK

In this guide, we'll create a utility method named createRestorationFootprint used for manually creating a restoration footprint and restore archived data in a contract.

First let's revisit how data is stored in a smart contract with the three different state archival types:

TemporaryInstancePersistent
Cheapest optionExpensive optionExpensive option
Deleted after TTL reaches 0Archived when TTL reaches 0Archived when TTL reaches 0
Cannot be restoredCan be restored using the RestoreFootprintOp operationCan be restored using the RestoreFootprintOp operation
Unlimited amount of storageLimited amount of storage availableUnlimited amount of storage

As seen above, all contract data is automatically archived when TTL reaches 0, except for Temporary entries, which are deleted permanently from the ledger.

Both types Instance and Persistent are suitable for storing data that cannot be easily recreated, with the nuance that Instance shares the same TTL as the contract instance while Persistent does not and, if the contract instance is not archived, Persistent data may be archived and need to be restored before invoking the contract.

For a detailed explanation of contract data archival, check out the State Archival section in the Encyclopedia.

import {
Contract,
Networks,
Keypair,
Operation,
TransactionBuilder,
xdr,
Address,
Account,
Transaction,
} from "@stellar/stellar-sdk";

async function createRestorationFootprint(
account: Account,
contractAddress: string,
fee: string,
dataKey: xdr.ScVal,
signer: Keypair,
) {
// Initialise contract & address
const contract: Contract = new Contract(contractAddress);
const address: Address = Address.fromString(contract.contractId());
// Setup contract data
const contractDataXDR = xdr.LedgerKey.contractData(
new xdr.LedgerKeyContractData({
contract: address.toScAddress(),
key: dataKey,
durability: xdr.ContractDataDurability.persistent(),
}),
);
// Prepare transaction data
const restoreData: xdr.SorobanTransactionData =
new xdr.SorobanTransactionData({
resources: new xdr.SorobanResources({
footprint: new xdr.LedgerFootprint({
readOnly: [],
readWrite: [contractDataXDR],
}),
instructions: 0,
readBytes: 0,
writeBytes: 0,
}),
resourceFee: xdr.Int64.fromString("0"),
// @ts-ignore
ext: new xdr.ExtensionPoint(0),
});
// Restore transaction with created restoration footprint
const restoreTx: Transaction = new TransactionBuilder(account, { fee: fee })
.setNetworkPassphrase(Networks.TESTNET)
.setSorobanData(restoreData)
.addOperation(Operation.restoreFootprint({}))
.build();

restoreTx.sign(signer);
}

Code walkthrough

As we're making use of Stellar SDK for JavaScript js-stellar-sdk, first we import the module.

Our function will require the following parameters:

  • account: The Stellar account from which the transaction will be sent.
  • contractAddress: The address of the contract to be restored.
  • fee: The fee for the transaction.
  • dataKey: The key for the contract data to be restored.
  • signer: The keypair that will sign the transaction.

After we initialize contract and address instances, we create an XDR representation of the contract data which includes:

  • contract: The contract address.
  • key: The key for the contract data.
  • durability: Specifies that the contract data is persistent - we assume it's Persistent.

Next up we are preparing the (Soroban) transaction data with:

  • resources: Specifies the resources needed for the transaction.
  • footprint: Defines which parts of the ledger will be read and written.
  • instructions, readBytes, writeBytes: Sets the resource limits (all set to 0 here).
  • resourceFee: Sets the resource fee to 0 (placeholder).
  • ext: Extension point for future use (set to 0).

Note that for restoration footprints we only need to fill in reaWrite.

The transaction can now be submitted to the Stellar (test) network & signed to restore the specified contract’s data.