Rust Cardano区块链序列化库cardano-serialization-lib的使用,支持高效交易构建与脚本解析

Cardano Serialization Lib

这是一个用Rust编写的库,用于序列化和反序列化Cardano在Haskell实现的Alonzo版本中使用的数据结构,并提供有用的实用函数。

安装

在您的项目目录中运行以下Cargo命令:

cargo add cardano-serialization-lib

或者在您的Cargo.toml中添加以下行:

cardano-serialization-lib = "15.0.0"

使用示例

下面是一个使用cardano-serialization-lib构建交易和解析脚本的完整示例:

use cardano_serialization_lib::{Transaction, TransactionBody, TransactionWitnessSet, 
                               TransactionOutput, TransactionInput, Value, 
                               NativeScript, ScriptHash, AssetName, MultiAsset};

fn main() {
    // 1. 创建交易输入
    let input = TransactionInput::new(
        &[0u8; 32],  // 交易哈希
        0            // 索引
    );
    
    // 2. 创建交易输出
    let output = TransactionOutput::new(
        &[0u8; 28],  // 接收者地址
        &Value::new(&1000000.into())  // 金额
    );
    
    // 3. 创建交易体
    let mut tx_body = TransactionBody::new();
    tx_body.add_input(&input);
    tx_body.add_output(&output);
    tx_body.set_fee(&100000.into());  // 设置手续费
    
    // 4. 创建见证集(可选)
    let mut witness_set = TransactionWitnessSet::new();
    
    // 5. 创建原生脚本(可选)
    let script = NativeScript::new_script_pubkey(&[0u8; 32]);  // 公钥哈希脚本
    let script_hash = ScriptHash::from_bytes(script.hash().to_bytes());
    
    // 6. 创建交易
    let tx = Transaction::new(
        &tx_body,
        &witness_set,
        None  // 元数据(可选)
    );
    
    // 7. 序列化交易
    let tx_bytes = tx.to_bytes();
    println!("Serialized transaction: {:?}", tx_bytes);
    
    // 8. 反序列化交易
    let deserialized_tx = Transaction::from_bytes(&tx_bytes).unwrap();
    println!("Deserialized transaction inputs: {}", deserialized_tx.body().inputs().len());
}

完整示例

下面是一个更完整的示例,展示如何使用Cardano Serialization Lib处理多资产交易:

use cardano_serialization_lib::{
    Transaction, TransactionBody, TransactionWitnessSet,
    TransactionOutput, TransactionInput, Value,
    NativeScript, ScriptHash, AssetName, MultiAsset,
    BigNum, Address, TransactionBuilder, 
    utils::from_bignum
};

fn main() {
    // 1. 创建交易构建器
    let mut tx_builder = TransactionBuilder::new();
    
    // 2. 创建交易输入
    let input = TransactionInput::new(
        &[1u8; 32],  // 交易哈希
        0            // 索引
    );
    
    // 3. 创建多资产
    let mut multi_asset = MultiAsset::new();
    let asset_name = AssetName::new(vec![1, 2, 3]);  // 资产名称
    let amount = BigNum::from(100);  // 资产数量
    
    multi_asset.insert(
        &[0u8; 28],  // 资产政策ID
        &asset_name,
        &amount
    );
    
    // 4. 创建交易输出(包含多资产)
    let output = TransactionOutput::new(
        &Address::from_bytes(&[0u8; 28]).unwrap(),  // 接收者地址
        &Value::new_with_assets(
            &BigNum::from(2000000),  // ADA数量
            &multi_asset  // 多资产
        )
    );
    
    // 5. 添加输入和输出到交易体
    tx_builder.add_input(&input);
    tx_builder.add_output(&output);
    
    // 6. 设置手续费
    tx_builder.set_fee(&BigNum::from(170000));
    
    // 7. 创建见证集(包含原生脚本)
    let mut witness_set = TransactionWitnessSet::new();
    let script = NativeScript::new_script_all(vec![
        NativeScript::new_script_pubkey(&[1u8; 32])  // 多签脚本
    ]);
    witness_set.add_native_script(&script);
    
    // 8. 构建最终交易
    let tx = Transaction::new(
        &tx_builder.build(),
        &witness_set,
        None  // 元数据(可选)
    );
    
    // 9. 序列化交易
    let tx_bytes = tx.to_bytes();
    println!("Serialized transaction with multi-assets: {:?}", tx_bytes);
    
    // 10. 反序列化交易
    let deserialized_tx = Transaction::from_bytes(&tx_bytes).unwrap();
    println!(
        "Deserialized transaction has {} inputs and {} outputs",
        deserialized_tx.body().inputs().len(),
        deserialized_tx.body().outputs().len()
    );
    
    // 11. 获取交易中的多资产信息
    if let Some(output) = deserialized_tx.body().outputs().get(0) {
        if let Some(assets) = output.amount().multiasset() {
            println!("Transaction contains multi-assets:");
            for (policy_id, assets_map) in assets.keys() {
                for (asset_name, amount) in assets_map.keys() {
                    println!(
                        "Asset: {}.{}, Amount: {}",
                        hex::encode(policy_id.to_bytes()),
                        hex::encode(asset_name.to_bytes()),
                        from_bignum(&amount)
                    );
                }
            }
        }
    }
}

