Skip to main content

Smart Contracts

note

Learn to write a smart contract on Stellar by following this Getting Started guide.

A smart contract is a programmed set of executable code and state that can be invoked or used on the Stellar network.

WebAssembly (Wasm)

Once a smart contract has been written by a developer and compiled into a Wasm executable file, it can then be uploaded onto the Stellar network. A CONTRACT_DATA ledger entry is created to store this binary data and its unique identifier is the hash of the executable file. This binary executable is stored independently from its deployed contract(s). When a Stellar transaction attempts to invoke a contract function, the Wasm bytecode is first retrieved from the ledger and a secure, isolated runtime virtual machine ("VM") is instantiated so it can run the bytecode for the contract and then exit.

WebAssembly (Wasm) in Stellar Smart Contracts

WebAssembly (Wasm) is a lightweight, portable binary instruction format designed for high-performance execution across various environments, including blockchains, web browsers, and cloud services. In Stellar, Wasm serves as the foundation for smart contracts by enabling a secure and efficient execution environment.

Wasm Compilation and Upload

Once a developer writes a smart contract in a supported language, such as Rust, the contract is compiled into a Wasm executable file. This file contains low-level bytecode that can be efficiently executed within a sandboxed environment. After compilation, the Wasm executable is uploaded on the Stellar network, where it is stored as a CONTRACT_DATA ledger entry . The unique identifier for this entry is derived from the hash of the compiled binary and is called Wasm hash.

To retrieve Wasm executable file from the Stellar network to upload in your local network, it is possible to do so using the RPC's getLedgerEntries or use Stellar Lab's Contract Explorer.

Execution and Virtual Machine (VM) Isolation

When a Stellar transaction calls a contract function, the network retrieves the corresponding Wasm bytecode from the ledger. To ensure secure execution, Stellar instantiates an isolated runtime virtual machine (VM) specifically for that transaction. This approach offers several benefits, including security (as VM operates in a sandboxed environment) and deterministic execution.

Wasm and Host Functions

Stellar’s Wasm-based smart contracts interact with the protocol through host functions—predefined operations that allow contracts to read from and write to the ledger. These host functions abstract away low-level blockchain interactions, providing developers with a simplified yet powerful interface for building decentralized applications.

Contract instances

info

Importantly, the Wasm bytecode itself is stored separately from the deployed contract instances. This separation allows multiple contract instances to reference the same Wasm executable while maintaining their own state and configurations.

After the executable bytecode is uploaded on-chain, contract instances can be deployed that reference the aformentioned bytecode. A smart contract executable can have a one-to-many relationship with "contract instances" which function independently. This means the same executable code can be used by multiple contract instances that all behave identically (because of the shared executable code), while maintaining separate and distinct state data (because the data is tied to the contract instance). A contract instance is stored as its own ledger entry, and any of the contract's instance storage is stored in that same ledger entry alongside the contract instance.

Contract storage

In addition to the ledger entries that are created during the contract upload/deploy process, each contract can create and access its own set of ledger entries. These ledger entries (as well as the contract code and the contract instance ledger entries) are subject to state archival lifetimes (a ledger entry's "TTL ledger"). While they all function similarly, each type has its own fee and TTL behavior.

Temporary storage

  • Cheapest fees.
  • Permanently deleted when its TTL ledger is reached, cannot be restored.
  • Suitable for time-bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data.
  • Unlimited amount of storage.

Persistent storage

  • Most expensive fees (same price as Instance storage).
  • Recoverable after archival, can be restored using the RestoreFootprintOp operation.
  • Does not share the same lifetime as the contract instance. If the contract instance has not reached its TTL ledger, Persistent data may still be archived and need to be restored before invoking the contract.
  • Unlimited amount of storage.
  • Suitable for user data that cannot be Temporary (i.e. balances).

Instance storage

info

While we are making a distinction here between "persistent" and "instance" storage, instance storage is really just a convenient, abstracted type of persistent storage. Under the hood, the instance storage works the same as persistent storage, except its own TTL is tied to that of the contract instance.

  • Most expensive fees (same price as Persistent storage).
  • Recoverable after archival, can be restored using the extendFootprintTTLOp operation.
  • Shares the same lifetime as the contract instance. If the contract instance has not reached its TTL ledger, instance data is guaranteed to be accessible.
  • Limited amount of storage available.
  • Suitable for "shared" contract state that cannot be Temporary (i.e. admin accounts, contract metadata, etc.).