# Manual TX Flow
The sequence below describes the standard transaction process from scratch, alongside accompanying code. If you are following along, be sure to use a testnet and be sure to top up with some testnet LUNA.
This serves mainly to illustrate how to work with the low-level transaction API; in practice, you can use the convenience functions offered by the
Wallet object to generate and sign transactions.
# Step 1: Define Messages
A transaction is comprised of one or more messages that get processed individually by message handlers in each module. Here, let's create a simple transaction with a
MsgSend and a
from jigu.core import Coin, Coins from jigu.core.msg import MsgSend, MsgSwap from jigu.key.mnemonic import MnemonicKey key = MnemonicKey.generate() send = MsgSend( from_address=key.acc_address, to_address="terra1aw0znxtlq0wrayyz7wppz3qnw94hfrmnnv5mzw", amount=Coins(uluna=1337) ) swap = MsgSwap( trader=key.acc_address, offer_coin=Coin("uluna", 8888), ask_denom="umnt" )
# Step 2: Create a StdSignMsg
StdSignMsg is a structure that prepares the requisite information for signing a transaction.
from jigu.core import StdSignMsg unsigned_tx = StdSignMsg( chain_id="columbus-3", account_number=123456, sequence=0, msgs=[send, swap], # NOTE: msgs, plural fee=None, # change this later memo="Deuteronomy 31:6" )
There are several pieces of info intended for verification that are necessary:
# Chain ID
Defines the name of the chain we are working with. A transaction prepared for the
soju-0013 testnet will be rejected if it is broadcasted on a node connected to
# Account Number
This is literally the number of the account on the chain specified. Any time funds are sent to an account address that has never received funds, the blockchain increments the number of total accounts and assigns that account this number.
# Sequence Number
A nonce, or value that gets incremented everytime a successful transaction signed by this account was included in a block. This prevents transactions that have already been accepted from being replayed.
It is sometimes difficult to know the
account number and
sequence fields. The
Wallet object dynamically will fetch the correct values to use and generate a transaction.
The memo field provides a place where you can put a short note. It is worth noting that the memo will be saved on the blockchain data and visible forever by the public, and that a larger memo will result in a higher fee.
# Step 3: Set the Fee
A fee must be added for your transaction to be accepted into the blockchain, otherwise it will likely get ignored by validators. The fee structure is defined by
StdFee, and specifies 2 components, the gas limit and fee amount.
The gas limit defines how much gas is allowed to be consumed by the node that processes it, and puts an upper bound on the limit of computation. The fee amount is the actual fee that gets paid. These two components provide the necessary information for validators to decide on whether to accept your transaction before processing it, as they determine the minimum gas price.
MsgMultiSend also incur a stability fee, which is a tax on the amount of the transaction. This must be factored in when you set the fee amount.
from jigu.core import StdFee # Option 1 fee = StdFee(gas=150000, amount=Coins(uluna=1000000)) # Option 2 fee = StdFee.make(150000, uluna=1000000)
# Automatic fee estimation
If you are unsure of which gas values and fee amount to use, you can optionally use your node to estimate the fees that your transaction may require.
from jigu import Terra terra = Terra("https://lcd.terra.dev/", "columbus-3") fee = terra.estimate_fee(unsigned_tx) fee._pp
See more on automatic fee estimation.
# Step 4: Sign and Create a StdTx
You can now sign your
StdSignMsg, resulting in a signature. Then, build the
StdTx (the actual transaction) and set the
signatures attribute to the result of signing.
from jigu.core import StdTx signature = key.create_signature(unsigned_tx) tx = StdTx( msg=unsigned_tx.msgs, # NOTE: msg, singular fee=fee, signatures=[signature], memo=unsigned_tx.memo )
Key also provides a more convenient option:
tx = key.sign_tx(unsigned_tx) # result: StdTx
# Applying more than one signature
Some transactions may require multiple signatures (such as those including
MsgMultiSend). If that is the case, each of the signing agents should sign the original
StdSignMsg individually, and you should create one
StdTx with both signatures. Make note that the order of signatures matters: the account corresponding to the first signature pays for the transacton fee.
# ... signature = key.create_signature(unsigned_tx) signature2 = key2.create_signature(unsigned_tx) tx = StdTx( msg=unsigned_tx.msgs, # NOTE: singular fee=fee, signatures=[signature, signature2], memo=unsigned_tx.memo )
# Step 5: Broadcast Transaction
Now we're ready to broadcast our transaction live to the blockchain.
from jigu import Terra terra = Terra("https://lcd.terra.dev", "columbus-3") res = terra.broadcast(tx, mode="block")
# Transaction Modes
You can broadcast the transaction in three modes:
# After Block Inclusion (default)
Wait until the transaction has been included into a block. This is lengthy and usually takes around 6-10 seconds.
Returns after the transaction has been locally checked for any errors that can be detected without consulting the blockchain state
Returns immediately without checking.