sui_devInspectTransactionBlock
Executes a transaction in dev-inspect mode for debugging, providing detailed execution information without state changes.
Overview​
The sui_devInspectTransactionBlock
method runs transactions in a special debugging mode that provides comprehensive execution details including return values from Move functions, detailed gas profiling, and execution traces. This is invaluable for smart contract development and debugging complex transactions.
Parameters​
Parameter | Type | Required | Description |
---|---|---|---|
sender | string | Yes | Address of the transaction sender |
transactionBlockBytes | string | Yes | BCS serialized transaction data as base64 string |
gasPrice | string | No | Gas price for simulation (defaults to reference gas price) |
epoch | string | No | Epoch to simulate in (defaults to current) |
Returns​
Returns detailed execution results and debugging information.
Field | Type | Description |
---|---|---|
effects | object | Transaction effects including status and changes |
events | array | Events emitted during execution |
results | array | Return values from Move function calls |
error | string | Error message if execution failed |
gasUsed | object | Detailed gas consumption breakdown |
Results Array​
Each element represents a Move call result:
Field | Type | Description |
---|---|---|
mutableReferenceOutputs | array | Mutable references returned |
returnValues | array | Function return values (BCS encoded) |
Code Examples​
- cURL
- JavaScript
- Python
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "sui_devInspectTransactionBlock",
"params": [
"0xsender_address",
"AAACAAgAypo7AAAAAAAg7Vgw...transaction_bytes_base64...",
null,
null
],
"id": 1
}'
import { TransactionBlock } from '@mysten/sui.js/transactions';
import { SuiClient } from '@mysten/sui.js/client';
import { bcs } from '@mysten/sui.js/bcs';
const client = new SuiClient({
url: 'https://sui-mainnet.dwellir.com/YOUR_API_KEY'
});
// Build transaction with Move call
const tx = new TransactionBlock();
const result = tx.moveCall({
target: '0xpackage::module::function',
arguments: [
tx.pure(123, 'u64'),
tx.object('0xobject_id')
]
});
// Add the result to transaction outputs for inspection
tx.setGasBudget(10000000);
// Dev inspect to see return values
const inspectResult = await client.devInspectTransactionBlock({
sender: '0xsender_address',
transactionBlock: tx
});
console.log('Execution status:', inspectResult.effects.status);
console.log('Gas used:', inspectResult.effects.gasUsed);
// Decode return values
if (inspectResult.results && inspectResult.results.length > 0) {
const returnValues = inspectResult.results[0].returnValues;
returnValues.forEach((value, idx) => {
// Decode based on expected type
const decoded = bcs.de('u64', value[0]);
console.log(`Return value ${idx}:`, decoded);
});
}
// Check events
inspectResult.events.forEach(event => {
console.log('Event:', event.type, event.parsedJson);
});
import requests
import json
import base64
url = "https://sui-mainnet.dwellir.com/YOUR_API_KEY"
# Transaction parameters
sender = "0xsender_address"
transaction_bytes = "AAACAAgAypo7AAAAAAAg7Vgw..."
payload = {
"jsonrpc": "2.0",
"method": "sui_devInspectTransactionBlock",
"params": [
sender,
transaction_bytes,
None, # Use default gas price
None # Use current epoch
],
"id": 1
}
response = requests.post(url, json=payload)
result = response.json()['result']
# Analyze execution
print(f"Status: {result['effects']['status']['status']}")
# Check return values
if 'results' in result:
for i, res in enumerate(result['results']):
if 'returnValues' in res:
for j, val in enumerate(res['returnValues']):
# val[0] contains BCS encoded data
print(f"Call {i}, Return {j}: {val[0]}")
# Examine gas usage
gas = result['effects']['gasUsed']
print(f"Computation cost: {gas['computationCost']}")
print(f"Storage cost: {gas['storageCost']}")
Response Example​
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"effects": {
"messageVersion": "v1",
"status": {
"status": "success"
},
"executedEpoch": "251",
"gasUsed": {
"computationCost": "1500000",
"storageCost": "2588000",
"storageRebate": "978120",
"nonRefundableStorageFee": "9880"
},
"modifiedAtVersions": [],
"transactionDigest": "DevInspectTransaction",
"created": [],
"mutated": [],
"deleted": [],
"dependencies": []
},
"events": [
{
"id": {
"txDigest": "DevInspectTransaction",
"eventSeq": "0"
},
"packageId": "0xpackage",
"transactionModule": "module",
"sender": "0xsender",
"type": "0xpackage::module::EventType",
"parsedJson": {
"field1": "value1",
"field2": 123
}
}
],
"results": [
{
"mutableReferenceOutputs": [],
"returnValues": [
["gAAAAAAAAA==", "u64"],
["AQAAAAAAAADoBwAAAAAAAOgHAAAAAAAA", "vector<u64>"]
]
}
]
}
}
Debugging Use Cases​
Testing Move Functions​
async function testMoveFunction(packageId, module, func, args) {
const tx = new TransactionBlock();
const result = tx.moveCall({
target: `${packageId}::${module}::${func}`,
arguments: args
});
const inspection = await client.devInspectTransactionBlock({
sender: '0x0', // Can use any address for inspection
transactionBlock: tx
});
if (inspection.effects.status.status !== 'success') {
console.error('Function failed:', inspection.error);
return null;
}
// Extract and decode return values
const returns = inspection.results?.[0]?.returnValues || [];
return returns.map(([data, type]) => {
// Decode based on type
return bcs.de(type, data);
});
}
Gas Profiling​
async function profileGasUsage(tx, sender) {
const result = await client.devInspectTransactionBlock({
sender,
transactionBlock: tx
});
const gas = result.effects.gasUsed;
console.log('Gas Profile:');
console.log('├─ Computation:', gas.computationCost);
console.log('├─ Storage:', gas.storageCost);
console.log('├─ Rebate:', gas.storageRebate);
console.log('└─ Total:',
Number(gas.computationCost) +
Number(gas.storageCost) -
Number(gas.storageRebate)
);
return gas;
}
Event Analysis​
async function analyzeEvents(tx, sender) {
const result = await client.devInspectTransactionBlock({
sender,
transactionBlock: tx
});
const eventsByType = {};
result.events.forEach(event => {
const type = event.type.split('::').pop();
if (!eventsByType[type]) {
eventsByType[type] = [];
}
eventsByType[type].push(event.parsedJson);
});
console.log('Events emitted:', Object.keys(eventsByType));
return eventsByType;
}
Complex Transaction Debugging​
async function debugComplexTransaction() {
const tx = new TransactionBlock();
// Multiple operations
const [coin1, coin2] = tx.splitCoins(tx.gas, [
tx.pure(1000000),
tx.pure(2000000)
]);
// First Move call
const result1 = tx.moveCall({
target: '0xdefi::swap::swap',
arguments: [coin1, tx.pure('0x2::sui::SUI')]
});
// Second Move call using first result
const result2 = tx.moveCall({
target: '0xdefi::pool::add_liquidity',
arguments: [result1, coin2]
});
// Inspect execution
const inspection = await client.devInspectTransactionBlock({
sender: '0xsender',
transactionBlock: tx
});
// Analyze each call's results
inspection.results?.forEach((result, idx) => {
console.log(`Call ${idx} results:`, result.returnValues);
});
return inspection;
}
Best Practices​
- Use for development only - Not for production validation
- Test with realistic sender - Some functions check sender permissions
- Decode return values properly - Use correct BCS types
- Check gas estimates - More accurate than dry run for complex transactions
- Analyze event emissions - Verify correct events are emitted
Differences from Other Methods​
Method | Purpose | Returns | State Change |
---|---|---|---|
devInspectTransactionBlock | Debugging | Return values, detailed traces | No |
dryRunTransactionBlock | Gas estimation | Effects preview | No |
executeTransactionBlock | Execution | Transaction receipt | Yes |
Related Methods​
- sui_dryRunTransactionBlock - Simulate for gas estimation
- sui_executeTransactionBlock - Execute transaction
- sui_getTransactionBlock - Get executed transaction details
Need help? Contact our support team or check the Sui documentation.