Skip to main content

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:

ChainTransaction ModelTypes
AlphaUTXO/RecordPrivate transfers, record creation
DeltaAccountTransfers, 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

OperationGas Cost
Base transfer21,000
Contract creation32,000 + code cost
Storage write (new)20,000
Storage write (existing)5,000
Storage read200
Call (cold)2,600
Call (warm)100
Log topic375
Log data (per byte)8

Alpha Chain Fee Schedule

OperationBase Fee
Private transfer0.001 ACDC
Per input record0.0001 ACDC
Per output record0.0001 ACDC
Proof verification0.0005 ACDC

Transaction Status

StatusDescription
pendingIn mempool, not yet included
includedIn a block, awaiting confirmations
confirmedSufficient confirmations
failedExecution reverted
droppedRemoved 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

ErrorDescription
NONCE_TOO_LOWNonce already used
NONCE_TOO_HIGHGap in nonce sequence
INSUFFICIENT_FUNDSNot enough balance
GAS_TOO_LOWGas limit too low
GAS_PRICE_TOO_LOWBelow minimum gas price
EXECUTION_REVERTEDContract execution failed
INVALID_SIGNATURESignature verification failed
INVALID_PROOFZK proof verification failed