交易所整合 CKB 简明方案

简介

Nervos CKB (简称 CKB) 是一个基于 UXTO 账户模型的 PoW 智能合约区块链,其虚拟机使用 RISC-V 指令集。Nervos CKB 的基础资产叫 CKB,或 CKBytes,其主要用途是支付状态空间占用费以及矿工费。

CKB 默认的签名算法是 secp256k1,默认的哈希算法是 blake2b。与 Bitcoin 和 Ethereum 充值方式相同,交易所可以为每个用户生成专用地址,用户向该专用地址充值。

区块链浏览器: https://explorer.nervos.org/
测试链水龙头:https://faucet.nervos.org/
桌面钱包:https://github.com/nervosnetwork/neuron
移动钱包:imToken, Bitpie, ABCWallet, Cobo, Hoo 等
SDK: ckb-sdk-js, ckb-sdk-java, ckb-sdk-go

整合步骤

1. 运行节点

Nervos 基金会并不提供中心化的公共 API。为了安全考虑,作为钱包或交易所运营方应该自行运行区块链节点(ckb node)和缓存中间件(ckb-indexer)。缓存中间件提供了查询余额、历史交易等便捷的接口。

这里还可以找到 ckb 开发团队维护的二合一 docker 映像,可以一键运行。它包括两组 API:ckb rpcckb-indexer rpc,分别在 http://localhost:8117/rpc,http://localhost:8117/indexer。

2. 生成充值地址

私钥生成

CKB 默认签名算法采用 secp256k1,公私钥生成算法与比特币、以太坊相同。

公钥与地址的关系

CKB 上的用户资产由 lock script 管理,每一个 lock script 对应一种签名算法和一个公钥哈希。地址是对 lock script 的人类可读编码:lock script ⇔ 地址

lock_script: {
	code_hash:	// 32 bytes 签名算法合约地址或代码hash (*固定数值*)
	hash_type:	// type/data 与 code_hash 配对设置 (*固定数值*)
	args: 		// 用户的公钥哈希
}

CKB 节点仅识别 lock script,应用层需要对地址进行转换。对于交易所充值地址来说,code_hashhash_type 都是固定值,仅需要根据 args 变化。

地址生成

生成私钥 => 生成公钥 => 取 blake2b 哈希前20字节作为 args 
  => 拼凑 lock script => 转换成地址

公钥到地址的 API:java sdkjs sdk(utils.pubkeyToAddress)

地址合法性校验

CKB 转账支持多种地址格式,SDK 已经对他们进行了恰当处理。前端可以使用 utils.parseAddress 进行地址合法性校验,后端 SDK 会自动把他们转换成 lock script 处理。

3. 查询

  • 余额查询:get_cell_capacity (from ckb-indexer-rpc)

  • tip header: get_tip (from ckb-indexer-rpc)

  • 不可逆确认数:24

  • 根据高度查block:get_block_by_number (from ckb-rpc)

  • 根据hash查block:get_block (from ckb-rpc)

  • 有效交易判定:所有的入块交易都是有效交易(与以太坊不同)

  • 交易历史查询:get_transactions (from ckb-indexer-rpc)

4. 转账

注意:由于 CKB 的底层逻辑,默认情况下转账和找零的最小金额是 61 ckb

转账实现请参考:

关于转账的原理,请参考 How to sign the transaction.

转账手续费的设置原理,请参考 Transaction Fee.

5. Live Cell 管理

注意:Live Cell 管理对业务可靠性非常重要,务必妥善处理

作为 UTXO 公链,每一笔对外转账都需要引用一定数量的 live cells 作为 input。但如果连续发送交易,就会出现 live cell 重复花费,或者可用 live cell 不足的情况。例如,通过 ckb-indexer 获取用户可用 cell 后连续发起交易,在上一笔交易未上链前,ckb-indexer 仍然可能返回其引用的 input cell 作为 live cell。这就需要开发者对已经引用但尚未上链的 cell 进行特殊处理。这里给出两个处理方案:

  • 开发者管理一个未上链的 TX 池,标记其引用的 input 为无效,新的交易中剔除这些 cell。在该交易成功上链或被区块链拒绝后更新该 TX 池;
  • 串行处理交易,每次发出 TX 后,等待交易上链,在等待过程中收集转账请求,在上一笔交易上链后构造一笔多输出交易,把收集到的转账请求一起发出。

6. 公共服务器

注意:个人建议,考虑到安全性和可靠性,接入方在生产环境务必使用自己维护的节点。下面收集的公共服务器由社区公益维护,仅供测试,不保证可用性。

Testnet:

https://testnet.ckb.dev/rpc => ckb node rpc
https://testnet.ckb.dev/indexer => ckb-indexer rpc

Mainnet:

https://mainnet.ckb.dev/rpc => ckb node rpc
https://mainnet.ckb.dev/indexer => ckb-indexer rpc

7 Likes

英文翻译版请见

1 Like

获得余额get_cells_capacity是否有问题?取到的余额都为0,与实际不符

需要等待 ckb-indexer 同步到最新高度。通过 get_tip 查询当前进度。

把你的地址和请求命令行都发一下看看。

噢,抱歉,是我的问题,我在模块代码里临时将服务器地址给写死为本地公网ckb-indexer rpc了,忘改回来了 :joy:

还有个问题请教下,ckb有合约币么?没有在文档中找到 想要确认下

你指的合约币是 sUDT 吗?

就是通过合约衍生的CKB的二代币,就像BCH/BTG/B2X都是比特币的合约币

代币如何转账呢?

转账功能似乎有问题,按照 sendSimpleTransaction 执行,但ckb.loadCells永远取不到cell,‘Input capacity is not enough’(ckb充足)

地址:ckt1qyqdl5w5k303qutwws4c0y34rygljqck8h8q8fh39z
私钥:0x3fb2613c8943fce49a6bc63fe52acba446f090d8f2809429820c7ae52bcdefad