Skip to content

Instantly share code, notes, and snippets.

@quake
Created March 4, 2020 08:33
Show Gist options
  • Save quake/d7482fc9ae5f0ab358c74b9291a18ad5 to your computer and use it in GitHub Desktop.
Save quake/d7482fc9ae5f0ab358c74b9291a18ad5 to your computer and use it in GitHub Desktop.

RPC

RPC 调用使用了 method missing 自动生成,统一返回结果是 Hash,而不是定义的 Class Type。优点:ckb 新加或者调整 rpc 方法,sdk 不需要跟随升级,缺点:需要查看 ckb 文档调用,ruby doc 无法生成文档,IDE 无自动提示。

RPC 参数做了 Integer 到 Hex 自动转化,方便调用(特别是分页参数这种)

调用方式和之前一样:

rpc = CKB::RPC.new
rpc.get_tip_header
rpc.get_header_by_number(255)
rpc.get_header_by_number(0xff)

Types

Types 直接从 hash 构建出对象,对于 hex string,内部统一使用 bytes,避免原先 SDK 代码里面有大量的 bin_to_hex / hex_to_bin 转化

CKB::Types::OutPoint.new(tx_hash: "0xff44", index: "0xff")
#<CKB::Types::OutPoint @tx_hash=[255, 68], @index=255>

Transaction Builder

把构建交易拆成了2个步骤:生成未签名交易/用私钥对交易进行签名

生成未签名交易(TransactionBuilder#generate) 会通过 collector 来收集 CellMeta,每收集到一个 CellMeta ,根据它对应的 output,去修改交易数据,比如添加 inputs / cell_deps / witnesses 等数据,相关代码请参考 CellMeta#generate

默认提供了2种 collector,一个通过 rpc get_cells_by_lock_hash 从高度0开始遍历(性能差),另外一个是通过 rpc get_live_cells_by_lock_hash (需要节点开启 Indexer 模块)。用户可以实现其他的 Collector 来满足不同的需求,只要返回 Enumerator<CellMeta> 即可

用私钥对交易进行签名(TransactionBuilder#sign) 会依次调用 CellMeta#sign

Wallet

Wallet 是对 Transaction Builder 的包装,提供了一个易用的接口专门用于生成转账交易:

rpc = CKB::RPC.new
wallet = CKB::Wallet.new(rpc)
tx = wallet.gen_tx(
    "ckt1qyqvsv5240xeh85wvnau2eky8pwrhh4jr8ts8vyj37",
    "ckt1qyqywrwdchjyqeysjegpzw38fvandtktdhrs0zaxl4",
    100_0000_0000,
    "0xd00c06bfd800d27397002dca6fb0993d5ba6399b4238b2f29ee9deb97593d2bc".from_hex
)
rpc.send_transaction(tx.as_json)

需要改进的地方

  1. 在这个 sdk 代码结构里面,构建交易和签名的核心代码都移到了 CellMeta 上,它做的两件事情:根据 input 的 lock / type 不同,给交易添加或者修改不同的数据,以及进行不同的签名逻辑。目前是用 if else 来做分支判断,这里的接口需要重新设计一下,将它独立出来,包括实现 DAO 的处理

  2. 构建交易和签名所需要的 context 不同,比如单签 lock,构建交易的时候 context 不需要提供私钥,签名的时候需要私钥。而多签 lock,构建交易的时候,需要 S/M/N/pubkeys 这个 context,而签名的时候只需要 private keys

  3. 序列化是手写的,应该考虑基于 molecule code-gen 生成

  4. 默认的 Collector 要实现开箱可用,需要改成接受从某个高度开始扫描的参数,这样用户就可用一个临时文件保存扫描的高度,而不是每次从0开始扫描

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment