Skip to main content
GraphQL mutations enable write operations on the IOTA blockchain. The Mutation type provides methods for executing transactions and dry-running them.

executeTransactionBlock

Execute a transaction block and return the results.
txBytes
String
required
BCS-encoded transaction data as a Base64 string
signatures
[String!]
required
List of signatures as Base64 strings. Each signature includes the flag, signature bytes, and public key.

Request Format

mutation {
  executeTransactionBlock(
    txBytes: "AAACACCNu5i3R...truncated..."
    signatures: ["ANjGTW36LqS...truncated..."]
  ) {
    effects {
      status
      errors
      timestamp
      gasEffects {
        gasSummary {
          computationCost
          storageCost
          storageRebate
          nonRefundableStorageFee
        }
      }
    }
    digest
    bcs
  }
}

Response Fields

digest
String
The transaction digest (Base58-encoded)
effects
TransactionBlockEffects
The effects of executing the transaction
bcs
Base64
BCS-encoded transaction block data

Example with Full Details

mutation ExecuteTransaction($txBytes: String!, $signatures: [String!]!) {
  executeTransactionBlock(txBytes: $txBytes, signatures: $signatures) {
    digest
    effects {
      status
      errors
      timestamp
      epoch {
        epochId
      }
      checkpoint {
        sequenceNumber
      }
      balanceChanges {
        owner {
          ... on AddressOwner {
            owner { address }
          }
        }
        amount
        coinType { repr }
      }
      objectChanges {
        idCreated
        idDeleted
      }
      gasEffects {
        gasSummary {
          computationCost
          storageCost
          storageRebate
          nonRefundableStorageFee
        }
      }
    }
  }
}
Variables:
{
  "txBytes": "AAACACCNu5i3R...",
  "signatures": ["ANjGTW36LqS..."]
}

Error Handling

If the transaction fails, the response includes error information:
{
  "data": {
    "executeTransactionBlock": {
      "digest": "...",
      "effects": {
        "status": "FAILURE",
        "errors": "InsufficientGas"
      }
    }
  }
}
Common execution errors:
  • InsufficientGas - Not enough gas to execute the transaction
  • InsufficientCoinBalance - Insufficient coin balance
  • ObjectNotFound - Referenced object doesn’t exist
  • InvalidObjectOwnership - Object ownership violation
  • MoveAbort - Move execution aborted

Transaction Building Workflow

To execute a transaction using GraphQL:

1. Build Transaction

Use the IOTA SDK to construct the transaction:
import { Transaction } from '@iota/iota-sdk/transactions';

const tx = new Transaction();
// Add transaction commands
tx.moveCall({
  target: '0x2::coin::transfer',
  arguments: [/* ... */]
});

2. Serialize Transaction

Serialize the transaction to bytes:
const txBytes = await tx.build({ client });
const txBytesBase64 = Buffer.from(txBytes).toString('base64');

3. Sign Transaction

Sign with your keypair:
const signature = await keypair.signTransaction(txBytes);
const signatureBase64 = signature.signature;

4. Execute via GraphQL

mutation {
  executeTransactionBlock(
    txBytes: $txBytesBase64
    signatures: [$signatureBase64]
  ) {
    digest
    effects {
      status
    }
  }
}

Dry Run Queries

Before executing, you can dry-run a transaction using queries:

dryRunTransactionBlock

Simulate transaction execution without committing:
query {
  dryRunTransactionBlock(
    txBytes: "AAACACCNu5i3R..."
  ) {
    transaction {
      digest
      sender { address }
    }
    effects {
      status
      errors
      gasEffects {
        gasSummary {
          computationCost
          storageCost
        }
      }
      balanceChanges {
        owner {
          ... on AddressOwner {
            owner { address }
          }
        }
        amount
      }
    }
    error
  }
}

Response Fields

transaction
TransactionBlock
The transaction block details
effects
TransactionBlockEffects
The simulated effects
error
String
Error message if simulation failed

Best Practices

1. Always Dry Run First

Dry-run transactions before executing to:
  • Verify the transaction will succeed
  • Check gas costs
  • Preview balance and object changes
  • Catch errors early

2. Handle Errors Gracefully

Check the status field in effects:
mutation {
  executeTransactionBlock(...) {
    effects {
      status
      errors
    }
  }
}
If status is FAILURE, read the errors field for details.

3. Request Only Needed Fields

GraphQL allows precise field selection. Only request fields you need:
mutation {
  executeTransactionBlock(...) {
    digest
    effects {
      status
    }
  }
}

4. Monitor Gas Costs

Always include gas cost information:
mutation {
  executeTransactionBlock(...) {
    effects {
      gasEffects {
        gasSummary {
          computationCost
          storageCost
          storageRebate
        }
      }
    }
  }
}

5. Track Balance Changes

Monitor balance changes to verify expected outcomes:
mutation {
  executeTransactionBlock(...) {
    effects {
      balanceChanges {
        owner {
          ... on AddressOwner {
            owner { address }
          }
        }
        amount
        coinType { repr }
      }
    }
  }
}

Transaction Types

The GraphQL API supports all transaction types:
  • Transfer - Transfer coins or objects
  • MoveCall - Call Move functions
  • Publish - Publish Move packages
  • SplitCoin - Split coin objects
  • MergeCoin - Merge coin objects
  • MakeMoveVec - Create Move vectors
  • Upgrade - Upgrade Move packages

Gas Configuration

Set gas parameters when building transactions:
const tx = new Transaction();
tx.setGasBudget(10000000); // 0.01 IOTA
tx.setGasPrice(await client.getReferenceGasPrice());
Query reference gas price:
{
  epoch {
    referenceGasPrice
  }
}

Transaction Finality

Transactions go through these stages:
  1. Submitted - Transaction sent to validators
  2. Certified - Quorum of validators signed the transaction
  3. Executed - Transaction executed and effects generated
  4. Finalized - Included in a checkpoint
The mutation returns after the transaction is executed. Query the transaction later to confirm checkpoint inclusion:
{
  transactionBlock(digest: "...") {
    effects {
      checkpoint {
        sequenceNumber
      }
    }
  }
}

Build docs developers (and LLMs) love