Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/provablehq/snarkvm/llms.txt

Use this file to discover all available pages before exploring further.

Your First SnarkVM Program

This guide walks you through creating a simple SnarkVM application that demonstrates key functionality: account generation, cryptographic operations, and working with field elements.
Before starting, ensure you have installed SnarkVM and have Rust 1.88.0 or higher.

Create a New Project

1

Initialize the Project

cargo new my-snarkvm-app
cd my-snarkvm-app
2

Add Dependencies

Update your Cargo.toml:
[package]
name = "my-snarkvm-app"
version = "0.1.0"
edition = "2024"

[dependencies]
snarkvm = "4.4.0"
anyhow = "1.0"

Example 1: Account Management

Learn how to create and manage Aleo accounts.

Generate a New Account

Replace src/main.rs with:
use snarkvm::prelude::*;
use anyhow::Result;

type CurrentNetwork = MainnetV0;

fn main() -> Result<()> {
    // Initialize a random number generator
    let rng = &mut snarkvm_utilities::TestRng::default();
    
    // Generate a new private key
    let private_key = PrivateKey::<CurrentNetwork>::new(rng)?;
    println!("Private Key: {}", private_key);
    
    // Derive the view key
    let view_key = ViewKey::try_from(&private_key)?;
    println!("View Key: {}", view_key);
    
    // Derive the address
    let address = Address::try_from(&private_key)?;
    println!("Address: {}", address);
    
    Ok(())
}
cargo build --release

Account Derivation from Existing Key

use snarkvm::prelude::*;
use anyhow::Result;

type CurrentNetwork = MainnetV0;

fn main() -> Result<()> {
    // Parse an existing private key
    let private_key = PrivateKey::<CurrentNetwork>::from_str(
        "APrivateKey1zkp8cC4jgHEBnbtu3xxs1Ndja2EMizcvTRDq5Nikdkukg1p"
    )?;
    
    // Derive the view key and address
    let view_key = ViewKey::try_from(&private_key)?;
    let address = Address::try_from(&private_key)?;
    
    // Verify the derivation
    assert_eq!(
        view_key.to_string(),
        "AViewKey1n1n3ZbnVEtXVe3La2xWkUvY3EY7XaCG6RZJJ3tbvrrrD"
    );
    assert_eq!(
        address.to_string(),
        "aleo1wvgwnqvy46qq0zemj0k6sfp3zv0mp77rw97khvwuhac05yuwscxqmfyhwf"
    );
    
    println!("✓ Account derivation verified");
    
    Ok(())
}

Example 2: Working with Field Elements

Field elements are fundamental to zero-knowledge proofs. Here’s how to use them:
use snarkvm::prelude::*;
use anyhow::Result;

type CurrentNetwork = MainnetV0;

fn main() -> Result<()> {
    // Create field elements from integers
    let field_a = Field::<CurrentNetwork>::from_u64(42);
    let field_b = Field::<CurrentNetwork>::from_u64(17);
    
    // Perform field arithmetic
    let sum = field_a + field_b;
    let product = field_a * field_b;
    let difference = field_a - field_b;
    
    println!("Field A: {}", field_a);
    println!("Field B: {}", field_b);
    println!("A + B = {}", sum);
    println!("A * B = {}", product);
    println!("A - B = {}", difference);
    
    // Field inversion (multiplicative inverse)
    let field_c = Field::<CurrentNetwork>::from_u64(5);
    let inverse = field_c.inverse().unwrap();
    println!("Inverse of 5: {}", inverse);
    println!("5 * inverse = {}", field_c * inverse); // Should be 1
    
    Ok(())
}
Field arithmetic operates modulo the field’s prime order. Division by zero will cause a panic.

Example 3: Cryptographic Hashing

SnarkVM includes several hash functions optimized for zero-knowledge proofs.
use snarkvm::prelude::*;
use anyhow::Result;

type CurrentNetwork = MainnetV0;

