原文中,我们可以发现 confuse、stuck 等单词会时常地出没在眼前,可以感受到 Brian 的认真与贴心。文末我们也整理了一些他遇到的坑或者建议,欢迎参考。如果您是之前没有接触过 CKB,又想要在 Nervos CKB 上开发玩耍的盆友,那么非常欢迎您来围观 Brian 的实操思路,在这篇文章中,您可以看到他踩过的那些坑,也许这可以帮助你省去一些时间。
原文链接:
https://talk.nervos.org/t/experience-report-first-time-building-and-running-ckb/4518
翻译 & 校对:姆斯哥 & 凯莉姐
Hi,最近我花了一些时间学习如何构建以及运行 CKB。在创建这个项目的过程中,我建立了 ckb 和 ckb-cli 以及可以挖矿的 devnet,把它连接到了测试网,用 ckb-cli 创建账户并在测试网上转账。
我发现当我着手一个新项目时,这种记录下我所看到的一切的方法,有助于我更好地理解这个项目。而且在这个过程中,几乎总是会出现许多简单的问题,如果能修正这些问题,那么其他人的体验也将会得到改善。
我希望记录下的这些经验能够向开发团队说明哪些地方是可以改进的,同时也能够帮助其他人开始在 CKB 上进行开发。感谢 Aimee 在资源和测试方面提供的帮助。
写于 2020 年 3 月 12 日至 4 月 5 日
初次尝试运行 CKB
我想要写一个可以运行在 CKB 上的软件,但首先我必须先学习如何建立、运行 CKB 以及使用它的工具。虽然我没有任何的区块链开发经验,但根据我过去的学习,我对 CKB 还是有一定了解的。我之前还在 CKB VM 上创建了一个项目:
http://www.ferrisfencing.org/
我开始是在 Nervos 的 GitHub 上下载那些主要的仓库,并且因此也来到了 Nervos 官网。我需要找到那些在 CKB 上构建以及运行私人测试网的文档,因为一旦我运行了一个测试节点,我将需要那些关于如何编写、部署和测试脚本的文档。
搭建 CKB
我浏览了一下 GitHub 上的 README,也没有看到任何关于如何构建 CKB 的文档。
虽然有两个名为「Get CKB」和「Quick Start」的链接,「Get CKB」的文档还包含了「从源代码构建」的部分,这些文档说要用 make prod 来构建 CKB。但因为 CKB 是一个 Rust 项目,我并不想这样做,相反的我想试试用 cargo build ,于是我便这么做了,而且还成功了。
我总是很好奇它们的 Makefiles 中添加了哪些其它的项目来增强 cargo,在这个例子中它只添加了 --cfg disable_faketime 。我不知道这是什么,但我猜 faketime 应该是在开发过程中可以使用的字段。我注记了这是一个「negative」cargo 特性,通常并不鼓励。
探索开发者文档
我似乎马上就远离了探索文档的「快乐路径」,因为我已经忽略了文档网站,并深入研究了 GitHub Repo 的 markdown,所以我退了回来并重新开始研究文档网站。
为了确保我没有漏掉什么主文档中我正在寻找的东西,我打开了「开始/介绍」的页面。这是关于运行节点、使用钱包以及交易的, 不是开发者文档。
我发誓我是通过点击「开发者文档」链接来到这里的。我又检查了一遍——我是在 nervos.org 上点击了「开发者」→「文档」,最终访问到的 docs.nervos.org,这个网站将自己描述为:
这是 Nervos CKB 的文档站点。在这里,您可以了解 Nervos CKB 的设计,以及如何运行节点和挖出 CKByte 代币。
我很困惑这个文档的读者会是谁。
在这个网站上还有另外一个叫做「开发者指引」的文档,这个页面上也没有任何关于如何构建 CKB 的提示。我还注意到它强调使用名为「Aggron」的测试网,这让我感觉到自己运行自己测试网的方法可能并不受欢迎。
阅读测试网文档
基于文档,我的新计划是学习使用 testnet。虽然我打算使用自己创建的 CKB,不管文档是否要求我下载一个版本。
「Testnet Aggron」页面的第一段真的把我搞糊涂了:
我们即将部署一个 POA 算法以在测试网中产生区块。然而,这将会耗费一些时间去开发。在这之前只要每超过一小时没有出块,我们就会常规性的重置测试网。用于启动 Aggron 的链上规范已经在此发布,请参阅 Aggron 链的文件信息。
我认为这里的「我们」应该指的是 Nervos 这个项目,而不是教程文档中经常用来表示「你」的「royal we」。而且这个似乎是很久以前,也就是测试网刚被部署的时候就写了。(译者注:该页面写于 2019 年 12 月 9 号)。
这个页面让我们下载一个 CKB 新版本,然后我查看了 CKB release 的页面,发现最新的版本是 v0.29.0 。
我查看了 v0.29.0 的 tag,并且在调试模式下重建了 CKB。
这时我发现 ckb-cli 并非 ckb repo 的一部分,我很轻易的就能找到 ckb-cli repo,但却遇到一个绊脚石。
创建 ckb—cli
在 ckb-cli 中并没有 v0.29.0 的 tag。我并不知道 ckb-cli 的哪个版本和 ckb 是匹配的。这个差异让我怀疑从 ckb repo 中释放的 tarballs 是否包含 ckb-cli。
我下载了 0.29 tarball 并发现它确实包含 ckb-cli 。我想确认它的 ckb-cli 是哪一个版本,而我除了运行最新版之外似乎别无选择。于是我便这么做了,然后看到的返回是:
ckb-cli 0.27.1 (9d0bf90 2020-01-31)
所以 ckb 0.29.0 是适配 ckb-cli 0.27.1 的,我猜这两个版本是松散耦合的,我应该总是使用其中一个的最新版本。
我确认了 ckb-cli 的最新版本号并且开始构建。这似乎还涉及建立另一个副本的 ckb。有点恼人,不过就这样吧。
在新的视窗中,我建立了 PATH 来让我有权限进入 ckb 和 ckb-cli。
~/ckb-testing$ export PATH="$PATH:$HOME/ckb/target/debug/:$HOME/ckb-cli/target/debug"~/ckb-testing$ ckb --versionckb 0.29.0 (a6733e6 2020-02-26)~/ckb-testing$ ckb-cli --versionckb-cli 0.27.1 (9d0bf90 2020-01-31)
我注意到在 testnet 页面上,ckb 和 ckb-cli 的示例版本是 2019 年 11 月的,并且有相同的版本号:
ckb 0.25.2 (dda4ed9 2019-11-17)ckb-cli 0.25.2 (6ca7bbb 2019-11-17)
使用测试网
现在我想要连接测试网并且验证我是否有能用的工具。
以下是最初的说明:
在包含 CKB 二进制文件的目录中创建 aggron.toml
用 ckb init --import-spec./aggron.toml --chain testnet 的指令来初始化 CKB 节点。
aggron.toml 的链接指向的是一个去年 12 月的 gist。我希望它还是有效的。
我创建了一个新的目录 ckb-testing 来装载我们测试网的数据,并将 aggron.toml 的事例包含在其中。
运行 ckb init:
~/ckb-testing$ ckb init --import-spec ./aggron.tml --chain testnet
输出了:
testing$ ckb init --import-spec ./aggron.toml --chain testnetWARN: mining feature is disabled because of lacking the block assembler config optionsInitialized CKB directory in /home/brian/ckb-testing/devnetcp ./aggron.toml specs/testnet.tomlcreate ckb.tomlcreate ckb-miner.toml
这看起来像是成功了,复制了 aggron.toml 到 specs/testnet.toml 中,并且创建 ckb.toml 和 ckb-miner.toml 。我在两个新的 toml 文件旁边摸索了一下。
ckb.toml 包含了下面几行:
[chain]# Choose the kind of chains to run, possible values:# - { file = "specs/dev.toml" }# - { bundled = "specs/testnet.toml" }# - { bundled = "specs/mainnet.toml" }spec = { file = "specs/testnet.toml" }
它表明有一个内置的 testnet 定义,这让我怀疑它是否与我们自己的 testnet 定义一致。让我们看看能不能找到内建的定义。
我用 fd 在 ckb repo 中搜索配置 :
~/ckb$ fd "testnet.toml"resource/specs/testnet.toml
果然没错!
这个内置的定义和开发者文档推荐的 aggron.toml 是一样的吗?
~/ckb$ diff ../ckb-testing/aggron.toml resource/specs/testnet.toml10c10< # run `cargo run cli hashes -b` to get the genesis hash---> # run `cargo run list-hashes -b` to get the genesis hash
是的,除了有一条过时的评论之外。
继续跟着测试网的文档看下去吧老铁们……
包含 aggron.toml 的 gist 中有另外一个说明:
请确认 log 输出中的创世哈希是0x184ac4658ed0c04a126551257990db132366cac22ab6270bbbc1f8c3220f302d
但它却没有说如何验证。创世哈希并不是由 ckb init 输出的。在测试网文档中的下一步是 ckb run ,我执行了。Windows 的防火墙需要请求我的许可,我同意了(我此刻正运行在 WSL 上)。我看到一大串的 log 输出,ckb 已经开始跑了:
2020-03-20 15:10:22.445 -06:00 main INFO sentry **Notice**: The ckb process will send stack trace to sentry on Rust panics. This is enabled by default before mainnet, which can be opted out by setting the option `dsn` to empty in the config file. The DSN is now https://48c6a88d92e246478e2d53b5917a887c@sentry.io/14227952020-03-20 15:10:23.354 -06:00 main INFO main Miner is disabled, edit ckb.toml to enable it2020-03-20 15:10:23.374 -06:00 main INFO ckb-db Initialize a new database2020-03-20 15:10:23.624 -06:00 main INFO ckb-db Init database version 201911271355212020-03-20 15:10:23.636 -06:00 main INFO ckb-chain Start: loading live cells ...2020-03-20 15:10:23.636 -06:00 main INFO ckb-chain Done: total 2 transactions.2020-03-20 15:10:23.653 -06:00 main INFO main ckb version: 0.29.0 (a6733e6 2020-02-26)2020-03-20 15:10:23.654 -06:00 main INFO main chain genesis hash: 0x184ac4658ed0c04a126551257990db132366cac22ab6270bbbc1f8c3220f302d2020-03-20 15:10:23.654 -06:00 main INFO ckb-network Generate random key2020-03-20 15:10:23.655 -06:00 main INFO ckb-network write random secret key to "/home/brian/ckb-testing/data/network/secret_key"2020-03-20 15:10:23.668 -06:00 main INFO ckb-network Listen on address: /ip4/0.0.0.0/tcp/8115/p2p/Qme9oaLbtaqF6JyZnZhrNPoW3dSPkzJSW1PGag3fKdEuaj2020-03-20 15:10:23.718 -06:00 NetworkRuntime-1 INFO ckb-network p2p service event: ListenStarted { address: "/ip4/0.0.0.0/tcp/8115" }2020-03-20 15:10:24.415 -06:00 NetworkRuntime-1 INFO ckb-relay RelayProtocol(1).connected peer=SessionId(1)2020-03-20 15:10:24.415 -06:00 NetworkRuntime-0 INFO ckb-sync SyncProtocol.connected peer=SessionId(1)2020-03-20 15:10:24.474 -06:00 NetworkRuntime-2 INFO ckb-sync Ignoring getheaders from peer=SessionId(1) because node is in initial block download2020-03-20 15:10:25.319 -06:00 NetworkRuntime-5 INFO ckb-relay RelayProtocol(1).connected peer=SessionId(2)2020-03-20 15:10:25.433 -06:00 NetworkRuntime-4 INFO ckb-relay RelayProtocol(1).connected peer=SessionId(3)2020-03-20 15:10:25.712 -06:00 NetworkRuntime-3 INFO ckb-relay RelayProtocol(1).connected peer=SessionId(4)2020-03-20 15:10:26.346 -06:00 NetworkRuntime-1 INFO ckb-sync SyncProtocol.connected peer=SessionId(2)2020-03-20 15:10:26.346 -06:00 NetworkRuntime-1 INFO ckb-sync Ignoring getheaders from peer=SessionId(2) because node is in initial block download2020-03-20 15:10:26.347 -06:00 NetworkRuntime-1 INFO ckb-sync SyncProtocol.connected peer=SessionId(3)2020-03-20 15:10:26.347 -06:00 NetworkRuntime-1 INFO ckb-sync Ignoring getheaders from peer=SessionId(3) because node is in initial block download2020-03-20 15:10:26.347 -06:00 NetworkRuntime-1 INFO ckb-sync SyncProtocol.connected peer=SessionId(4)2020-03-20 15:10:26.348 -06:00 NetworkRuntime-1 INFO ckb-sync Ignoring getheaders from peer=SessionId(4) because node is in initial block download2020-03-20 15:10:28.039 -06:00 ChainService INFO ckb-chain block: 1, hash: 0xcfbc1525e97bdb6e3202ff19270bddc1fcd6d8f1aee14c719064a8b989909f5d, epoch: 0(1/1000), total_diff: 0x1800060, txs: 1
这个日志说明测试网有正确的创世哈希,而且我们正在同步区块。
我目前正在 2704 这个区块高度。我想知道测试网上有多少个块,这样我就知道还需要等待多久。
这是测试网专用的区块浏览器吗?我 google 了「nervos block explorer」然后找到了:
https://explorer.nervos.org/
还有测试网的浏览器:
https://explorer.nervos.org/aggron/
测试网上有 567493 个区块,不过我并不会特别兴奋地等它下载完。
我的数据目录大小约为 7MB,所以我估计需要 (600_000/3000 * 7)= ~1.4GB的空间来进行测试网的开发,还是扛得住的。不过我真的不想等着同步,所以我们继续下个部分吧。
下一个文档是「Dev Chain」,希望它能告诉我们如何使用我们自己的链。
设置 dev chain
我暂时停止了正在同步测试网的 ckb ,将它的所有数据移动到 ckb-testing/testnet ,然后继续用 ckb 运行来同步测试网。
紧接着我创建了 ckb-testing/devnet 。根据 dev chain 的文档我执行了:
ckb init --chain dev
它输出了:
~/ckb-testing/devnet$ ckb init --chain devWARN: mining feature is disabled because of lacking the block assembler config optionsInitialized CKB directory in /home/brian/ckb-testing/devnetcreate specs/dev.tomlcreate ckb.tomlcreate ckb-miner.toml
dev chain 文档想要让我来定制 specs/dev.toml,并设置 genesis_epoch_length 到 1000。我看了一下我的 dev.toml 还有 genesis_epoch_length 已经到 1000 了。
它想让我定制 ckb-miner.toml 来设置空闲时间间隔(常被称为 value )到 500。我瞄了一眼 ckb-miner.toml 和 value 已经都到 500 了。这份文档似乎已经过时了。
译者注:文档中显示设定的值为 5000(截图为 2020/03/10 版)
在 dev chain 上挖矿
正如 ckb init 上所说,一个初始化的链尚未为挖矿进行配置。dev chain 文档的步骤 4 标题为「在 ckb.toml 中配置挖矿用的 block-assembler」,它提到:
我们使用 ckb-cli 生成 lock_arg 。需要 lock_arg 来配置挖矿功能,所以请将它备份。
我真希望它能解释到底 lock_arg 是什么,或者链接到更多的资讯。
紧接着我运行了 ckb-cli account new。
它要求我设置密码,我便设置成了「foo」,但 CLI 端有很长一段时间没有给我任何反馈。我真想知道它是不是坏了。
Aimee 想知道为什么我们需要一个账户。我猜它是连接到我们矿工的公钥,并且该账号会提供权限让矿工存放挖到的 CKB。
这部分文档是有缺陷的。
最后,账户的创建命令已经完成并且输出:
~/ckb-testing/devnet$ time ckb-cli account newYour new account is locked with a password. Please give a password. Do not forget this password.Password: Repeat password: address: mainnet: ckb1qyq9u782efpvk8m3q88gplxlzadpct5d7ypqythss9 testnet: ckt1qyq9u782efpvk8m3q88gplxlzadpct5d7ypqewf0uelock_arg: 0x5e78eaca42cb1f7101ce80fcdf175a1c2e8df102lock_hash: 0xe68befeae28e69dc658565be71bc7146fd33a9a4bea3f7edba8de8c8c46865ff
呃,看了一下输出,还需要做一些工作。你只能看到标签(地址、主网也是在我的终端机中看不到的深蓝色)。
我花了 168 秒来运行二进制文件的调试以及在后台同步测试网。
为了实验,我停止了对测试网的同步,在调试版本中再次运行 ckb-cli account new;然后在 release 模式下重建 ckb 和 ckb-cli。
测试网重置了!
2020-03-24 21:50:22.644 -06:00 NetworkRuntime-3 INFO ckb-network Ban peer PeerId(QmT6DFfm18wtbJz3y4aPNn3ac86N4d4p4xtfQRRPf73frC) for 300 seconds, reason: The nodes are not on the same network
继续 dev chain 的设置
# Set the lock script to protect mined CKB.## CKB uses CS architecture for miner. Miner process (ckb miner) gets block# template from the Node process (ckb run) via RPC. Thus the lock script is# configured in ckb.toml instead of ckb-miner.toml, and the config takes effect# after restarting Node process.## The `code_hash` identifies different cryptography algorithm. Read the manual# of the lock script provider about how to generate this config.## CKB provides an secp256k1 implementation, it requires a hash on the# compressed public key. The hash algorithm is blake2b, with personal# "ckb-default-hash". The first 160 bits (20 bytes) are used as the only arg.## You can use any tool you trust to generate a Bitcoin private key and public# key pair, which can be used in CKB as well. CKB CLI provides the function for# you to convert the public key into block assembler configuration parameters.## Here is an example using ckb-cli to generate an account, this command will# print the block assembler args(lock_arg) to screen:## ckb-cli account new## If you already have a raw secp256k1 private key, you can get the lock_arg by:## ckb-cli util key-info --privkey-path## The command `ckb init` also accepts options to generate the block assembler# directly. See `ckb init --help` for details.## ckb init## secp256k1_blake160_sighash_all example:# [block_assembler]# code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8"# args = "ckb cli blake160"# hash_type = "type"# message = "A 0x-prefixed hex string"
好吧,这里还是有好多没解释清楚的地方:
# [block_assembler]# code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8"# args = "ckb cli blake160"# hash_type = "type"# message = "A 0x-prefixed hex string"
缺失
在测试网上发送 CKB
CKB> account newYour new account is locked with a password. Please give a password. Do not forget this password.Password: Repeat password: address: mainnet: ckb1qyq2p6jgd8pnqlngy4cf4h7c76p383rug9sqw9e2hp testnet: ckt1qyq2p6jgd8pnqlngy4cf4h7c76p383rug9sqnq84malock_arg: 0xa0ea4869c3307e6825709adfd8f68313c47c4160lock_hash: 0xb686ca47423942cd64f4d091829450ad3b968b485d922b773a4672616a084c0c
CKB> wallet get-capacity --lock-arg 0xa0ea4869c3307e6825709adfd8f68313c47c4160total: 0.0 (CKB)
CKB> wallet get-live-cells --address=ckt1qyq2p6jgd8pnqlngy4cf4h7c76p383rug9sqnq84macurrent_capacity: 5000.0 (CKB)current_count: 1live_cells: - capacity: 5000.0 (CKB) data_bytes: 0 index: output_index: 0 tx_index: 1 lock_hash: 0xb686ca47423942cd64f4d091829450ad3b968b485d922b773a4672616a084c0c mature: true number: 55611 tx_hash: 0x1a8a1650dcf8bc21a210a970073b6d1a47eff13afdd649e5cb3ecc3d56c06083 tx_index: 0 type_hashes: ~total_capacity: 5000.0 (CKB)total_count: 1
CKB> wallet transfer --capacity 1000 --from-account 0x2af2ea2efbffce44f51cd4d7731507fdbbd63629 --to-address ckt1qyq2p6jgd8pnqlngy4cf4h7c76p383rug9sqnq84ma --tx-fee 1PassworD:0xc0a6973ac921cea95d27fa9e8a30ae6fca18de2404f768e3a077dd1e5f345ec0
CKB> wallet get-capacity --address=ckt1qyq2p6jgd8pnqlngy4cf4h7c76p383rug9sqnq84matotal: 6000.0 (CKB)CKB> wallet get-live-cells --address=ckt1qyq2p6jgd8pnqlngy4cf4h7c76p383rug9sqnq84macurrent_capacity: 6000.0 (CKB)current_count: 2live_cells: - capacity: 5000.0 (CKB) data_bytes: 0 index: output_index: 0 tx_index: 1 lock_hash: 0xb686ca47423942cd64f4d091829450ad3b968b485d922b773a4672616a084c0c mature: true number: 55611 tx_hash: 0x1a8a1650dcf8bc21a210a970073b6d1a47eff13afdd649e5cb3ecc3d56c06083 tx_index: 0 type_hashes: ~ - capacity: 1000.0 (CKB) data_bytes: 0 index: output_index: 0 tx_index: 1 lock_hash: 0xb686ca47423942cd64f4d091829450ad3b968b485d922b773a4672616a084c0c mature: true
附录:CKB 文档
https://docs.nervos.org
https://github.com/nervosnetwork/ckb/blob/develop/docs/get-ckb.md
https://github.com/nervosnetwork/ckb/tree/develop/docs
RFC: Simple UDT Draft Spec
RFC: anyone-can-pay lock
https://gist.github.com/WilfredTA/bb1d2a80c420f0910d40ca881c2bd5d4
https://github.com/nervosnetwork/ckb-cli/blob/develop/README.md
https://github.com/nervosnetwork/ckb/wiki/Chains
https://github.com/nervosnetwork/ckb/wiki
Introducing Godwoken - A missing piece of the cell model
SECBIT Labs - zkp-toolkit-ckb - a Zero-Knowledge Proof toolkit for CKB
https://github.com/nervosnetwork/wasm-secp256k1-test
Summa - Bitcoin SPV Utils
https://github.com/nervosnetwork/ckb-cli/wiki/Sub-Commands
声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。