Skip to content

Commit

Permalink
Extend-wasm-ttl (#888)
Browse files Browse the repository at this point in the history
* extend footprint operation

* format doc

* use absolute link to extend ttl op

* Editorial and links

* explain more about soroban data

* chore: Improve documentation on extending Soroban TTL

---------

Co-authored-by: Bri <[email protected]>
  • Loading branch information
Myestery and briwylde08 authored Aug 27, 2024
1 parent 1377e24 commit 6048e91
Showing 1 changed file with 110 additions and 0 deletions.
110 changes: 110 additions & 0 deletions docs/build/guides/conventions/extending-wasm-ttl.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: Extend a deployed contract’s TTL with code
description: How to extend the TTL of a deployed contract's Wasm code using JavaScript SDK
---

# Extending a deployed contract’s TTL using code

When a smart contract is deployed on the Stellar network, its WebAssembly (Wasm) code has a [Time To Live (TTL)](../../../learn/encyclopedia/storage/state-archival.mdx#ttl) that determines how long it remains accessible.

The TTL is the number of ledgers between the current ledger and the final ledger for which the contract data can still be accessed. If the TTL expires, the contract's code becomes archived and inaccessible. To prevent this, you need to periodically extend the TTL of the contract's Wasm code.

This guide will show you how to extend the TTL of a deployed contract's Wasm code using JavaScript.

## Prerequisites

- Stellar SDK: `npm install @stellar/stellar-sdk`
- A Soroban RPC endpoint (e.g., `https://soroban-testnet.stellar.org`)
- Basic knowledge of Stellar SDK

## Process overview

- Get the contract's footprint,
- Set a reasonable resource fee (perhaps start at 10,000 stroops as this is a costly operation),
- Set Soroban data as read-only,
- Set the desired ledger TTL to expire the contract,
- Create an operation `StellarSdk.Operation.extendFootprintTtl`,
- Note that a resource fee and base fee are both charged in this operation.

## JavaScript code

The code below uses Nodejs environment but same concept can also be applied in the browser using Freighter wallet or using any other [Stellar SDK](../../../tools/sdks/library.mdx).

```javascript
import * as StellarSdk from "@stellar/stellar-sdk";

import { Server } from "@stellar/stellar-sdk/rpc";

async function extendContractWasmTTL(contractId, sourceKeypair) {
const server = new Server("https://soroban-testnet.stellar.org");

// Create a new transaction builder
const account = await server.getAccount(sourceKeypair.publicKey());
const fee = "200100"; // Base fee plus resource fee

// Get the contract instance
const contract = new StellarSdk.Contract(contractId);
const instance = contract.getFootprint();

// Set the Soroban data and create an operation to extend the contract's TTL
const sorobanData = new StellarSdk.SorobanDataBuilder()
.setResourceFee(200_000)
.setReadOnly([instance])
.build();
const transaction = new StellarSdk.TransactionBuilder(account, {
fee,
networkPassphrase: StellarSdk.Networks.TESTNET, // Use appropriate network
})
.setSorobanData(sorobanData)
.addOperation(
StellarSdk.Operation.extendFootprintTtl({
extendTo: 500_000,
}),
)
.setTimeout(30)
.build();

// Sign and submit the transaction
transaction.sign(sourceKeypair);
const result = await server.sendTransaction(transaction);

console.log(
"Transaction submitted. Result:",
JSON.stringify(result, null, 2),
);
return result;
}

// Usage
const contractId = "CC6MWZMG2JPQEENRL7XVICAY5RNMHJ2OORMUHXKRDID6MNGXSSOJZLLF";
const sourceKeypair = StellarSdk.Keypair.fromSecret(
"SXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
);

extendContractWasmTTL(contractId, sourceKeypair)
.then(console.log)
.catch(console.error);
```

### Breaking Down the Code

Let's walk through the key parts of this function:

1. Setting up the Soroban data: The `SorobanDataBuilder()` is where we prep the Soroban-specific info for our transaction.

- We set a resource fee with `setResourceFee(200_000)`. This covers the extra costs for storage and execution.
- We use `setReadOnly([instance])` to tell the network which contract stuff we need to access. We're using `setReadOnly()` instead of `setReadWrite()` because we're just extending the TTL, not changing any data.

Why `setReadOnly()`? A few reasons:

- It's faster and uses fewer resources
- It's safer - we can't accidentally change data we're not supposed to
- The `ExtendFootprintTTLOp` operation needs it

2. Adding the operation: After setting up the Soroban data, we add the `extendFootprintTtl` operation to our transaction. We're telling it to extend the TTL to 500,000 ledgers with `extendTo: 500_000`.

3. What's the point? This whole process is about keeping our contract's data alive in the ledger. It's like renewing a lease - we're telling the network "Hey, keep this stuff around longer, we're still using it!"

This is super important for contracts that need to stick around for a while. Without extending the TTL, the contract's data could expire and disappear from the ledger.

Want to dive deeper? Check out the docs on the [Extend Footprint TTL operation](../../../learn/encyclopedia/storage/state-archival.mdx#extendfootprintttlop).

0 comments on commit 6048e91

Please sign in to comment.