创建自己的Ergo钱包:使用ErgoTool管理Ergo币
2019年12月31日

介绍
ErgoTool 是一个命令行界面 (CLI) 用于
Ergo区块链。您可以在不运行自己的Ergo节点的情况下使用ErgoTool。尽管运行节点是与Ergo区块链网络通信的最安全方式,但ErgoTool旨在提供更多基础工具供您使用。当然,您仍然可以与自己运行的节点一起使用它。
在这篇文章中,我们将通过简单的步骤生成助记词,创建本地秘密存储,并使用它在地址之间发送ERGs,所有这些都借助于ErgoTool命令。
开始使用
首先,我们需要按照安装说明 从源代码在系统上安装ErgoTool。在我们克隆ErgoTool的目录中,有一个ergo-tool.sh脚本,我们将使用它来运行命令。运行以下命令以检查ErgoTool是否正确安装。
$ ./ergo-tool.sh help
命令名称未指定(运行不带参数的ergo-tool以列出命令)
命令名称: help
用法语法: ergo-tool help <commandName>
描述: 打印命令的使用帮助
文档页面: https://aslesarenko.github.io/ergo-tool/api/org/ergoplatform/appkit/ergotool/HelpCmd.html
让我们看看我们在这里得到了什么。ErgoTool输出了错误消息,包含有关help命令的信息。这是ErgoTool在指定已知命令但使用不当时的典型输出。从消息中我们可以了解到,help命令要求我们指定额外的<commandName>参数。此外,每个命令都有一个API文档页面,包含有关命令执行的所有详细信息,因此其URL在此处显示。
创建新的助记词
助记词是一串随机字符,用于根据分层确定性钱包规范生成主密钥。为了方便,使用随机的英语单词序列,但这并不是必需的。运行以下命令以生成新的助记词:
$ ./ergo-tool.sh mnemonic
bird harbor wheat innocent business disease busy quick yellow trust time oil enter situate moon
将其写在纸上并保存在安全和秘密的地方。
作为额外的安全措施,您可以创建一个任意的助记密码。
在某种意义上,它可以作为助记词中的额外非词汇单词。
助记密码是可选的,用于额外的安全性。
如果您决定使用助记密码,您还应该将其写下并保存在一个秘密的地方,可能与助记词不同。
重要的是,恢复秘密密钥需要助记词和助记密码,如果您丢失其中任何一个,您将无法再次生成主密钥。
接下来,让我们使用生成的助记词创建一个带有主秘密密钥的存储。
创建新的加密存储
为了更好的安全性,ErgoTool在执行交易签名时不要求助记词或密码。相反,签署支出交易需要来自加密存储的秘密密钥。我们可以使用createStorage命令生成一个秘密密钥并将其存储在加密存储中。
$ ./ergo-tool.sh help createStorage
命令名称: createStorage
用法语法: ergo-tool createStorage [<storageDir>="storage"] [<storageFileName>="secret.json"]
描述: 为用户输入的助记词创建一个加密存储文件
文档页面: https://aslesarenko.github.io/ergo-tool/api/org/ergoplatform/appkit/ergotool/CreateStorageCmd.html
$ ./ergo-tool.sh createStorage
输入助记词> bird harbor wheat innocent business disease busy quick yellow trust time oil enter situate moon
助记密码>
重复助记密码>
存储密码>
重复存储密码>
存储文件:storage/secret.json
从(助记词,助记密码)对生成主秘密密钥,并加密保存在storage/secret.json文件中。助记词本身不存储在文件中,即使您知道密码,也无法从文件中恢复它。
请注意输入正确的助记密码,即您之前选择并保存的那个。
由于助记密码是可选的,您可以通过按回车键将其留空。
如果您忘记存储密码(即加密密码),您将无法再使用该存储文件,但是,您可以始终从(助记词,助记密码)对恢复您的秘密密钥,从而创建一个带有新密码的新存储文件。
将您的存储文件和存储密码保密,任何获得您存储文件和存储密码的人都将能够解密它并访问秘密密钥。
从存储中提取数据
秘密存储包含主秘密密钥,因此可以用于计算与该秘密密钥对应的公钥和支付到公钥地址。extractStorage命令正是这样做的。
$ ./ergo-tool.sh help extractStorage
命令名称: extractStorage
用法语法: ergo-tool extractStorage <storage file> address|masterKey|publicKey|secretKey mainnet|testnet
描述: 读取文件,使用密码解锁并从给定存储文件中提取请求的属性。
文档页面: https://aslesarenko.github.io/ergo-tool/api/org/ergoplatform/appkit/ergotool/ExtractStorageCmd.html
$ ./ergo-tool.sh extractStorage storage/secret.json address mainnet
存储密码>
9iHiSAg3ko2ZGxR2vhc1Aem3tShqfzEPDAF7XK5cdtbZ3Ut2CCf
在这里,命令将秘密密钥转换为相应的公钥,然后在主网创建支付到公钥地址。
同样,我们可以从存储中获取公钥、私钥和其他数据。
$ ./ergo-tool.sh extractStorage storage/secret.json secretKey mainnet
存储密码>
55dfde63c9b6b4f47683592e85ee997ba2e93507f38ba3f9c82933bcfbc677ca
$ ./ergo-tool.sh extractStorage storage/secret.json publicKey mainnet
存储密码>
03f07aecb145a85920bf6e9be80efe5f1cd1a165b45ad3aa8e5c4ca3ba50856bb8
列出未花费的盒子
ErgoTool有一个特殊命令,用于列出给定地址的所有可用(即未花费)盒子。
$ ./ergo-tool.sh listAddressBoxes 9f4QF8AD1nQ3nJahQVkMj8hFSVVzVom77b52JU7EW71Zexg6N8v
BoxId NanoERGs
4840cb6facc20b765085db0ad24768ed0c5e7afd413e8e58e597c33a993f8119 4987000000
如果我们指定--print-json选项,则ErgoTool将以json格式输出所有盒子。
$ ./ergo-tool.sh listAddressBoxes --print-json 9f4QF8AD1nQ3nJahQVkMj8hFSVVzVom77b52JU7EW71Zexg6N8v
[{"boxId":"4840cb6facc20b765085db0ad24768ed0c5e7afd413e8e58e597c33a993f8119","value":4987000000,"ergoTree":"0008cd02472963123ce32c057907c7a7268bc09f45d9ca57819d3327b9e7497d7b1cc347","creationHeight":125646,"assets":[],"additionalRegisters":{},"transactionId":"820c688f4b9d709924ba0186ee930a7df374d8852920bc769fc1f1d0b313e5ab","index":2}]
转移币
现在,秘密密钥安全地存储在加密存储文件中,我们可以使用ErgoTool将币从我们的地址转移到其他接收地址。执行此操作的命令是send。
./ergo-tool.sh help send
命令名称: send
用法语法: ergo-tool send <storageFile> <recipientAddr> <amountToSend>
描述: 使用给定的<storageFile>签署交易,将给定的<amountToSend>发送到给定的<recipientAddr>(请求存储密码)
文档页面: https://aslesarenko.github.io/ergo-tool/api/org/ergoplatform/appkit/ergotool/SendCmd.html
存储文件是访问秘密密钥和生成签名所必需的。ErgoTool将请求存储密码以解锁和解密文件内容。命令send支持--dry-run选项,该选项强制ErgoTool创建签名交易,但不将其发送到区块链,而是将交易打印在控制台上。
$ ./ergo-tool.sh send --dry-run storage/E1.json 9hHDQb26AjnJUXxcqriqY1mnhpLuUeC81C4pggtK7tupr92Ea1K 5000000
存储密码>
创建证明者... 好
从地址9f4QF8AD1nQ3nJahQVkMj8hFSVVzVom77b52JU7EW71Zexg6N8v加载未花费的盒子... 好
签署交易... 好
Tx: {
"id": "2633733a1d81b8fc747d984bdc36fac42cb52118b5057375b081b4c543c62b0e",
"inputs": [
{
"boxId": "4840cb6facc20b765085db0ad24768ed0c5e7afd413e8e58e597c33a993f8119",
"spendingProof": {
"proofBytes": "060e7c99c9c9cecf89ec5c3e7b692075e0b3415318f8064c64f7f01401ac29c6637b44535151e51d43d4cd25e05ad459dbe33718a99a22dd",
"extension": {}
}
}
],
"dataInputs": [],
"outputs": [
{
"boxId": "4eaed414ae763158126859bbf912fa9ffb9ea67ac13d81d473b1c81ec65b06fd",
"value": 5000000,
"ergoTree": "ErgoTree(0,WrappedArray(),Right(ConstantNode(SigmaProp(ProveDlog(ECPoint(6ba5cf,8ae5ac,...))),SSigmaProp)),80,[B@1117fff48)",
"creationHeight": 130508,
"assets": [],
"additionalRegisters": {},
"transactionId": "2633733a1d81b8fc747d984bdc36fac42cb52118b5057375b081b4c543c62b0e",
"index": 0
},
{
"boxId": "059b426fe2aaef10b6a9a618f0c5b4e97d4dd9931328bf4f52bcf92b0943a42c",
"value": 1000000,
"ergoTree": "ErgoTree(16,WrappedArray(IntConstant(0), IntConstant(0), ConstantNode(Coll(16,2,4,-96,11,8,-51,2,121,-66,102,126,-7,-36,-69,-84,85,-96,98,-107,-50,-121,11,7,2,-101,-4,-37,45,-50,40,-39,89,-14,-127,91,22,-8,23,-104,-22,2,-47,-110,-93,-102,-116,-57,-89,1,115,0,115,1),Coll[SByte$]), ConstantNode(Coll(1),Coll[SInt$]), IntConstant(1)),Right(BoolToSigmaProp(AND(ConcreteCollection(WrappedArray(EQ(Height$(163),SelectField(ExtractCreationInfo(ByIndex(Outputs$(165),ConstantPlaceholder(0,SInt$),None)),1)), EQ(ExtractScriptBytes(ByIndex(Outputs$(165),ConstantPlaceholder(1,SInt$),None)),SubstConstants(ConstantPlaceholder(2,Coll[SByte$]),ConstantPlaceholder(3,Coll[SInt$]),ConcreteCollection(WrappedArray(CreateProveDlog(DecodePoint(MinerPubkey$(172)))),SSigmaProp))), EQ(SizeOf(Outputs$(165)),ConstantPlaceholder(4,SInt$))),SBoolean)))),4836,[B@111805c40)",
"creationHeight": 130508,
"assets": [],
"additionalRegisters": {},
"transactionId": "2633733a1d81b8fc747d984bdc36fac42cb52118b5057375b081b4c543c62b0e",
"index": 1
},
{
"boxId": "0638ddb0fe6a8cc6ca4f981f71777f4a6e8aad72d57fdf945b24e0ef4ca714e1",
"value": 4981000000,
"ergoTree": "ErgoTree(0,WrappedArray(),Right(ConstantNode(SigmaProp(ProveDlog(ECPoint(472963,7c85fd,...))),SSigmaProp)),80,[B@111816258)",
"creationHeight": 130508,
"assets": [],
"additionalRegisters": {},
"transactionId": "2633733a1d81b8fc747d984bdc36fac42cb52118b5057375b081b4c543c62b0e",
"index": 2
}
]
}
请注意,"ergoTree"脚本被反序列化并打印为抽象语法树。此打印格式可以通过附加选项进行调节,以便脚本可以以人类可读的ErgoScript形式打印。(尚未实现,但在路线图上。)
如果我们排除--dry-run选项,交易将被发送并包含在区块链中。
$ ./ergo-tool.sh send storage/E1.json 9hHDQb26AjnJUXxcqriqY1mnhpLuUeC81C4pggtK7tupr92Ea1K 5000000
存储密码>
创建证明者... 好
从地址9f4QF8AD1nQ3nJahQVkMj8hFSVVzVom77b52JU7EW71Zexg6N8v加载未花费的盒子... 好
签署交易... 好
发送交易... 好
服务器返回交易ID: "c5710af17f5124a232a5ef731fdf94a493025334c2a7d5a79e9923210972b962"
新创建的交易将被广播到整个区块链,矿工开始将其包含在新块中。一旦包含我们交易的新块被挖掘并被网络接受,我们的转账就会被确认,我们可以在Explorer中查看。
我们还可以列出接收地址的盒子,并在其他盒子中看到我们创建的币(直到它被接收者花费)
$ ./ergo-tool.sh listAddressBoxes 9hHDQb26AjnJUXxcqriqY1mnhpLuUeC81C4pggtK7tupr92Ea1K
BoxId NanoERGs
252c5ce38fc367001ea48fa6813e6252ebc169288d9b5392c572edb55380b3cd 5000000
6df9dbf08b4859b7e280afbd0822dcf20dba5bf8e3e33b78fe278df6597276f1 2000000
d47f958b201dc7162f641f7eb055e9fa7a9cb65cc24d4447a10f86675fc58328 1000000
e050a3af38241ce444c34eb25c0ab880674fc23a0e63632633ae14f547141c37 1000000
b50ed8c2953fd33b52af816c4caa63ec5b6d236a262a5a192534695c3478da78 1000000
26d6e08027e005270b38e5c5f4a73ffdb6d65a3289efb51ac37f98ad395d887c 10000000000
安全注意事项
ErgoTool的创建考虑了安全性,并尽力保护敏感信息的使用,如助记词(从不持久存储)、密码(从不在屏幕上显示)等。此外,秘密密钥从不以未加密的形式存储在本地磁盘上,当然也从不发送到任何地方。
结论
ErgoTool旨在看起来和感觉像一个典型的CLI实用程序:
- 易于使用,快速从命令行运行
- 可以通过shell脚本进行脚本化
- 具有内置的使用帮助
同时,ErgoTool设计为易于扩展:
- 用高级语言Scala实现
- 重用在Ergo网络客户端中使用的核心库
- 开源并且完全文档化
最后一点尤其重要,因为许多新命令可以轻松添加到ErgoTool,得益于其架构。如果您需要特定的功能或命令,请提交问题或甚至PR。
ErgoTool的可扩展性是下一个计划的博客文章的主题,敬请关注!
参考文献
Share post




