功能说明

  1. 交易构建:可以创建交易输入、输出、设置手续费等,构建完整的Cardano交易
  2. 脚本解析:支持原生脚本(NativeScript)的创建和解析
  3. 序列化/反序列化:提供高效的二进制序列化和反序列化功能
  4. 多资产支持:可以处理Cardano上的多资产(MultiAsset)交易

版本信息

  • 版本:15.0.0
  • 许可证:MIT
  • 发布方式:2018 edition
  • 大小:342 KiB

1 回复

Rust Cardano区块链序列化库cardano-serialization-lib使用指南

介绍

cardano-serialization-lib是一个用于Cardano区块链的Rust序列化库,它提供了高效构建交易和解析脚本的能力。这个库是Cardano生态系统中重要的开发工具,特别适合需要与Cardano区块链交互的Rust开发者。

主要功能包括:

  • Cardano交易构建和序列化
  • 原生脚本和多签名脚本处理
  • 地址生成和验证
  • 元数据处理
  • CBOR编码/解码

安装

在Cargo.toml中添加依赖:

[dependencies]
cardano-serialization-lib = { git = "https://github.com/Emurgo/cardano-serialization-lib", branch = "master" }

基本使用方法

1. 创建简单交易

use cardano_serialization_lib::{
    address::Address,
    crypto::Bip32PrivateKey,
    Transaction, TransactionBuilder, TransactionOutput, TransactionOutputBuilder,
    utils::BigNum,
};

fn create_simple_transaction() {
    // 创建接收地址
    let receiver_address = Address::from_bech32("addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x").unwrap();
    
    // 创建交易输出
    let output = TransactionOutputBuilder::new()
        .with_address(&receiver_address)
        .with_coin(&BigNum::from(1000000)) // 1 ADA = 1,000,000 Lovelace
        .build()
        .unwrap();
    
    // 创建交易构建器
    let mut tx_builder = TransactionBuilder::new();
    tx_builder.add_output(&output);
    
    // 设置TTL (可选)
    tx_builder.set_ttl(12345678);
    
    // 构建交易
    let transaction = tx_builder.build();
    
    // 序列化为CBOR
    let tx_cbor = transaction.to_bytes();
    println!("Transaction CBOR: {:?}", tx_cbor);
}

2. 解析脚本

use cardano_serialization_lib::{
    plutus::{PlutusScript, PlutusData},
    utils::from_bytes
};

fn parse_plutus_script(script_bytes: Vec<u8>) {
    let plutus_script = PlutusScript::from_bytes(script_bytes).unwrap();
    
    // 获取脚本哈希
    let script_hash = plutus_script.hash();
    println!("Script hash: {:?}", script_hash.to_hex());
    
    // 解析脚本中的Plutus数据
    if let Some(data_bytes) = plutus_script.data() {
        let plutus_data = PlutusData::from_bytes(data_bytes).unwrap();
        println!("Parsed Plutus data: {:?}", plutus_data);
    }
}

