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)
);
}
}
}
}
}
功能说明
- 交易构建:可以创建交易输入、输出、设置手续费等,构建完整的Cardano交易
- 脚本解析:支持原生脚本(NativeScript)的创建和解析
- 序列化/反序列化:提供高效的二进制序列化和反序列化功能
- 多资产支持:可以处理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);
}
注意事项
- 该库主要提供Cardano区块链数据的序列化和反序列化功能,不直接处理网络通信
- 对于密钥管理,建议使用专门的加密库
- 在生产环境中使用前,务必充分测试所有交易
- 注意Cardano协议更新可能导致API变化