Skip to main content

Extending a deployed contract's TTL using code

When a smart contract is deployed on the Stellar network, two ledger entries are created. A contract instance ledger entry is created that defines the contract address, which WebAssembly (WASM) code it uses, and any additional storage the contract utilizes. The WebAssembly (WASM) code also has its own ledger entry that can be shared by multiple contract instances. Each ledger entry has a Time To Live (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 data can still be accessed. If the TTL expires, the data becomes archived and inaccessible. To prevent this, you need to periodically extend the TTL of the contract's Wasm code and instance entry.

This guide will show you how to extend the TTL of a deployed contract's Wasm code and instance within a contract, and by submitting a TTL extension transaction using the Stellar JS SDK or CLI.

Understanding TTL in Soroban

Before we demonstrate the TTL extension methods, you should note that in Soroban:

  • The contract instance and code are two separate, persistent storage entries
  • TTL exists to prevent the blockchain from being cluttered with unused storage entries
  • TTL extension can be done for both the contract instance and the contract code

Prerequisites

  • Stellar SDK: npm install @stellar/stellar-sdk for Javascript
  • Install the Stellar CLI
  • A Stellar RPC endpoint (e.g., https://soroban-testnet.stellar.org)
  • Basic knowledge of the SDK in use

Extending Contract Code and Instance TTL with a Contract

  1. Self-Extension: Extending the TTL from within the contract itself, in Rust.

    • Use case: When a contract needs to manage its own lifetime
    • Process: Directly accessing the contract's instance storage to extend its TTL
  2. External Extension: Extending the TTL from another contract (the deployer), in Rust.

    • Use case: When managing multiple contract instances or implementing administrative control
    • Process: Using the deployer's authority to extend TTL for any contract it has deployed
#![no_std]
use soroban_sdk::{contract, contractimpl, Address, Env};

#[contract]
pub struct ExtendTTLContract;

#[contractimpl]
impl ExtendTTLContract {
// Self-extension
pub fn extend_contract_ttl(env: Env, threshold: u32, extend_to: u32) {
env.storage().instance().extend_ttl(threshold, extend_to);
}

// External extension
pub fn extend_other_contract_ttl(env: Env, contract_address: Address, threshold: u32, extend_to: u32) {
let deployer = env.deployer();
deployer.extend_ttl(
contract_address,
threshold,
extend_to
);
}
}
  • env.storage().instance().extend_ttl(...) is called to extend the TTL of the current contract instance and the code entries.
  • threshold is a check that ensures that the current TTL of the contract instance is less than the set threshold value.
  • extend_to is the minimum number of ledgers from the current ledger that the TTL should be extended to (if the current TTL is already greater, this call is a no-op).
  • contract_address is the address of the contract instance whose TTL we want to extend.
  • env.deployer() accesses the deployer, which has methods for managing the contract's lifecycle.
  • deployer.extend_ttl(...) extends the TTL of the specified contract instance and code entries.

Extending Contract Code and Instance TTL with a Transaction

  • Use Case: When you need to manage contract TTLs through an external application or automated system.
  • Process:
    • Get the contract's footprint
    • Set the entries you want to extend as read-only in the Soroban Data
    • Create an operation StellarSdk.Operation.extendFootprintTtl with the new TTL value (extendTo), this will ensure the entries' TTL will be at least extendTo ledgers from now
    • Simulate to determine the resource fee needed to extend the TTL
    • Sign and submit the transaction
note

A resource fee and inclusion fee are both charged in this transaction.

The CLI has separate commands to extend contract code and contract instance ledger entries. The --ledgers-to-extend argument is the new entries TTL value.

Contract Code:

stellar contract extend \
--network testnet \
--source-account alice \
--ledgers-to-extend 500000 \
--wasm-hash a7e8e679a9692676e19926cca52aa975a2ca6c933368bc2b09739eed140f2adc

Contract Instance:

stellar contract extend \
--network testnet \
--source-account alice \
--ledgers-to-extend 500000 \
--id CC77VMQFKNXIKZQ6LMX56FTH2S2NLAF2FDZIHITSM3UKW24Z75UZ4YW2

Learn how to test the TTL extension in this guide.

Want to dive deeper? Check out the docs on the Extend Footprint TTL operation.