3. 构建多签名交易

use cardano_serialization_lib::{
    crypto::{Bip32PrivateKey, Ed25519Signature},
    transaction::{Transaction, TransactionBuilder, TransactionWitnessSet},
    utils::BigNum,
    address::Address,
};

fn build_multisig_transaction() {
    // 创建交易输出
    let receiver_address = Address::from_bech32("addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x").unwrap();
    let output = TransactionOutputBuilder::new()
        .with_address(&receiver_address)
        .with_coin(&BigNum::from(5000000)) // 5 ADA
        .build
        .unwrap();
    
    // 创建交易构建器
    let mut tx_builder = TransactionBuilder::new();
    tx_builder.add_output(&output);
    
    // 构建未签名的交易
    let unsigned_tx = tx_builder.build();
    
    // 创建见证集
    let mut witness_set = TransactionWitnessSet::new();
    
    // 模拟多个签名
    let priv_key1 = Bip32PrivateKey::generate_ed25519_bip32().to_raw_key();
    let priv_key2 = Bip32PrivateKey::generate_ed25519_bip32().to_raw_key();
    
    // 对交易体哈希进行签名
    let tx_body_hash = unsigned_tx.body().hash();
    let signature1 = priv_key1.sign(&tx_body_hash.to_bytes());
    let signature2 = priv_key2.sign(&tx_body_hash.to_bytes());
    
    // 添加见证
    let mut vkey_witnesses = witness_set.vkeys().unwrap_or_default();
    vkey_witnesses.add(&signature1);
    vkey_witnesses.add(&signature2);
    witness_set.set_vkeys(&vkey_witnesses);
    
    // 构建最终交易
    let signed_tx = Transaction::new(
        unsigned_tx.body(),
        Some(witness_set),
        unsigned_tx.auxiliary_data()
    );
    
    println!("Signed transaction: {:?}", signed_tx.to_bytes());
}

高级功能

1. 处理元数据

use cardano_serialization_lib::{
    metadata::GeneralTransactionMetadata,
    transaction::{AuxiliaryData, TransactionMetadata},
    utils::from_bytes,
};

fn add_metadata_to_transaction() {
    // 创建元数据
    let mut metadata = GeneralTransactionMetadata::new();
    metadata.insert(&BigNum::from(1), &Metadata::new_text("Hello Cardano!").unwrap());
    
    // 构建辅助数据
    let mut auxiliary_data = AuxiliaryData::new();
    auxiliary_data.set_metadata(&TransactionMetadata::new(metadata));
    
    // 可以在交易构建器中添加
    let mut tx_builder = TransactionBuilder::new();
    tx_builder.set_auxiliary_data(&auxiliary_data);
}

2. 处理原生资产

use cardano_serialization_lib::{
    address::Address,
    assets::{AssetName, MintAssets},
    crypto::ScriptHash,
    transaction::{TransactionBuilder, TransactionOutputBuilder},
    utils::BigNum,
};

