Transaction Types
This reference documents all transaction types supported on the ACDC network, including their structure, encoding, and use cases.
Overview
ACDC supports different transaction types for each chain:
| Chain | Transaction Model | Types |
|---|---|---|
| Alpha | UTXO/Record | Private transfers, record creation |
| Delta | Account | Transfers, contract calls, staking, governance |
Delta Chain Transactions
Type 0: Legacy Transfer
Simple value transfer between accounts.
Structure:
interface LegacyTransfer {
type: 0;
nonce: number;
gasPrice: bigint;
gasLimit: bigint;
to: string;
value: bigint;
data: string; // '0x' for simple transfer
v: number;
r: string;
s: string;
}
Example:
const tx = {
type: 0,
nonce: 42,
gasPrice: parseUnits('10', 9), // 10 gwei
gasLimit: 21000n,
to: 'dx1recipient...',
value: parseUnits('1.0', 18),
data: '0x'
};
Gas Cost: 21,000 (base transfer)
Type 1: Access List Transaction
Transfer with access list for gas optimization.
Structure:
interface AccessListTransaction {
type: 1;
chainId: number;
nonce: number;
gasPrice: bigint;
gasLimit: bigint;
to: string;
value: bigint;
data: string;
accessList: AccessListEntry[];
v: number;
r: string;
s: string;
}
interface AccessListEntry {
address: string;
storageKeys: string[];
}
Example:
const tx = {
type: 1,
chainId: 1,
nonce: 42,
gasPrice: parseUnits('10', 9),
gasLimit: 50000n,
to: 'dx1contract...',
value: 0n,
data: '0xa9059cbb...', // transfer(address,uint256)
accessList: [
{
address: 'dx1contract...',
storageKeys: [
'0x0000...0001', // balances slot
'0x0000...0002' // allowances slot
]
}
]
};
Type 2: EIP-1559 Transaction
Dynamic fee transaction with priority fee.
Structure:
interface EIP1559Transaction {
type: 2;
chainId: number;
nonce: number;
maxPriorityFeePerGas: bigint;
maxFeePerGas: bigint;
gasLimit: bigint;
to: string;
value: bigint;
data: string;
accessList: AccessListEntry[];
v: number;
r: string;
s: string;
}
Example:
const tx = {
type: 2,
chainId: 1,
nonce: 42,
maxPriorityFeePerGas: parseUnits('2', 9), // 2 gwei tip
maxFeePerGas: parseUnits('100', 9), // 100 gwei max
gasLimit: 21000n,
to: 'dx1recipient...',
value: parseUnits('1.0', 18),
data: '0x',
accessList: []
};
Fee Calculation:
actualFee = gasUsed * min(maxFeePerGas, baseFee + maxPriorityFeePerGas)
Type 100: Staking Transaction
Stake delegation and management.
Structure:
interface StakingTransaction {
type: 100;
chainId: number;
nonce: number;
maxFeePerGas: bigint;
maxPriorityFeePerGas: bigint;
gasLimit: bigint;
action: StakingAction;
v: number;
r: string;
s: string;
}
type StakingAction =
| { type: 'delegate'; validator: string; amount: bigint }
| { type: 'undelegate'; validator: string; amount: bigint }
| { type: 'redelegate'; from: string; to: string; amount: bigint }
| { type: 'claimRewards' }
| { type: 'registerValidator'; pubkey: string; commission: number };
Examples:
// Delegate stake
const delegateTx = {
type: 100,
action: {
type: 'delegate',
validator: 'dx1validator...',
amount: parseUnits('1000', 18)
},
// ... other fields
};
// Claim rewards
const claimTx = {
type: 100,
action: { type: 'claimRewards' },
// ... other fields
};
Type 101: Governance Transaction
Governance proposals and voting.
Structure:
interface GovernanceTransaction {
type: 101;
chainId: number;
nonce: number;
maxFeePerGas: bigint;
maxPriorityFeePerGas: bigint;
gasLimit: bigint;
action: GovernanceAction;
v: number;
r: string;
s: string;
}
type GovernanceAction =
| { type: 'propose'; proposal: Proposal }
| { type: 'vote'; proposalId: number; vote: 'yes' | 'no' | 'abstain' }
| { type: 'delegate'; delegatee: string }
| { type: 'execute'; proposalId: number };
Examples:
// Vote on proposal
const voteTx = {
type: 101,
action: {
type: 'vote',
proposalId: 42,
vote: 'yes'
},
// ... other fields
};
// Create proposal
const proposeTx = {
type: 101,
action: {
type: 'propose',
proposal: {
title: 'Increase gas limit',
description: '...',
actions: [
{
target: 'dx1params...',
data: '0x...'
}
]
}
},
// ... other fields
};
Type 102: Bridge Transaction
Cross-chain transfers between Alpha and Delta.
Structure:
interface BridgeTransaction {
type: 102;
chainId: number;
nonce: number;
maxFeePerGas: bigint;
maxPriorityFeePerGas: bigint;
gasLimit: bigint;
action: BridgeAction;
v: number;
r: string;
s: string;
}
type BridgeAction =
| { type: 'lockAndMint'; amount: bigint; targetAddress: string }
| { type: 'burnAndRelease'; amount: bigint; targetAddress: string }
| { type: 'claimBridged'; proof: string };
Alpha Chain Transactions
Private Transfer
Transfer records privately using zero-knowledge proofs.
Structure:
interface PrivateTransfer {
type: 'private_transfer';
inputs: RecordInput[];
outputs: RecordOutput[];
proof: string; // ZK proof
fee: bigint;
}
interface RecordInput {
commitment: string;
nullifier: string; // Prevents double-spend
}
interface RecordOutput {
commitment: string;
encryptedData: string; // Encrypted for recipient
}
Example:
const privateTx = {
type: 'private_transfer',
inputs: [
{
commitment: '0xabc123...',
nullifier: '0xdef456...'
}
],
outputs: [
{
commitment: '0xghi789...', // To recipient
encryptedData: '0x...'
},
{
commitment: '0xjkl012...', // Change back to self
encryptedData: '0x...'
}
],
proof: '0x...', // ZK proof of valid transfer
fee: parseUnits('0.001', 18)
};
Record Creation
Create new records (minting from bridge or rewards).
Structure:
interface RecordCreation {
type: 'record_creation';
outputs: RecordOutput[];
authorization: string; // Bridge or system authorization
proof: string;
}
Join Transaction
Combine multiple records into one.
Structure:
interface JoinTransaction {
type: 'join';
inputs: RecordInput[]; // Multiple inputs
output: RecordOutput; // Single output
proof: string;
}
Split Transaction
Split one record into multiple.
Structure:
interface SplitTransaction {
type: 'split';
input: RecordInput; // Single input
outputs: RecordOutput[]; // Multiple outputs
proof: string;
}
Transaction Encoding
RLP Encoding (Delta)
import { RLP } from '@acdc/sdk';
const tx = {
type: 2,
chainId: 1,
nonce: 42,
// ... other fields
};
// Encode for signing
const encoded = RLP.encode([
tx.chainId,
tx.nonce,
tx.maxPriorityFeePerGas,
tx.maxFeePerGas,
tx.gasLimit,
tx.to,
tx.value,
tx.data,
tx.accessList
]);
// Hash for signing
const hash = keccak256(concat([0x02], encoded));
Borsh Encoding (Alpha)
import { borsh } from '@acdc/sdk';
const tx = {
type: 'private_transfer',
inputs: [...],
outputs: [...],
proof: '0x...',
fee: 1000000n
};
const encoded = borsh.serialize(PrivateTransferSchema, tx);
Transaction Signing
Delta Chain
import { Wallet, signTransaction } from '@acdc/sdk';
const wallet = Wallet.fromPrivateKey('0x...');
const tx = {
type: 2,
chainId: 1,
nonce: 42,
maxFeePerGas: parseUnits('100', 9),
maxPriorityFeePerGas: parseUnits('2', 9),
gasLimit: 21000n,
to: 'dx1recipient...',
value: parseUnits('1.0', 18),
data: '0x'
};
const signedTx = await wallet.signTransaction(tx);
console.log('Signed TX:', signedTx);
Alpha Chain
import { AlphaWallet, createPrivateTransfer } from '@acdc/sdk';
const wallet = AlphaWallet.fromPrivateKey('0x...');
const privateTx = await wallet.createPrivateTransfer({
to: 'ax1recipient...',
amount: parseUnits('10', 18),
records: inputRecords // Your unspent records
});
// Proof is generated automatically
console.log('Private TX:', privateTx);
Gas Costs
Delta Chain Gas Schedule
| Operation | Gas Cost |
|---|---|
| Base transfer | 21,000 |
| Contract creation | 32,000 + code cost |
| Storage write (new) | 20,000 |
| Storage write (existing) | 5,000 |
| Storage read | 200 |
| Call (cold) | 2,600 |
| Call (warm) | 100 |
| Log topic | 375 |
| Log data (per byte) | 8 |
Alpha Chain Fee Schedule
| Operation | Base Fee |
|---|---|
| Private transfer | 0.001 ACDC |
| Per input record | 0.0001 ACDC |
| Per output record | 0.0001 ACDC |
| Proof verification | 0.0005 ACDC |
Transaction Status
| Status | Description |
|---|---|
pending | In mempool, not yet included |
included | In a block, awaiting confirmations |
confirmed | Sufficient confirmations |
failed | Execution reverted |
dropped | Removed from mempool |
Query Transaction
// Get transaction details
const tx = await client.getTransaction('0xhash...');
// Get receipt (after confirmation)
const receipt = await client.getTransactionReceipt('0xhash...');
console.log('Status:', receipt.status); // 1 = success, 0 = failed
console.log('Gas Used:', receipt.gasUsed);
console.log('Block:', receipt.blockNumber);
Error Handling
| Error | Description |
|---|---|
NONCE_TOO_LOW | Nonce already used |
NONCE_TOO_HIGH | Gap in nonce sequence |
INSUFFICIENT_FUNDS | Not enough balance |
GAS_TOO_LOW | Gas limit too low |
GAS_PRICE_TOO_LOW | Below minimum gas price |
EXECUTION_REVERTED | Contract execution failed |
INVALID_SIGNATURE | Signature verification failed |
INVALID_PROOF | ZK proof verification failed |