Docs

ExecuteTransaction - Submit Signed Transactions

Execute signed transactions on Sui blockchain via gRPC. Learn how to submit transactions, handle signatures, and verify execution with Dwellir's high-performance infrastructure.

Submit Transactions to Sui Blockchain

The ExecuteTransaction method submits cryptographically signed transactions to the Sui network for execution and consensus. This is the primary method for committing state changes to the blockchain, from simple token transfers to complex smart contract interactions.

Overview

Every state modification on Sui requires a signed transaction. The ExecuteTransaction method takes your prepared and signed transaction, broadcasts it to validators, processes it through consensus, and returns the execution results. Understanding this method is essential for any application that modifies blockchain state.

Transaction Lifecycle

  1. Build: Construct transaction with desired operations
  2. Sign: Cryptographically sign with private key
  3. Submit: Send to network via ExecuteTransaction
  4. Consensus: Validators reach agreement
  5. Execute: Smart contracts run, state changes
  6. Finalize: Transaction included in checkpoint

Method Signature

Service: sui.rpc.v2.TransactionService Method: ExecuteTransaction Type: Unary RPC

Use Cases

1. Token Transfers

Execute SUI or custom token transfers:

TypeScript
async function executeTokenTransfer(
  from: string,
  to: string,
  amount: string,
  coinType: string,
  keypair: any
): Promise<string> {
  const tx = new TransactionBlock();

  if (coinType === '0x2::sui::SUI') {
    const [coin] = tx.splitCoins(tx.gas, [tx.pure(amount)]);
    tx.transferObjects([coin], tx.pure(to));
  } else {
    // Custom token transfer logic
  }

  tx.setSender(from);
  const txBytes = await tx.build({ client });
  const { signature, publicKey } = await keypair.signTransactionBlock(txBytes);

  const result = await executeTransaction(txBytes, signature, publicKey.toBytes());

  return result.transaction.digest;
}

2. Smart Contract Interaction

Call Move functions:

TypeScript
async function callSmartContract(
  packageId: string,
  module: string,
  function_name: string,
  args: any[],
  keypair: any
): Promise<any> {
  const tx = new TransactionBlock();

  tx.moveCall({
    target: `${packageId}::${module}::${function_name}`,
    arguments: args.map(arg => tx.pure(arg))
  });

  const txBytes = await tx.build({ client });
  const { signature, publicKey } = await keypair.signTransactionBlock(txBytes);

  return await executeTransaction(txBytes, signature, publicKey.toBytes());
}

3. NFT Minting

Mint and transfer NFTs:

TypeScript
async function mintNFT(
  name: string,
  description: string,
  imageUrl: string,
  recipient: string,
  keypair: any
): Promise<string> {
  const tx = new TransactionBlock();

  tx.moveCall({
    target: `${NFT_PACKAGE}::nft::mint`,
    arguments: [
      tx.pure(name),
      tx.pure(description),
      tx.pure(imageUrl),
      tx.pure(recipient)
    ]
  });

  const txBytes = await tx.build({ client });
  const { signature, publicKey } = await keypair.signTransactionBlock(txBytes);

  const result = await executeTransaction(txBytes, signature, publicKey.toBytes());

  console.log(`✓ NFT minted: ${result.transaction.digest}`);

  return result.transaction.digest;
}

Best Practices

1. Always Verify Signatures

Ensure signatures are valid before submission:

TypeScript
function validateSignature(
  txBytes: Uint8Array,
  signature: Uint8Array,
  publicKey: Uint8Array
): boolean {
  // Implement signature verification
  // Use cryptographic library to verify
  return true;  // Placeholder
}

2. Handle Gas Appropriately

Set reasonable gas budgets:

TypeScript
tx.setGasBudget(10_000_000);  // 0.01 SUI
tx.setGasPrice(495);  // Current reference gas price

3. Implement Retry Logic

Handle transient network failures:

TypeScript
async function executeWithRetry(
  txBytes: Uint8Array,
  signature: Uint8Array,
  publicKey: Uint8Array,
  maxAttempts: number = 3
): Promise<any> {
  let lastError;

  for (let i = 0; i < maxAttempts; i++) {
    try {
      return await executeTransaction(txBytes, signature, publicKey);
    } catch (error) {
      lastError = error;
      if (i < maxAttempts - 1) {
        await new Promise(resolve => setTimeout(resolve, 2000 * (i + 1)));
      }
    }
  }

  throw lastError;
}

4. Monitor Finality

Track transaction finality status:

TypeScript
async function waitForFinality(
  digest: string,
  desiredFinality: 'CERTIFIED' | 'CHECKPOINT' = 'CHECKPOINT'
): Promise<void> {
  const maxWait = 60000;  // 60 seconds
  const start = Date.now();

  while (Date.now() - start < maxWait) {
    const tx = await getTransaction(digest);

    if (desiredFinality === 'CERTIFIED' && tx.finality >= 0) {
      return;
    }

    if (desiredFinality === 'CHECKPOINT' && tx.finality >= 1) {
      return;
    }

    await new Promise(resolve => setTimeout(resolve, 1000));
  }

  throw new Error('Finality timeout');
}

Need help with transaction execution? Contact support@dwellir.com or check the gRPC overview.