Transaction Bundles

Transaction Bundles - Technical Specification

This document describes the transaction bundle format, which packages all components of a Roru transaction into a single, verifiable unit.

Bundle Structure

Bundle Format

Transaction Bundle:

pub struct TransactionBundle {
    pub header: BundleHeader,
    pub inputs: Vec<Input>,
    pub outputs: Vec<Output>,
    pub proof: Proof,
    pub nullifiers: Vec<Nullifier>,
    pub public_data: PublicData,
    pub signature: Signature,
    pub metadata: BundleMetadata,
}

Bundle Header

Header Format:

pub struct BundleHeader {
    pub version: u8,              // Bundle version
    pub network_id: u32,          // Network identifier
    pub timestamp: u64,            // Creation timestamp
    pub expiry: Option<u64>,       // Expiry timestamp (if any)
    pub bundle_hash: Hash,        // Hash of bundle
}

Input Structure

Input Format

Input Definition:

pub struct Input {
    pub note_commitment: Commitment,  // Commitment to note
    pub merkle_proof: MerkleProof,    // Proof of inclusion
    pub nullifier: Nullifier,          // Nullifier for note
    pub authorization: Authorization, // Spending authorization
}

Input Components

Note Commitment:

  • Pedersen commitment to note

  • Proves note exists

  • Hides note value

  • Binding commitment

Merkle Proof:

  • Proof note exists in tree

  • Path from leaf to root

  • Verifies inclusion

  • Logarithmic size

Nullifier:

  • Prevents double-spending

  • Unique per note

  • Unlinkable

  • Verifiable

Authorization:

  • Proves spending right

  • Signature or proof

  • Device attestation (if used)

  • Validates ownership

Output Structure

Output Format

Output Definition:

pub struct Output {
    pub commitment: Commitment,        // Commitment to new note
    pub encrypted_note: EncryptedNote,  // Encrypted note data
    pub recipient: ShieldedAddress,     // Recipient address
}

Output Components

Commitment:

  • Pedersen commitment

  • Added to state tree

  • Hides value

  • Binding

Encrypted Note:

  • Encrypted note data

  • Only recipient can decrypt

  • End-to-end encryption

  • Privacy-preserving

Recipient Address:

  • Shielded address format

  • Cannot be linked

  • Privacy-preserving

  • Verifiable

Proof Structure

Proof Format

Proof Definition:

pub struct Proof {
    pub input_proof: InputProof,      // Proof for inputs
    pub output_proof: OutputProof,    // Proof for outputs
    pub balance_proof: BalanceProof,   // Balance proof
    pub authorization_proof: AuthProof, // Authorization proof
}

Proof Components

Input Proof:

  • Proves input notes exist

  • Validates nullifiers

  • Verifies authorization

  • Ensures notes not spent

Output Proof:

  • Proves output notes valid

  • Validates commitments

  • Checks recipient format

  • Ensures value ranges

Balance Proof:

  • Proves value conservation

  • Hides individual values

  • Verifies no overflow

  • Ensures correctness

Authorization Proof:

  • Proves spending right

  • Validates signature

  • Checks device (if used)

  • Ensures ownership

Nullifier Set

Nullifier Format

Nullifier Structure:

pub struct Nullifier {
    pub hash: Hash,  // Nullifier hash
}

Nullifier Verification

Verification Process:

  1. Check nullifier not in set

  2. Verify nullifier format

  3. Validate nullifier generation

  4. Add to nullifier set

Verification Code:

fn verify_nullifiers(nullifiers: &[Nullifier], nullifier_set: &NullifierSet) -> bool {
    for nullifier in nullifiers {
        if nullifier_set.contains(nullifier) {
            return false;  // Double-spend detected
        }
    }
    true
}

Public Data

Public Data Format

Public Data Structure:

pub struct PublicData {
    pub fee: Option<u64>,           // Public fee (if any)
    pub refund: Option<u64>,        // Public refund (if any)
    pub memo: Option<Vec<u8>>,      // Public memo (if any)
    pub metadata: Option<Metadata>,  // Additional metadata
}

Public Data Usage

Use Cases:

  • Public fees

  • Compliance requirements

  • Transparent operations

  • Optional metadata

Signature

Signature Format

Signature Structure:

pub struct Signature {
    pub signature: [u8; 64],  // Signature bytes
    pub public_key: Point,    // Public key
}

