Stellar Cheatsheet
For more info check : https://developers.stellar.org/docs/build/guides/cli/contract-lifecycle
Calling (invoking) a contract :
❯ stellar contract invoke --id CBTS6YRSMV565V57LT4GEX6I4CYRENZS2T3UHSKFRUADEMIXSJ3M6BTQ \
--source alice \
--network testnet \
-- hello --to '"Hi Mr Moo"'
ℹ️ Send skipped because simulation identified as read-only. Send by rerunning with --send=yes
.
["MoFo","Hi Mr Moo"]
Stellar & Smart Contracts
py-stellar-base is a Python library for communicating with a Stellar Horizon server and Soroban-RPC server. It is used for building Stellar apps on Python. It supports Python 3.8+ as well as PyPy 3.8+.
It provides:
a networking layer API for Horizon endpoints.
a networking layer API for Soroban-RPC server methods.
facilities for building and signing transactions, for communicating with a Stellar Horizon and Soroban-RPC instance, and for submitting transactions or querying network history
Genarate Keypairs
stellar keys generate --rpc-url https://horizon-testnet.stellar.org --network-passphrase "Test SDF Network ; September 2015" --network testnet alice
stellar keys show alice
SDFWXEGR3ANXTTGHUYC6YXWQISH5BA5KYSF2FPI7KLVVKA6J6G3WUENT
stellar keys generate --rpc-url https://horizon-testnet.stellar.org --network-passphrase "Test SDF Network ; September 2015" --network testnet bob
stellar keys show bob
SCMTED3TOHSL4LXDMZXDYS6D63GHVFLW2ILNIMSNUOQBE7KEMOXBGTTD
stellar keys address bob
GCJIE7EIKWRMPZOW3OPGYJHQO6E6F5OZVQQNLFJGB7PAHVBS5KBQEUFM
Alice pay 10.25 XLM to Bob
# Alice pay 10.25 XLM to Bob
from stellar_sdk import Asset, Server, Keypair, TransactionBuilder, Network
alice_keypair = Keypair.from_secret("SDFWXEGR3ANXTTGHUYC6YXWQISH5BA5KYSF2FPI7KLVVKA6J6G3WUENT")
bob_address = "GCJIE7EIKWRMPZOW3OPGYJHQO6E6F5OZVQQNLFJGB7PAHVBS5KBQEUFM"
server = Server("https://horizon-testnet.stellar.org")
alice_account = server.load_account(alice_keypair.public_key)
base_fee = 100
transaction = (
TransactionBuilder(
source_account=alice_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=base_fee,
)
.add_text_memo("Hello, Stellar!")
.append_payment_op(bob_address, Asset.native(), "10.25")
.set_timeout(30)
.build()
)
transaction.sign(alice_keypair)
response = server.submit_transaction(transaction)
print(response)
❯ python demo1.py
{'_links': {'account': {'href': 'https://horizon-testnet.stellar.org/accounts/GAWZAXIY3KVZEPY3OB3NKAC3K4U5WPLJWL65ZP5BERXQKH4W3VDZU2TA'},
'effects': {'href': 'https://horizon-testnet.stellar.org/transactions/ab9ac227560914cdcb942209d82508b12a796da43cbfcb821997f2b538240fe0/effects{?cursor,limit,order}',
'templated': True},
'ledger': {'href': 'https://horizon-testnet.stellar.org/ledgers/45916'},
'operations': {'href': 'https://horizon-testnet.stellar.org/transactions/ab9ac227560914cdcb942209d82508b12a796da43cbfcb821997f2b538240fe0/operations{?cursor,limit,order}',
'templated': True},
'precedes': {'href': 'https://horizon-testnet.stellar.org/transactions?order=asc&cursor=197207718383616'},
'self': {'href': 'https://horizon-testnet.stellar.org/transactions/ab9ac227560914cdcb942209d82508b12a796da43cbfcb821997f2b538240fe0'},
'succeeds': {'href': 'https://horizon-testnet.stellar.org/transactions?order=desc&cursor=197207718383616'},
'transaction': {'href': 'https://horizon-testnet.stellar.org/transactions/ab9ac227560914cdcb942209d82508b12a796da43cbfcb821997f2b538240fe0'}},
'created_at': '2024-09-20T12:23:53Z',
'envelope_xdr': 'AAAAAgAAAAAtkF0Y2quSPxtwdtUAW1cp2z1psv3cv6EkbwUflt1HmgAAAGQAALLuAAAAAgAAAAEAAAAAAAAAAAAAAABm7WlyAAAAAQAAAA9IZWxsbywgU3RlbGxhciEAAAAAAQAAAAAAAAABAAAAAJKCfIhVosfl1tuebCTwd4ni9dmsINWVJg/eA9Qy6oMCAAAAAAAAAAAGHAagAAAAAAAAAAGW3UeaAAAAQA93/QaNIyYWVt0035DSbQgdhcrAqefu98EvnzB/fkILpbFhPgCbvpKgi0De4Yz/u6D2a/3LtYdkYjieI8Z84Q4=',
'fee_account': 'GAWZAXIY3KVZEPY3OB3NKAC3K4U5WPLJWL65ZP5BERXQKH4W3VDZU2TA',
'fee_charged': '100',
'fee_meta_xdr': 'AAAAAgAAAAMAALNKAAAAAAAAAAAtkF0Y2quSPxtwdtUAW1cp2z1psv3cv6EkbwUflt1HmgAAABdCWuD8AACy7gAAAAEAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAs0oAAAAAZu1o9wAAAAAAAAABAACzXAAAAAAAAAAALZBdGNqrkj8bcHbVAFtXKds9abL93L+hJG8FH5bdR5oAAAAXQlrgmAAAsu4AAAABAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAALNKAAAAAGbtaPcAAAAA',
'hash': 'ab9ac227560914cdcb942209d82508b12a796da43cbfcb821997f2b538240fe0',
'id': 'ab9ac227560914cdcb942209d82508b12a796da43cbfcb821997f2b538240fe0',
'ledger': 45916,
'max_fee': '100',
'memo': 'Hello, Stellar!',
'memo_bytes': 'SGVsbG8sIFN0ZWxsYXIh',
'memo_type': 'text',
'operation_count': 1,
'paging_token': '197207718383616',
'preconditions': {'timebounds': {'max_time': '1726835058', 'min_time': '0'}},
'result_meta_xdr': 'AAAAAwAAAAAAAAACAAAAAwAAs1wAAAAAAAAAAC2QXRjaq5I/G3B21QBbVynbPWmy/dy/oSRvBR+W3UeaAAAAF0Ja4JgAALLuAAAAAQAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAACzSgAAAABm7Wj3AAAAAAAAAAEAALNcAAAAAAAAAAAtkF0Y2quSPxtwdtUAW1cp2z1psv3cv6EkbwUflt1HmgAAABdCWuCYAACy7gAAAAIAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAs1wAAAAAZu1pWQAAAAAAAAABAAAABAAAAAMAALNcAAAAAAAAAAAtkF0Y2quSPxtwdtUAW1cp2z1psv3cv6EkbwUflt1HmgAAABdCWuCYAACy7gAAAAIAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAs1wAAAAAZu1pWQAAAAAAAAABAACzXAAAAAAAAAAALZBdGNqrkj8bcHbVAFtXKds9abL93L+hJG8FH5bdR5oAAAAXPD7Z+AAAsu4AAAACAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAALNcAAAAAGbtaVkAAAAAAAAAAwAAs0oAAAAAAAAAAJKCfIhVosfl1tuebCTwd4ni9dmsINWVJg/eA9Qy6oMCAAAAF06S7qAAALMfAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAs1wAAAAAAAAAAJKCfIhVosfl1tuebCTwd4ni9dmsINWVJg/eA9Qy6oMCAAAAF1Su9UAAALMfAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
'result_xdr': 'AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=',
'signatures': ['D3f9Bo0jJhZW3TTfkNJtCB2FysCp5+73wS+fMH9+QgulsWE+AJu+kqCLQN7hjP+7oPZr/cu1h2RiOJ4jxnzhDg=='],
'source_account': 'GAWZAXIY3KVZEPY3OB3NKAC3K4U5WPLJWL65ZP5BERXQKH4W3VDZU2TA',
'source_account_sequence': '196735271960578',
'successful': True,
'valid_after': '1970-01-01T00:00:00Z',
'valid_before': '2024-09-20T12:24:18Z'}
Merge Alice account into Bob’s account
"""
This example shows how to transfer the native balance (the amount of XLM an account holds) to
another account and removes the source account from the ledger.
See: https://developers.stellar.org/docs/start/list-of-operations/#account-merge
"""
from stellar_sdk import Keypair, Network, Server, TransactionBuilder
# Configure StellarSdk to talk to the horizon instance hosted by Stellar.org
# To use the live network, set the hostname to 'horizon.stellar.org'
server = Server(horizon_url="https://horizon-testnet.stellar.org")
# The following source key was created by the friendbot at https://laboratory.stellar.org/#account-creator?network=test
# before running this example create a new account, fund it and then copy and paste the
# secret key where the current key is.
source_secret_key = "SDFWXEGR3ANXTTGHUYC6YXWQISH5BA5KYSF2FPI7KLVVKA6J6G3WUENT"
# The following obtains the keypair of the source account we will be dealing with.
source_keypair = Keypair.from_secret(source_secret_key)
source_public_key = source_keypair.public_key
# This is the public key of another account created by the friendbot. When I wrote this
# code it was active on the test network, but I would recommened creating a new account
# the same way the source account was created.
destination_public_key = "GCJIE7EIKWRMPZOW3OPGYJHQO6E6F5OZVQQNLFJGB7PAHVBS5KBQEUFM"
# loads the source account from the testnet
source_account = server.load_account(source_public_key)
# builds the transaction that merges the two accounts.
# The current code uses the testnetwork and if you wanted to use
# the public network 'Network.TESTNET_NETWORK_PASSPHRASE' would
# have to be replaced with 'Network.PUBLIC_NETWORK_PASSPHRASE'.
transaction = (
TransactionBuilder(
source_account=source_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=100,
)
.append_account_merge_op(destination=destination_public_key)
.set_timeout(30)
.build()
)
# source account signs the transaction
transaction.sign(source_keypair)
# submit the transaction to the server
response = server.submit_transaction(transaction)
How to issue assets on the Stellar network
Note there is a “change trust” AND a “payment” op?
"""
This example shows how to issue assets on the Stellar network.
# See: https://developers.stellar.org/docs/issuing-assets/
"""
from stellar_sdk.asset import Asset
from stellar_sdk.keypair import Keypair
from stellar_sdk.network import Network
from stellar_sdk.server import Server
from stellar_sdk.transaction_builder import TransactionBuilder
# Configure StellarSdk to talk to the horizon instance hosted by Stellar.org
# To use the live network, set the hostname to 'horizon.stellar.org'
server = Server(horizon_url="https://horizon-testnet.stellar.org")
# Keys for accounts to issue and receive the new asset
issuing_keypair = Keypair.from_secret(
"SD6ZEL7NZD2DOEJIT2Q5SP6WATJOUEL4REX6LQR3U7S6NRS7KBTLR3ZQ"
)
issuing_public = issuing_keypair.public_key
distributor_keypair = Keypair.from_secret(
"SB3HDYRLXR6O6DUBWN2FAMQGVAOP3OH6ROKKWDYXXTGPTAFIYIOMGED4"
)
distributor_public = distributor_keypair.public_key
# Transactions require a valid sequence number that is specific to this account.
# We can fetch the current sequence number for the source account from Horizon.
distributor_account = server.load_account(distributor_public)
# Create an object to represent the new asset
hello_asset = Asset("Hello", issuing_public)
# First, the receiving account must trust the asset
trust_transaction = (
TransactionBuilder(
source_account=distributor_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=100,
)
.append_change_trust_op(asset=hello_asset)
.set_timeout(30)
.build()
)
trust_transaction.sign(distributor_keypair)
resp = server.submit_transaction(trust_transaction)
print(f"Change Trust Op Resp:\n{resp}")
print("-" * 32)
issuing_account = server.load_account(issuing_public)
# Second, the issuing account actually sends a payment using the asset.
# We recommend that you use the distribution account to distribute assets and
# add more security measures to the issue account. Other acceptances should also
# add a trust line to accept assets like the distribution account.
payment_transaction = (
TransactionBuilder(
source_account=issuing_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=100,
)
.append_payment_op(destination=distributor_public, amount="1000", asset=hello_asset)
.set_timeout(30)
.build()
)
payment_transaction.sign(issuing_keypair)
resp = server.submit_transaction(payment_transaction)
print(f"Payment Op Resp:\n{resp}")
Query Horizon
- Deploy the Soroban hello word example built with Rust/wasm
- Invoke the contract
- Check with this Python code:
❯ stellar contract build
❯ stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/hello_world.wasm \
--source alice \
--network testnet
❯ stellar contract invoke \
--id CDDV2X2DJJOKPL75UCAIPF24L6QRWPLWPDTUJ5CS2SCPRBZCREVD4QL5 \
--source alice \
--network testnet \
-- \
hello \
--to RPC
"""
See: https://stellar-sdk.readthedocs.io/en/latest/querying_horizon.html#building-requests
"""
from stellar_sdk import Server
server = Server(horizon_url="https://horizon-testnet.stellar.org")
account = "GAUSBA6IHKK63ZPCLNQJQ332OFIETXOFSTK7AI7YTKR3M7EPTW7CLR5H"
# get a list of transactions that occurred in ledger 1400
transactions = server.transactions().for_ledger(1400).call()
print(transactions)
# get a list of transactions submitted by a particular account
transactions = server.transactions().for_account(account_id=account).call()
print(transactions)
# The following example will show you how to handle paging
print(f"Gets all payment operations associated with {account}.")
payments_records = []
payments_call_builder = (
server.payments().for_account(account).order(desc=False).limit(10)
) # limit can be set to a maximum of 200
payments_records += payments_call_builder.call()["_embedded"]["records"]
page_count = 0
while page_records := payments_call_builder.next()["_embedded"]["records"]:
payments_records += page_records
print(f"Page {page_count} fetched")
print(f"data: {page_records}")
page_count += 1
print(f"Payments count: {len(payments_records)}")