Transactions are the core building blocks for interacting with the Hive blockchain. This guide shows you how to create transactions with different types of operations.
Basic Transaction Flow
Import the Transaction class
import { Transaction, PrivateKey } from 'hive-tx'
Create a new transaction
const tx = new Transaction()
You can optionally set a custom expiration time (in milliseconds):const tx = new Transaction({ expiration: 120_000 }) // 2 minutes
Default expiration is 60 seconds (60,000 ms). Maximum is 24 hours (86,400,000 ms).
Add operations to the transaction
Use addOperation() to add operations. This method automatically creates the transaction structure on first call:await tx.addOperation('transfer', {
from: 'alice',
to: 'bob',
amount: '1.000 HIVE',
memo: 'Payment for services'
})
Sign and broadcast
const privateKey = PrivateKey.from('5JdeC9P7Pbd1uGdFVEsJ41EkEnADbbHGq6p1BwFxm6txNBsQnsw')
tx.sign(privateKey)
const result = await tx.broadcast()
console.log('Transaction ID:', result.tx_id)
Transfer Operation
Send HIVE or HBD tokens between accounts:
import { Transaction, PrivateKey } from 'hive-tx'
const tx = new Transaction()
await tx.addOperation('transfer', {
from: 'alice',
to: 'bob',
amount: '1.000 HIVE',
memo: 'Thanks for the help!'
})
const key = PrivateKey.fromLogin('alice', 'password', 'active')
tx.sign(key)
await tx.broadcast()
For transfers, you need the account’s active key.
Vote Operation
Upvote or downvote content:
const tx = new Transaction()
// Upvote at 100%
await tx.addOperation('vote', {
voter: 'alice',
author: 'bob',
permlink: 'my-awesome-post',
weight: 10000 // 100% = 10000, 50% = 5000
})
// Downvote at 50%
await tx.addOperation('vote', {
voter: 'alice',
author: 'spammer',
permlink: 'spam-post',
weight: -5000 // negative for downvote
})
const key = PrivateKey.fromLogin('alice', 'password', 'posting')
tx.sign(key)
await tx.broadcast()
Vote weight ranges from -10000 (100% downvote) to 10000 (100% upvote). Use posting key for voting.
Create posts and comments:
const tx = new Transaction()
// Create a new post
await tx.addOperation('comment', {
parent_author: '',
parent_permlink: 'hive', // category/tag
author: 'alice',
permlink: 'my-first-post',
title: 'My First Post',
body: 'Hello Hive! This is my first post.',
json_metadata: JSON.stringify({
tags: ['hive', 'introduction'],
app: 'my-app/1.0'
})
})
const key = PrivateKey.fromLogin('alice', 'password', 'posting')
tx.sign(key)
await tx.broadcast()
Create a comment (reply):
const tx = new Transaction()
await tx.addOperation('comment', {
parent_author: 'bob',
parent_permlink: 'bobs-post',
author: 'alice',
permlink: 're-bobs-post-20240101',
title: '',
body: 'Great post! Thanks for sharing.',
json_metadata: JSON.stringify({ app: 'my-app/1.0' })
})
const key = PrivateKey.fromLogin('alice', 'password', 'posting')
tx.sign(key)
await tx.broadcast()
Custom JSON Operation
Execute custom operations for apps and games:
const tx = new Transaction()
await tx.addOperation('custom_json', {
required_auths: [], // Use for active authority
required_posting_auths: ['alice'], // Use for posting authority
id: 'follow', // operation ID
json: JSON.stringify([
'follow',
{
follower: 'alice',
following: 'bob',
what: ['blog'] // can be ['blog'], ['ignore'], or []
}
])
})
const key = PrivateKey.fromLogin('alice', 'password', 'posting')
tx.sign(key)
await tx.broadcast()
Delegate Vesting Shares
Delegate HIVE Power to another account:
const tx = new Transaction()
await tx.addOperation('delegate_vesting_shares', {
delegator: 'alice',
delegatee: 'bob',
vesting_shares: '1000.000000 VESTS' // Use VESTS, not HP
})
const key = PrivateKey.fromLogin('alice', 'password', 'active')
tx.sign(key)
await tx.broadcast()
Delegation amounts must be in VESTS, not HIVE Power. Use conversion APIs to calculate VESTS from HP.
Multiple Operations in One Transaction
You can add multiple operations to a single transaction:
const tx = new Transaction()
// Upvote a post
await tx.addOperation('vote', {
voter: 'alice',
author: 'bob',
permlink: 'great-post',
weight: 10000
})
// Leave a comment
await tx.addOperation('comment', {
parent_author: 'bob',
parent_permlink: 'great-post',
author: 'alice',
permlink: 're-great-post',
title: '',
body: 'Excellent work!',
json_metadata: '{}'
})
const key = PrivateKey.fromLogin('alice', 'password', 'posting')
tx.sign(key)
await tx.broadcast()
Transaction Expiration
Control when your transaction expires:
// Expire in 30 seconds
const tx1 = new Transaction({ expiration: 30_000 })
// Expire in 5 minutes
const tx2 = new Transaction({ expiration: 300_000 })
// Expire in 1 hour
const tx3 = new Transaction({ expiration: 3_600_000 })
Transactions that haven’t been included in a block when they expire will be dropped from the mempool.
Error Handling
Always wrap transaction creation and broadcasting in try-catch blocks:
import { Transaction, PrivateKey, RPCError } from 'hive-tx'
try {
const tx = new Transaction()
await tx.addOperation('transfer', {
from: 'alice',
to: 'bob',
amount: '1.000 HIVE',
memo: 'Payment'
})
const key = PrivateKey.from('5J...')
tx.sign(key)
const result = await tx.broadcast()
console.log('Success! TX ID:', result.tx_id)
} catch (error) {
if (error instanceof RPCError) {
console.error('RPC Error:', error.message)
console.error('Error code:', error.code)
console.error('Error data:', error.data)
} else {
console.error('Error:', error.message)
}
}
Common Errors
Missing Required Authority: Ensure you’re using the correct key type (posting, active, or owner) for your operation.
Insufficient Funds: Check account balance before transferring or delegating.
Invalid Operation Data: Verify all required fields are present and formatted correctly.
Next Steps