Signature Verification

Verification Process:

  1. Recover public key

  2. Verify signature

  3. Check authorization

  4. Validate format

Verification Code:

fn verify_signature(bundle: &TransactionBundle, signature: &Signature) -> bool {
    let message = bundle.hash();
    verify_signature(&message, &signature.signature, &signature.public_key)
}

Bundle Metadata

Metadata Format

Metadata Structure:

pub struct BundleMetadata {
    pub version: u8,              // Metadata version
    pub chain_id: u32,           // Target chain
    pub gas_limit: Option<u64>,  // Gas limit (if applicable)
    pub priority: Option<u8>,    // Priority level
    pub tags: Vec<String>,        // Optional tags
}

Bundle Serialization

Serialization Format

Binary Format:

[Header][Inputs][Outputs][Proof][Nullifiers][PublicData][Signature][Metadata]

Serialization Code:

fn serialize_bundle(bundle: &TransactionBundle) -> Vec<u8> {
    let mut data = Vec::new();
    data.extend_from_slice(&bundle.header.serialize());
    data.extend_from_slice(&serialize_inputs(&bundle.inputs));
    data.extend_from_slice(&serialize_outputs(&bundle.outputs));
    data.extend_from_slice(&bundle.proof.serialize());
    data.extend_from_slice(&serialize_nullifiers(&bundle.nullifiers));
    data.extend_from_slice(&bundle.public_data.serialize());
    data.extend_from_slice(&bundle.signature.serialize());
    data.extend_from_slice(&bundle.metadata.serialize());
    data
}

Deserialization

Deserialization Code:

fn deserialize_bundle(data: &[u8]) -> Result<TransactionBundle> {
    let mut offset = 0;
    let header = BundleHeader::deserialize(&data[offset..])?;
    offset += header.size();
    // ... continue deserializing other components
    Ok(TransactionBundle { /* ... */ })
}

Bundle Validation

Validation Process

Validation Steps:

  1. Verify bundle format

  2. Verify signatures

  3. Verify proofs

  4. Verify nullifiers

  5. Verify balance

  6. Verify constraints

Validation Code:

fn validate_bundle(bundle: &TransactionBundle, state: &State) -> Result<()> {
    // Verify format
    verify_format(bundle)?;
    
    // Verify signatures
    verify_signature(bundle)?;
    
    // Verify proofs
    verify_proofs(bundle, state)?;
    
    // Verify nullifiers
    verify_nullifiers(&bundle.nullifiers, &state.nullifier_set)?;
    
    // Verify balance
    verify_balance(bundle)?;
    
    // Verify constraints
    verify_constraints(bundle)?;
    
    Ok(())
}

Bundle Hashing

Hash Calculation

Hash Formula:

bundle_hash = Hash(header || inputs || outputs || proof || nullifiers || public_data)

Hash Implementation:

fn hash_bundle(bundle: &TransactionBundle) -> Hash {
    let mut hasher = Hasher::new();
    hasher.update(&bundle.header.serialize());
    hasher.update(&serialize_inputs(&bundle.inputs));
    hasher.update(&serialize_outputs(&bundle.outputs));
    hasher.update(&bundle.proof.serialize());
    hasher.update(&serialize_nullifiers(&bundle.nullifiers));
    hasher.update(&bundle.public_data.serialize());
    hasher.finalize()
}

Performance

Bundle Sizes

Typical Sizes:

  • Header: ~64 bytes

  • Input (per): ~500 bytes

  • Output (per): ~300 bytes

  • Proof: ~1-2 KB

  • Nullifiers: 32 bytes each

  • Signature: ~96 bytes

  • Total: ~2-5 KB (typical)

Optimization

Optimization Techniques:

  • Compress proofs

  • Batch operations

  • Efficient serialization

  • Reduce redundancy

Security

Security Properties

Integrity:

  • Bundle hash prevents tampering

  • Signatures ensure authenticity

  • Proofs ensure correctness

  • Nullifiers prevent double-spending

Privacy:

  • Values hidden in commitments

  • Addresses encrypted

  • Proofs hide information

  • No linkability

Conclusion

Transaction bundles provide:

  • Completeness: All transaction data

  • Verifiability: Cryptographic proofs

  • Privacy: Hidden information

  • Efficiency: Compact format

  • Security: Cryptographic guarantees

Understanding bundles is essential for transaction processing.

Last updated