Rust区块链容量计算库ckb-occupied-capacity的使用:高效管理与验证CKB链上空间占用
Rust区块链容量计算库ckb-occupied-capacity的使用:高效管理与验证CKB链上空间占用
ckb-occupied-capacity简介
ckb-occupied-capacity是Nervos CKB区块链的一个组件库,用于计算和管理CKB链上的空间占用情况。该库的最小支持Rust版本(MSRV)为1.85.0。
安装方法
在项目目录中运行以下Cargo命令:
cargo add ckb-occupied-capacity
或者在Cargo.toml中添加以下依赖项:
ckb-occupied-capacity = "0.202.0"
完整示例代码
以下是一个使用ckb-occupied-capacity计算CKB链上空间占用的完整示例:
use ckb_occupied_capacity::Capacity;
use ckb_types::{bytes::Bytes, core::Capacity as CoreCapacity};
fn main() {
// 创建一个简单的数据示例
let data = Bytes::from(vec![0u8; 100]);
// 计算数据占用的容量
let occupied_capacity = Capacity::bytes(data.len()).unwrap();
// 转换为core::Capacity类型
let core_capacity: CoreCapacity = occupied_capacity.into();
println!("数据占用容量: {} shannons", core_capacity.as_u64());
// 验证容量是否足够
let available_capacity = CoreCapacity::shannons(200);
if available_capacity >= core_capacity {
println!("可用容量足够");
} else {
println!("可用容量不足");
}
}
扩展示例代码
以下是一个更完整的示例,展示了如何处理不同类型的数据和容量计算:
use ckb_occupied_capacity::{Capacity, Error};
use ckb_types::{bytes::Bytes, core::Capacity as CoreCapacity, packed::Script};
fn main() -> Result<(), Error> {
// 示例1: 计算字节数据的容量
let data = Bytes::from(vec![1, 2, 3, 4, 5]);
let data_capacity = Capacity::bytes(data.len())?;
println!("5字节数据占用容量: {} shannons", data_capacity.as_u64());
// 示例2: 计算脚本的容量
let script = Script::default();
let script_capacity = Capacity::bytes(script.as_bytes().len())?;
println!("默认脚本占用容量: {} shannons", script_capacity.as_u64());
// 示例3: 容量运算
let total_capacity = data_capacity.safe_add(script_capacity)?;
println!("总占用容量: {} shannons", total_capacity.as_u64());
// 示例4: 容量验证
let available = CoreCapacity::shannons(1000);
if available >= total_capacity.into() {
println!("容量验证通过");
} else {
println!("容量不足");
}
Ok(())
}
代码说明
Capacity::bytes()
方法用于计算特定字节数数据占用的CKB容量- 可以方便地在
ckb_occupied_capacity::Capacity
和ckb_types::core::Capacity
之间转换 - 提供了安全的容量运算方法如
safe_add
,避免溢出 - 支持处理各种区块链数据类型如Script的容量计算
- 提供了完整的错误处理机制
该库遵循MIT许可证,是管理CKB链上空间占用的高效工具,特别适合需要精确计算和验证区块链存储空间的场景。
1 回复
Rust区块链容量计算库ckb-occupied-capacity使用指南
介绍
ckb-occupied-capacity
是一个专门为Nervos CKB(Common Knowledge Base)区块链开发的Rust库,用于高效计算和管理链上空间(容量)占用情况。它提供了一套工具来验证交易和单元格(Cell)的容量占用,确保符合CKB网络规则。
主要功能
- 计算交易和单元格的占用容量
- 验证容量是否符合CKB网络要求
- 支持各种CKB数据类型和结构
- 提供精确的容量计算算法
安装方法
在Cargo.toml中添加依赖:
[dependencies]
ckb-occupied-capacity = "0.5.0"
基本使用方法
1. 计算单元格容量
use ckb_occupied_capacity::{Capacity, Result};
fn calculate_cell_capacity() -> Result<Capacity> {
let data = vec![0u8; 100]; // 单元格数据
let capacity = Capacity::bytes(data.len())?;
Ok(capacity)
}
2. 验证交易容量
use ckb_occupied_capacity::{Capacity, Ratio};
fn verify_transaction_capacity(input_cap: u64, output_cap: u64) -> bool {
let input_capacity = Capacity::shannons(input_cap);
let output_capacity = Capacity::shannons(output_cap);
// 确保输出不超过输入
output_capacity <= input_capacity
}
3. 计算复杂交易容量
use ckb_types::{packed, prelude::*};
use ckb_occupied_capacity::Capacity;
fn calculate_transaction_occupied_capacity(tx: packed::Transaction) -> Result<Capacity, String> {
let tx_size = tx.as_slice().len();
Capacity::bytes(tx_size).map_err(|e| e.to_string())
}
高级用法
1. 计算带锁脚本的容量
use ckb_types::{packed, prelude::*};
use ckb_occupied capacity::Capacity;
fn calculate_cell_with_lock_script(
lock_script: packed::Script,
data: &[u8]
) -> Result<Capacity, String> {
let lock_script_size = lock_script.as_slice().len();
let total_size = lock_script_size + data.len();
Capacity::bytes(total_size).map_err(|e| e.to_string())
}
2. 容量比例计算
use ckb_occupied_capacity::{Capacity, Ratio};
fn calculate_capacity_ratio(used: Capacity, total: Capacity) -> Ratio {
used / total
}
实际应用示例
构建合规交易
use ckb_types::{packed, core::TransactionBuilder};
use ckb_occupied_capacity::Capacity;
fn build_valid_transaction(
inputs: Vec<packed::CellInput>,
outputs: Vec<packed::CellOutput>,
outputs_data: Vec<bytes::Bytes>
) -> Result<packed::Transaction, String> {
let tx = TransactionBuilder::default()
.inputs(inputs)
.outputs(outputs)
.outputs_data(outputs_data)
.build();
// 验证输入容量是否足够
let input_cap: Capacity = tx.input_capacities()?;
let output_cap: Capacity = tx.output_capacities()?;
if output_cap > input_cap {
return Err("输出容量超过输入容量".to_string());
}
Ok(tx)
}
完整示例demo
以下是一个完整的CKB交易构建和容量验证示例:
use ckb_types::{
packed::{self, CellInput, CellOutput, Script},
prelude::*,
bytes::Bytes,
core::TransactionBuilder,
};
use ckb_occupied_capacity::{Capacity, Result as CapResult};
// 构建一个完整的CKB交易并进行容量验证
fn build_and_verify_transaction() -> Result<packed::Transaction, String> {
// 1. 准备交易输入
let input_cell = create_input_cell()?;
// 2. 准备交易输出
let output_cell = create_output_cell()?;
// 3. 构建交易
let tx = TransactionBuilder::default()
.inputs(vec![input_cell.input])
.outputs(vec![output_cell.output])
.outputs_data(vec![output_cell.data])
.build();
// 4. 验证交易容量
verify_transaction_capacity(&tx)?;
Ok(tx)
}
// 创建输入单元格
fn create_input_cell() -> Result<CellInfo, String> {
let lock_script = Script::default(); // 实际应用中替换为真实的锁脚本
let data = Bytes::from(vec![0u8; 200]); // 单元格数据
let output = CellOutput::new_builder()
.capacity(Capacity::bytes(lock_script.as_slice().len() + data.len())?.pack())
.lock(lock_script)
.build();
let input = CellInput::new(packed::OutPoint::default(), 0);
Ok(CellInfo {
input,
output,
data,
})
}
// 创建输出单元格
fn create_output_cell() -> Result<CellInfo, String> {
let lock_script = Script::default(); // 实际应用中替换为真实的锁脚本
let data = Bytes::from(vec![0u8; 150]); // 单元格数据
let output = CellOutput::new_builder()
.capacity(Capacity::bytes(lock_script.as_slice().len() + data.len())?.pack())
.lock(lock_script)
.build();
Ok(CellInfo {
input: CellInput::default(),
output,
data,
})
}
// 验证交易容量
fn verify_transaction_capacity(tx: &packed::Transaction) -> CapResult<()> {
let inputs_cap: Capacity = tx.input_capacities()?;
let outputs_cap: Capacity = tx.output_capacities()?;
if outputs_cap > inputs_cap {
return Err(anyhow::anyhow!("输出容量超过输入容量"));
}
// 验证每个单元格满足最小容量要求
for (i, output) in tx.outputs().into_iter().enumerate() {
let output_data = tx.outputs_data().get(i).unwrap_or_default();
let occupied = Capacity::bytes(output.as_slice().len() + output_data.len())?;
let provided = Capacity::shannons(output.capacity().unpack());
if provided < occupied {
return Err(anyhow::anyhow!("单元格{}容量不足", i));
}
}
Ok(())
}
// 辅助结构体
struct CellInfo {
input: CellInput,
output: CellOutput,
data: Bytes,
}
fn main() {
match build_and_verify_transaction() {
Ok(tx) => println!("交易构建成功: {:?}", tx),
Err(e) => eprintln!("交易验证失败: {}", e),
}
}
注意事项
- 容量计算必须精确到字节级别
- CKB的最小容量单位是Shannon (1 CKB = 100,000,000 Shannon)
- 所有单元格必须满足最小容量要求
- 交易费也需要从输入容量中扣除
性能建议
- 对于批量计算,考虑使用缓存机制
- 在频繁计算的场景下,可以预计算固定结构的容量
- 使用
Capacity
类型而不是原始u64来避免单位混淆
这个库是开发CKB dApp和智能合约的重要工具,能确保你的应用符合CKB网络容量规则,避免交易被拒绝。