fn main() -> Result<()> {
    // Create some data to hash
    let data = Field::<CurrentNetwork>::from_u64(12345);
    
    // Hash using Poseidon (optimized for SNARKs)
    let hash = CurrentNetwork::hash_to_field(&[data])?;
    
    println!("Input: {}", data);
    println!("Poseidon Hash: {}", hash);
    
    // Hash multiple inputs
    let field_a = Field::<CurrentNetwork>::from_u64(100);
    let field_b = Field::<CurrentNetwork>::from_u64(200);
    let field_c = Field::<CurrentNetwork>::from_u64(300);
    
    let multi_hash = CurrentNetwork::hash_to_field(&[field_a, field_b, field_c])?;
    println!("Multi-input Hash: {}", multi_hash);
    
    Ok(())
}

Example 4: Complete Application

Combining all concepts into a practical example:
use snarkvm::prelude::*;
use anyhow::Result;

type CurrentNetwork = MainnetV0;

fn main() -> Result<()> {
    println!("=== SnarkVM Quick Start Demo ===");
    println!();
    
    // 1. Account Generation
    println!("[1] Generating Account");
    let rng = &mut snarkvm_utilities::TestRng::default();
    let private_key = PrivateKey::<CurrentNetwork>::new(rng)?;
    let address = Address::try_from(&private_key)?;
    println!("  Address: {}", address);
    println!();
    
    // 2. Field Operations
    println!("[2] Field Operations");
    let value = Field::<CurrentNetwork>::from_u64(1000);
    let multiplier = Field::<CurrentNetwork>::from_u64(3);
    let result = value * multiplier;
    println!("  {} * {} = {}", value, multiplier, result);
    println!();
    
    // 3. Cryptographic Hash
    println!("[3] Cryptographic Hash");
    let message = Field::<CurrentNetwork>::from_u64(42);
    let hash = CurrentNetwork::hash_to_field(&[message])?;
    println!("  Hash of {}: {}", message, hash);
    println!();
    
    // 4. Random Field Element
    println!("[4] Random Field Element");
    let random_field = Field::<CurrentNetwork>::rand(rng);
    println!("  Random: {}", random_field);
    println!();
    
    println!("✓ All operations completed successfully!");
    
    Ok(())
}
Run this complete example:
cargo run --release
Expected output:
=== SnarkVM Quick Start Demo ===

[1] Generating Account
  Address: aleo1...

[2] Field Operations
  1000 * 3 = 3000

[3] Cryptographic Hash
  Hash of 42: 5891234...

[4] Random Field Element
  Random: 1839567...

✓ All operations completed successfully!

Understanding Network Types

SnarkVM supports multiple network configurations:
use snarkvm::console::network::MainnetV0;
type CurrentNetwork = MainnetV0;
Use MainnetV0 for production applications. TestnetV0 and CanaryV0 are for testing and development.

Common Patterns

Error Handling

SnarkVM uses Result types extensively:
use snarkvm::prelude::*;
use anyhow::{Result, Context};

fn create_account() -> Result<Address<MainnetV0>> {
    let rng = &mut snarkvm_utilities::TestRng::default();
    let private_key = PrivateKey::new(rng)
        .context("Failed to generate private key")?;
    let address = Address::try_from(&private_key)
        .context("Failed to derive address")?;
    Ok(address)
}

Working with Random Number Generators

use snarkvm_utilities::TestRng;

// For deterministic testing
let rng = &mut TestRng::fixed(12345);

// For random generation
let rng = &mut TestRng::default();
TestRng is for testing only. For production applications, use cryptographically secure random number generators.

Next Steps

Console Types

Learn about Field, Group, Scalar, and other primitive types

Program Synthesis

Execute Aleo programs and generate zero-knowledge proofs

Circuit Development

Build constraint systems for custom computations

API Reference

Explore the complete API documentation

Troubleshooting

Compilation Errors

If you encounter compilation errors:
# Clean build artifacts
cargo clean

# Update dependencies
cargo update

# Rebuild
cargo build --release

Performance Issues

For optimal performance:
  • Always use --release flag for production builds
  • Enable CPU-specific optimizations in .cargo/config.toml:
[target.'cfg(not(target_env = "msvc"))']
rustflags = ["-C", "target-cpu=native"]

Getting Help

GitHub Issues

Report bugs or request features

Discord Community

Join the Aleo developer community

Build docs developers (and LLMs) love