Post
Share your knowledge.
Guide to Sui Transactions: From Setup to Execution and Verification
Guide to Sui Transactions: From Setup to Execution and Verification
If you’re curious about the nuts and bolts of executing transactions on the Sui blockchain and want an in-depth, practical guide that walks you through every step.
In this article, we’ll explore the entire journey—from setting up your client environment, checking your wallet objects, calculating gas fees, to signing and executing a transaction, and finally verifying its details.
Let’s break it down step by step:
What Makes Sui So Special? 🔥
Sui offers a highly optimized platform for decentralized applications (dApps) and smart contracts. Its elegant design in managing gas fees and transaction logic makes it an exciting playground for developers looking to push the boundaries of Web3 technology.
2. Getting Started: Environment Setup and Wallet Configuration ⚙️
2.1. Configuring Your Sui Client Environment
Before diving into transactions, ensure your Sui client is properly set up. Sui supports multiple networks (devnet, mainnet, testnet), and you can check which one is active with the command below:
➜ sui client envs
╭─────────┬─────────────────────────────────────┬────────╮
│ alias │ url │ active │
├─────────┼─────────────────────────────────────┼────────┤
│ devnet │ https://fullnode.devnet.sui.io:443 │ │
│ mainnet │ https://fullnode.mainnet.sui.io:443 │ │
│ testnet │ https://fullnode.testnet.sui.io:443 │ * │
╰─────────┴─────────────────────────────────────┴────────╯
This confirms that you’re connected to the testnet. Being on the right network is the first step toward a successful transaction.
2.2. Checking Your Active Wallet
Next, verify your active wallet address. This is crucial because every transaction is tied to your wallet identity:
➜ sui client active-address
0x35370841d2e69b495b1e2f944a3087e4242f314e503691a00b054e0ee2a45a73
2.3. Querying Owned Objects
Using the suix_getOwnedObjects API, you can fetch details about the objects (like coins) you own on the blockchain. This command helps you check your account balance and the assets available for transactions:
{
"jsonrpc": "2.0",
"id": 1,
"method": "suix_getOwnedObjects",
"params": [
"0x35370841d2e69b495b1e2f944a3087e4242f314e503691a00b054e0ee2a45a73",
{
"filter": {
"MatchAll": [
{
"StructType": "0x2::coin::Coin<0x2::sui::SUI>"
}
]
},
"options": {
"showType": true,
"showOwner": true,
"showPreviousTransaction": true
}
}
]
}
This step is vital for verifying that your wallet has the necessary coins (in this case, SUI coins) before you attempt any transactions.
3. Gas Calculation: Budgeting for Transaction Costs 💸
Gas is the fuel that powers blockchain transactions. It’s essential to understand both the gas price and gas budget to avoid transaction failures.
3.1. Fetching the Gas Price
The current gas price can be retrieved using the suix_getReferenceGasPrice API call:
{
"jsonrpc": "2.0",
"id": 1,
"method": "suix_getReferenceGasPrice",
"params": []
}
If the API returns "1000", it means that each unit of gas costs 1000 MIST. Remember, 1 SUI equals 10^9 MIST, so even small numbers in MIST can add up when budgeting.
3.2. Setting the Gas Budget
Your gas budget is the maximum amount of gas (in MIST) you’re willing to spend. For our example, let’s say your gas budget is 4964000 MIST. The total cost of a transaction is typically computed as:
Total Cost = Computation Cost + Storage Cost – Storage Rebate
For instance: • Computation Cost: 1,000,000 MIST • Storage Cost: 2,964,000 MIST • Storage Rebate: 978,120 MIST
So, the net cost becomes 1,000,000 + 2,964,000 − 978,120 = 2,985,880 MIST.
Accurately setting your gas budget ensures your transaction has sufficient funds to be executed successfully.
4. Crafting the Transaction: A Dry Run for Confidence 🔧
Before sending a live transaction, it’s best to run a “dry run” to catch any potential issues. This allows you to validate the transaction logic without spending any gas.
4.1. Building a Dry-Run Transaction
Here’s a sample TypeScript function that demonstrates how to prepare and execute a dry-run transaction. This code outlines how to split coins and prepare transfer operations:
export const signSuiDryRunTransaction = async (requestParams: SignDryRequestParams): Promise<string> => {
const { gasPrice, privateKey, coinRefs, network, recipients } = requestParams;
const keypair = Ed25519Keypair.fromSecretKey(privateKey);
const tx = newTransaction();
// Configure gas payment, price, and sender
tx.setGasPayment(coinRefs);
tx.setGasPrice(gasPrice);
tx.setSender(keypair.toSuiAddress());
// Split coins based on each recipient's amount
const coins = tx.splitCoins(tx.gas, recipients.map((transfer) => transfer.amount));
recipients.forEach((transfer, index) => {
tx.transferObjects([coins[index]], transfer.to);
});
// Build and sign the transaction with the client
const client = newSuiClient({ url: getFullnodeUrl(network) });
const bytes = await tx.build({ client });
const { signature } = await keypair.signTransaction(bytes);
await verifyTransactionSignature(bytes, signature, { address: keypair.getPublicKey().toSuiAddress() });
return JSON.stringify([toBase64(bytes), signature]);
};
This dry-run step is crucial to ensure that every detail is correct before you commit real funds.
5. Signing & Executing the Transaction: Putting It All Together ✍️
After a successful dry run, the next step is to sign and send your transaction on the blockchain.
5.1. Signing the Transaction
Below is a refined example function that signs the transaction with the specified gas budget:
const signSuiTransaction = async (requestParams: SignRequestParams): Promise<string> => {
const { gasBudget, gasPrice, privateKey, coinRefs, network, recipients } = requestParams;
const keypair = Ed25519Keypair.fromSecretKey(privateKey);
const tx = newTransaction();
// Set up gas parameters, including the gas budget
tx.setGasPayment(coinRefs);
tx.setGasPrice(gasPrice);
tx.setGasBudget(gasBudget);
tx.setSender(keypair.toSuiAddress());
// Split coins for each recipient
const coins = tx.splitCoins(tx.gas, recipients.map((transfer) => transfer.amount));
recipients.forEach((transfer, index) => {
tx.transferObjects([coins[index]], transfer.to);
});
// Build the transaction and sign it
const client = newSuiClient({ url: getFullnodeUrl(network) });
const bytes = await tx.build({ client });
const { signature } = await keypair.signTransaction(bytes);
await verifyTransactionSignature(bytes, signature, { address: keypair.getPublicKey().toSuiAddress() });
return JSON.stringify([toBase64(bytes), signature]);
};
This function integrates all necessary parameters—including gas details and recipients—ensuring that your transaction is securely signed and ready for execution.
5.2. Executing the Transaction
Once signed, the transaction is sent to the blockchain using the sui_executeTransactionBlock API endpoint:
curl --location 'https://fullnode.testnet.sui.io:443' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_executeTransactionBlock",
"params": [
"<base64-encoded-transaction>",
["<signature>"],
{
"showInput": true,
"showRawInput": true,
"showEffects": true,
"showEvents": true,
"showObjectChanges": true,
"showBalanceChanges": true
},
"WaitForLocalExecution"
]
}'
This call returns a detailed JSON response with information such as the transaction digest, gas consumption, object modifications, and balance updates.
6. Verifying Your Transaction: Cross-Check Everything 🔍
After executing the transaction, it’s essential to verify that everything executed as expected.
6.1. Browser Verification
You can check your transaction on a blockchain explorer like Suivision Testnet Explorer. The explorer displays all transaction details in an intuitive visual format, making it easier to spot any issues.
6.2. Command Line Verification
For a more detailed audit, use the command line:
sui client tx-block -- 3FopuDy5qzKm1kLRFZCdi8Lynadym9j15NaVxzUH6nYD
This command provides a comprehensive breakdown of the transaction, including sender details, gas payment, object changes, and execution status.
7. Analyzing the JSON Response: Understanding the Layers of a Transaction
Let’s unpack the JSON response you receive after executing your transaction:
7.1. Transaction Overview
- jsonrpc & id: Standard fields for the JSON-RPC protocol.
- digest: The unique transaction hash (e.g., "3FopuDy5qzKm1kLRFZCdi8Lynadym9j15NaVxzUH6nYD"), which is used for tracking.
- timestampMs & checkpoint: Provide context on when the transaction was executed and the blockchain checkpoint at that moment.
7.2. Transaction Content
- Sender & Gas Data: Includes the sender’s address and all gas-related configurations (payment, price, budget).
- Operations (Transactions): The transaction logic includes operations such as:
- SplitCoins: Breaking a gas coin into smaller parts.
- TransferObjects: Moving coin segments to the specified recipient addresses.
- Signatures: Cryptographic signatures (Base64 encoded) ensure the transaction’s authenticity.
7.3. Execution Effects
- Status: A “success” status confirms that the transaction was processed without errors.
- Gas Usage: Details the computational and storage costs along with any applicable rebates.
- Object Changes: Outlines which objects were modified, created, or updated as a result of the transaction.
- Dependencies: Lists related transaction hashes that this transaction depends on.
This granular breakdown is essential for debugging and improving your dApp’s performance.
⸻
8. Practical Developer Insights: Tips and Takeaways
Understanding each step of this process equips you with the skills to build secure, efficient Web3 applications on Sui. These insights not only help you troubleshoot issues but also empower you to innovate confidently within the Sui ecosystem.
⸻
- Sui
- SDKs and Developer Tools
- Transaction Processing
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.