28 个版本 (17 个稳定版)

3.3.0 2024年7月30日
3.2.0 2024年5月13日
3.1.1 2024年3月25日
3.0.1 2023年11月3日
0.1.0 2019年8月6日

#516 in 神奇豆

Download history 83/week @ 2024-04-29 207/week @ 2024-05-06 383/week @ 2024-05-13 126/week @ 2024-05-20 52/week @ 2024-05-27 171/week @ 2024-06-03 260/week @ 2024-06-10 303/week @ 2024-06-17 396/week @ 2024-06-24 79/week @ 2024-07-01 51/week @ 2024-07-08 149/week @ 2024-07-15 59/week @ 2024-07-22 336/week @ 2024-07-29 85/week @ 2024-08-05 223/week @ 2024-08-12

每月712次下载
用于 15 个包 (12 个直接使用)

MIT 许可证

1.5MB
19K SLoC

包含 (ELF 可执行文件/库, 110KB) src/test-data/omni_lock, (ELF 可执行文件/库, 67KB) src/test-data/anyone_can_pay, (ELF 可执行文件/库, 83KB) src/test-data/ckb-cheque-script, (ELF 可执行文件/库, 40KB) src/test-data/cycle.debug, (ELF 可执行文件/库, 1KB) src/test-data/always_success, (ELF 可执行文件/库, 1KB) src/test-data/cycle 和更多.

CKB SDK Rust

Nervos CKB 的 Rust SDK 为开发者提供了几个基本功能

  • CKB 节点的 RPC 访问
  • CKB 内部各种概念的数据结构定义
  • 支持组装 CKB 交易
  • 支持常用 锁脚本 的签名解锁。

这些功能允许与 CKB 无缝交互,并促进了 CKB 网络上去中心化应用程序的开发。

安装

# Cargo.toml
[dependencies]
ckb-sdk = "3.3.0"

构建

构建

cargo build

运行单元测试

make test

有关更多编译命令,请参阅Makefile

快速入门

设置

ckb-sdk-rust 提供了一个方便的客户端,使您能够轻松与 CKB 节点交互。

use ckb_sdk::rpc::CkbRpcClient;

let mut ckb_client = CkbRpcClient::new("https://testnet.ckb.dev");
let block = ckb_client.get_block_by_number(0.into()).unwrap();
println!("block: {}", serde_json::to_string_pretty(&block).unwrap());

有关 CKB RPC API 的更多详细信息,请参阅CKB RPC 文档

手动构建交易

以下代码示例演示了如何在 CKB 上构建转账交易。您可以使用它将指定数量的 CKB 从一个地址转账到另一个地址。

注意:地址和密钥仅用于演示目的,不应在生产环境中使用。

use ckb_sdk::{
    constants::SIGHASH_TYPE_HASH,
    rpc::CkbRpcClient,
    traits::{
        DefaultCellCollector, DefaultCellDepResolver, DefaultHeaderDepResolver,
        DefaultTransactionDependencyProvider, SecpCkbRawKeySigner,
    },
    tx_builder::{transfer::CapacityTransferBuilder, CapacityBalancer, TxBuilder},
    unlock::{ScriptUnlocker, SecpSighashUnlocker},
    Address, HumanCapacity, ScriptId,
};
use ckb_types::{
    bytes::Bytes,
    core::BlockView,
    h256,
    packed::{CellOutput, Script, WitnessArgs},
    prelude::*,
};
use std::{collections::HashMap, str::FromStr};

// Prepare the necessary data for a CKB transaction:
//   * set the RPC endpoint for the testnet
//   * define the sender's address and secret key
//   * define the recipient's address
//   * specify the capacity to transfer
let ckb_rpc = "https://testnet.ckb.dev:8114";
let sender = Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqf7v2xsyj0p8szesqrwqapvvygpc8hzg9sku954v").unwrap();
let sender_key = secp256k1::SecretKey::from_slice(
    h256!("0xef4dfe655b3df20838bdd16e20afc70dfc1b9c3e87c54c276820315a570e6555").as_bytes(),
)
.unwrap();
let receiver = Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqvglkprurm00l7hrs3rfqmmzyy3ll7djdsujdm6z").unwrap();
let capacity = HumanCapacity::from_str("100.0").unwrap();

 // Build ScriptUnlocker