fn handle_native_assets() {
    // 创建资产
    let policy_id = ScriptHash::from_bytes(vec![0; 28].unwrap(); // 示例policy id
    let asset_name = AssetName::new(vec![65, 65, 65]).unwrap(); // "AAA"
    
    // 创建MintAssets
    let mut mint_assets = MintAssets::new();
    mint_assets.insert(&asset_name, &BigNum::from(100)); // 铸造100个AAA资产
    
    // 创建交易构建器并设置mint
    let mut tx_builder = TransactionBuilder::new();
    tx_builder.set_mint(&mint_assets, &policy_id);
    
    // 创建包含资产的输出
    let receiver_address = Address::from_bech32("addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x").unwrap();
    let output = TransactionOutputBuilder::new()
        .with_address(&receiver_address)
        .with_coin(&BigNum::from(2000000)) // 2 ADA
        .with_asset(&policy_id, &asset_name, &BigNum::from(50)) // 发送50个AAA资产
        .build()
        .unwrap();
    
    tx_builder.add_output(&output);
    
    let transaction = tx_builder.build();
    println!("Transaction with native assets: {:?}", transaction.to_bytes());
}

完整示例

下面是一个结合上述功能的完整示例,展示如何构建一个包含元数据和原生资产的Cardano交易:

use cardano_serialization_lib::{
    address::Address,
    assets::{AssetName, MintAssets},
    crypto::{Bip32PrivateKey, Ed25519Signature},
    metadata::{GeneralTransactionMetadata, Metadata},
    plutus::PlutusData,
    transaction::{
        AuxiliaryData, Transaction, TransactionBuilder, TransactionMetadata,
        TransactionOutput, TransactionOutputBuilder, TransactionWitnessSet,
    },
    utils::BigNum,
    ScriptHash,
};

fn build_complete_transaction() {
    // 1. 创建交易构建器
    let mut tx_builder = TransactionBuilder::new();

    // 2. 添加普通ADA输出
    let receiver_address = Address::from_bech32("addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgse35a3x").unwrap();
    let output = TransactionOutputBuilder::new()
        .with_address(&receiver_address)
        .with_coin(&BigNum::from(1000000)) // 1 ADA
        .build()
        .unwrap();
    tx_builder.add_output(&output);

    // 3. 添加原生资产输出
    let policy_id = ScriptHash::from_bytes(vec![0; 28]).unwrap();
    let asset_name = AssetName::new(vec![65, 65, 65]).unwrap(); // "AAA"
    let asset_output = TransactionOutputBuilder::new()
        .with_address(&receiver_address)
        .with_coin(&BigNum::from(2000000)) // 2 ADA
        .with_asset(&policy_id, &asset_name, &BigNum::from(50)) // 50个AAA资产
        .build()
        .unwrap();
    tx_builder.add_output(&asset_output);

    // 4. 设置铸造资产
    let mut mint_assets = MintAssets::new();
    mint_assets.insert(&asset_name, &BigNum::from(100)); // 铸造100个AAA资产
    tx_builder.set_mint(&mint_assets, &policy_id);

    // 5. 添加元数据
    let mut metadata = GeneralTransactionMetadata::new();
    metadata.insert(
        &BigNum::from(1),
        &Metadata::new_text("Hello Cardano!").unwrap(),
    );
    let mut auxiliary_data = AuxiliaryData::new();
    auxiliary_data.set_metadata(&TransactionMetadata::new(metadata));
    tx_builder.set_auxiliary_data(&auxiliary_data);

    // 6. 设置TTL
    tx_builder.set_ttl(12345678);

    // 7. 构建未签名交易
    let unsigned_tx = tx_builder.build();

    // 8. 签名交易
    let mut witness_set = TransactionWitnessSet::new();
    let priv_key = Bip32PrivateKey::generate_ed25519_bip32().to_raw_key();
    let tx_body_hash = unsigned_tx.body().hash();
    let signature = priv_key.sign(&tx_body_hash.to_bytes());

    let mut vkey_witnesses = witness_set.vkeys().unwrap_or_default();
    vkey_witnesses.add(&signature);
    witness_set.set_vkeys(&vkey_witnesses);

    // 9. 构建最终交易
    let signed_tx = Transaction::new(
        unsigned_tx.body(),
        Some(witness_set),
        unsigned_tx.auxiliary_data(),
    );

    // 10. 序列化为CBOR
    let tx_cbor = signed_tx.to_bytes();
    println!("Final transaction CBOR: {:?}", tx_cbor);
}

注意事项

  1. 该库主要提供Cardano区块链数据的序列化和反序列化功能,不直接处理网络通信
  2. 对于密钥管理,建议使用专门的加密库
  3. 在生产环境中使用前,务必充分测试所有交易
  4. 注意Cardano协议更新可能导致API变化
回到顶部