Skip to content

Python Substrate Interface

Introduction

The Python Substrate Interface is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for:

  • Querying on-chain storage
  • Composing and submitting extrinsics
  • SCALE encoding/decoding
  • Interacting with Substrate runtime metadata
  • Managing blockchain interactions through convenient utility methods

Installation

Install the library using pip:

pip install substrate-interface

Note

For more installation details, refer to the Installation section in the official Python Substrate Interface documentation.

Get Started

This guide will walk you through the basic operations with the Python Substrate Interface: connecting to a node, reading chain state, and submitting transactions.

Establishing Connection

The first step is to establish a connection to a Polkadot SDK-based node. You can connect to either a local or remote node:

from substrateinterface import SubstrateInterface

# Connect to a node using websocket
substrate = SubstrateInterface(
    # For local node: "ws://127.0.0.1:9944"
    # For Polkadot: "wss://rpc.polkadot.io"
    # For Kusama: "wss://kusama-rpc.polkadot.io"
    url="INSERT_WS_URL"
)

# Verify connection
print(f"Connected to chain: {substrate.chain}")

Reading Chain State

You can query various on-chain storage items. To retrieve data, you need to specify three key pieces of information:

  • Pallet name - module or pallet that contains the storage item you want to access
  • Storage item - specific storage entry you want to query within the pallet
  • Required parameters - any parameters needed to retrieve the desired data

Here's an example of how to check an account's balance and other details:

# ...

# Query account balance and info
account_info = substrate.query(
    module="System",  # The pallet name
    storage_function="Account",  # The storage item
    params=["INSERT_ADDRESS"],  # Account address in SS58 format
)

# Access account details from the result
free_balance = account_info.value["data"]["free"]
reserved = account_info.value["data"]["reserved"]
nonce = account_info.value["nonce"]

print(
    f"""
    Account Details:
    - Free Balance: {free_balance}
    - Reserved: {reserved} 
    - Nonce: {nonce}
    """
)

Submitting Transactions

To modify the chain state, you need to submit transactions (extrinsics). Before proceeding, ensure you have:

  • A funded account with sufficient balance to pay transaction fees
  • Access to the account's keypair

Here's how to create and submit a balance transfer:

#...

# Compose the transfer call
call = substrate.compose_call(
    call_module="Balances",  # The pallet name
    call_function="transfer_keep_alive",  # The extrinsic function
    call_params={
        'dest': 'INSERT_ADDRESS',  # Recipient's address
        'value': 'INSERT_VALUE'  # Amount in smallest unit (e.g., Planck for DOT)
    }
)

# Create a signed extrinsic
extrinsic = substrate.create_signed_extrinsic(
    call=call, keypair=keypair  # Your keypair for signing
)

# Submit and wait for inclusion
receipt = substrate.submit_extrinsic(
    extrinsic, wait_for_inclusion=True  # Wait until the transaction is in a block
)

if receipt.is_success:
    print(
        f"""
        Transaction successful:
        - Extrinsic Hash: {receipt.extrinsic_hash}
        - Block Hash: {receipt.block_hash}
        """
    )
else:
    print(f"Transaction failed: {receipt.error_message}")

Note

The keypair object is essential for signing transactions. See the Keypair documentation for more details.

Where to Go Next

Now that you understand the basics, you can:

  • Explore more complex queries and transactions
  • Learn about batch transactions and utility functions
  • Discover how to work with custom pallets and types

For comprehensive reference materials and advanced features, visit the py-substrate-interface documentation.

Last update: November 14, 2024
| Created: October 18, 2024