let signer = SecpCkbRawKeySigner::new_with_secret_keys(vec![sender_key]);
let sighash_unlocker = SecpSighashUnlocker::from(Box::new(signer) as Box<_>);
let sighash_script_id = ScriptId::new_type(SIGHASH_TYPE_HASH.clone());
let mut unlockers = HashMap::default();
unlockers.insert(
    sighash_script_id,
    Box::new(sighash_unlocker) as Box<dyn ScriptUnlocker>,
);

// Build CapacityBalancer
let placeholder_witness = WitnessArgs::new_builder()
    .lock(Some(Bytes::from(vec![0u8; 65])).pack())
    .build();
let balancer = CapacityBalancer::new_simple(sender.payload().into(), placeholder_witness, 1000);

// Build:
//   * CellDepResolver
//   * HeaderDepResolver
//   * CellCollector
//   * TransactionDependencyProvider
let mut ckb_client = CkbRpcClient::new(ckb_rpc);
let cell_dep_resolver = {
    let genesis_block = ckb_client.get_block_by_number(0.into()).unwrap().unwrap();
    DefaultCellDepResolver::from_genesis(&BlockView::from(genesis_block)).unwrap()
};
let header_dep_resolver = DefaultHeaderDepResolver::new(ckb_rpc);
let mut cell_collector = DefaultCellCollector::new(ckb_rpc);
let tx_dep_provider = DefaultTransactionDependencyProvider::new(ckb_rpc, 10);

// Build the transaction
let output = CellOutput::new_builder()
    .lock(Script::from(&receiver))
    .capacity(capacity.0.pack())
    .build();
let builder = CapacityTransferBuilder::new(vec![(output, Bytes::default())]);
let (_tx, _) = builder
    .build_unlocked(
        &mut cell_collector,
        &cell_dep_resolver,
        &header_dep_resolver,
        &tx_dep_provider,
        &balancer,
        &unlockers,
    )
    .unwrap();

生成新地址

在 CKB 中,可以使用私钥生成公钥,然后使用 Blake2b 哈希算法对其进行哈希,从而生成 CKB 地址。公钥是通过使用 secp256k1 椭圆曲线密码学算法从私钥派生出来的。这个过程产生了一个唯一的 CKB 地址,可用于接收或发送 CKB 代币。保护私钥的安全非常重要,因为任何能够访问私钥的人都有可能访问相关的 CKB 资金。

use ckb_sdk::types::{Address, AddressPayload, NetworkType};
use rand::Rng;

let mut rng = rand::thread_rng();
let privkey_bytes: [u8; 32] = rng.gen();
let secp_secret_key = secp256k1::SecretKey::from_slice(&privkey_bytes).unwrap();
let pubkey =
    secp256k1::PublicKey::from_secret_key(&ckb_crypto::secp::SECP256K1, &secp_secret_key);
let payload = AddressPayload::from_pubkey(&pubkey);
let address = Address::new(NetworkType::Mainnet, payload, true);
println!("address: {}", address.to_string());

解析地址

在 CKB 的世界中,锁脚本可以表示为地址。可以从编码字符串中解析地址,然后获取其网络和脚本。

use ckb_sdk::types::Address;
use ckb_types::packed::Script;
use std::str::FromStr;

let addr_str = "ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgvf0k9sc40s3azmpfvhyuudhahpsj72tsr8cx3d";
let addr = Address::from_str(addr_str).unwrap();
let _network = addr.network();
let _script: Script = addr.payload().into();

有关 CKB 地址的更多详细信息,请参阅 CKB rfc 0021

更多示例

您可以通过在终端运行以下命令尝试编译它们

cargo build --examples

有关使用 CKB 节点构建事务的更多用例,请参阅 这些示例单元测试

许可证

该 SDK 以开源形式提供,遵循 MIT 许可证 的条款。

变更日志

有关更多详细信息,请参阅 变更日志

依赖关系

~26–60MB
~1M SLoC