#
Working with Online Transaction
The Online Transaction class extends the standard ITransaction
interface implementation by adding functionality that requires chain API access. This provides enhanced verification capabilities and enables several important online transaction features that aren't available in offline transactions (such as created from TaPoS data, or directly using Protobuf or JSON objects).
#
Overview
The Online Transaction class:
- Inherits from the base
ITransaction
class - Adds online-specific functionality for chain verification
- Enables security checks for operations to prevent accidental key leaks
- Verifies account existence and authority requirements
#
On-Chain Verification
One of the most powerful features of Online Transaction is the ability to perform on-chain verification:
import { createHiveChain } from '@hiveio/wax';
// Initialize hive chain interface
const chain = await createHiveChain();
// Initialize an online transaction object
const tx = await chain.createTransaction();
// Declare example operation
const operation = {
vote_operation: {
voter: "gtg",
author: "gtg",
permlink: "hello-world",
weight: 2200
}
};
// Push operation into the transction
tx.pushOperation(operation);
// Perform on-chain verification before broadcasting
try {
await tx.performOnChainVerification();
console.log('Transaction passed on-chain verification!');
// Now safe to broadcast
// await chain.broadcast(tx);
} catch (error) {
console.error('Verification failed:', error.message);
}
TBA
This verification process includes:
- Scanning for potential private key leaks in memos and comments
- Ensuring referenced accounts exist on the blockchain
- Validating authority changes in account operations
This verification process is automatically performed only on online transactions before broadcasting them. This way, you won't have to manually perform on-chain verification every time before broadcasting.
#
On-Chain Operation Validation
The Online Transaction uses an internal on-chain operation validator class that performs various security checks:
- Private Key Leak Prevention: Scans operation content (like memos and comments) for accidental inclusion of private keys
- Account Existence Verification: Ensures referenced accounts exist on the blockchain
- Authority Modification Safety: Checks for potentially dangerous authority changes
Example of what this prevents:
import { createHiveChain } from '@hiveio/wax';
// Initialize hive chain interface
const chain = await createHiveChain();
// Initialize an online transaction object
const tx = await chain.createTransaction();
// Declare example operation
const operation = {
transfer_operation: {
from: "gtg",
to: "friend",
amount: chain.hiveCoins(5),
// Would be caught:
memo: 'Here is my private key: '
+ '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
}
};
// Push operation into the transction
tx.pushOperation(operation);
// Perform on-chain verification before broadcasting
try {
// The verification would fail before broadcasting
// Throws error: "Potential private key leak detected!":
await tx.performOnChainVerification();
console.log('Verification successful!');
} catch (error) {
console.error('Verification failed:', error.message);
}
TBA
#
Authority Verification Trace
For debugging or advanced use cases, you can generate a detailed trace of authority verification:
import { createHiveChain } from '@hiveio/wax';
// Initialize hive chain interface
const chain = await createHiveChain();
// Initialize a transaction object with already existing data
// (txid: 88e992c6094a6c6813f970b77abc4a6fee4a8a27)
const parsedTransaction = chain.createTransactionFromJson({
"expiration": "2025-09-03T15:43:06",
"extensions": [],
"operations": [
{
"type": "custom_json_operation",
"value": {
"id": "notify",
"json": "[\"setLastRead\",{\"date\":\"2025-09-03T15:31:07\"}]",
"required_auths": [],
"required_posting_auths": [
"sandormb"
]
}
}
],
"signatures": [
"202cf9ea0754d1927a7875fdaf3aa6d743d7ffe4ccdc64059b9d6cb8e7"
+ "5ea1e5421e5d28d7205e6c820f8307c36e97b45da2bed6fa5795b3cf675020b77facdaee"
],
"ref_block_num": 17420,
"ref_block_prefix": 1854844897
});
const useLegacySerialization = false;
// Create an online transaction to perform online authority verification
const tx = await chain.createTransaction();
// Provide an external transaction for analysis
const trace = await tx.generateAuthorityVerificationTrace(
useLegacySerialization,
parsedTransaction
);
// Display the final trace
console.log(trace);
{
"collectedData": [
{
"finalAuthorityPath": {
"processedEntry": "sandormb",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": [
{
"processedEntry": "STM5M43EiFVh7eobDsPWeGGDQqUZohxgoBmR25hoz5GHMhNhKDknm",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": []
}
]
},
"matchingSignatures": [
{
"signature": "202cf9ea0754d1927a7875fdaf3aa6d743d7ffe4ccdc64059b9d6cb8e75ea1e5421e5d28d7205e6c820f8307c36e97b45da2bed6fa5795b3cf675020b77facdaee",
"signatureKey": "STM5M43EiFVh7eobDsPWeGGDQqUZohxgoBmR25hoz5GHMhNhKDknm"
}
]
}
],
"rootEntries": [
{
"processedEntry": "sandormb",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": [
{
"processedEntry": "STM5M43EiFVh7eobDsPWeGGDQqUZohxgoBmR25hoz5GHMhNhKDknm",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": []
}
]
}
],
"rootEntry": {
"processedEntry": "sandormb",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": [
{
"processedEntry": "STM5M43EiFVh7eobDsPWeGGDQqUZohxgoBmR25hoz5GHMhNhKDknm",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": []
}
]
},
"finalAuthorityPath": [
{
"processedEntry": "sandormb",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": [
{
"processedEntry": "STM5M43EiFVh7eobDsPWeGGDQqUZohxgoBmR25hoz5GHMhNhKDknm",
"processedRole": "posting",
"threshold": 1,
"weight": 1,
"recursionDepth": 0,
"processingStatus": {
"entryAccepted": true,
"isOpenAuthority": false
},
"visitedEntries": []
}
]
}
],
"verificationStatus": {
"entryAccepted": true,
"isOpenAuthority": false
}
}
TBA
The trace can help understand:
- Which signatures were used
- Which authorities were satisfied
- What authorities are still missing
- The full verification path through nested authorities
By utilizing these features, we were able to create the Transaction Inspector app: