在前一节中,我们学习了如何使用 basecoin 启动区块链和 basecli 来发送交易,同时研究了 Account
和 SendTx
这两种基本类型。本节,我们将演示如何扩展 SendTx
以便让它支持另外一种交易类型:AppTx
,这样就可以发送数据到一个自定义的插件 plugin。这里,我们来探索一个简单的 plugin:Counter
。
Example Plugin
basecoin 的设计使得实现一个用户自定义插件变得十分简单,Counter
插件是和 basecoin 区块链打包在一起的,因此,如果你已经安装了 baseocin,并且运行了 make install
,你应该可以直接运行 Counter
区块链节点和它的客户端 countercli
,它和我们之前的 basecli
用法十分相似。
除了 --name
和 --amount
是必选参数,Counter
交易由其他两个参数确定:boolean
类型的 valid
,和 countfee
表示某种代币类型和数量。只有当 valid
为 true
且 amount
数量大于 counterfee
时,该笔交易才是有效的。
跟之前 basecoin 区块链一样,类似的,counter 区块链也可以这样初始化:
1 | # WARNING: this wipes out data - but counter is only for demos... |
counter 的配置文件默认存放在 ~/.counter
目录,打开另一个命令行窗口, 初始化 countercli
并用 tx
的子命令 send
发送交易:
1 | countercli init --node=tcp://localhost:46657 --genesis=$HOME/.counter/genesis.json |
Counter
的 tx 还有另外一个子命令 counter
,它会为这个 plugin 构造一个特殊的 AppTx:
1 | countercli tx counter --name cool --amount=1mycoin --sequence=2 |
第一笔交易不会被区块链接受,因为它没有指定 valid 参数,第二笔顺利发送,接下来我们可以查询这个 plugin:
1 | countercli query counter |
可以看到,我们这个自定义插件已经可以跑通,你应该看到 Counter
值为 1 代表当前 counter 的有效交易数量,如果再发送一笔交易:
1 | countercli tx counter --name cool --amount=2mycoin --sequence=4 --valid --countfee=2mycoin |
再次查询,我们将看到 Counter
值会变为 2,这一次,我们指定了 countfee=2mycoin
,它没有超出 --amount=2mycoin
,因此,可以通过 counter 区块链的合法性验证。
记住,和 basecli 一样,每次查询, countercli 都会验证区块链返回的 proof,保证返回结果是最新且正确的。
AppTx
在实现我们自己的 plugin 之前,有必要先探究下 AppTx
和 basecoin 的 plugin 系统。
AppTx
和 SendTx
相似,不同之处在于,SendTx
是从 inputs 发送交易到 outputs,而 AppTx
是从一个 input 发送交易到一个 plugin,当然,也可以附加其他数据 Data
。
1 | type AppTx struct { |
通过 plugin 的方式,AppTx
可以使 Basecoin 扩展为能够处理除了转账之外的其他交易。Name
字段代表某个处理特殊交易的 plugin 名字,Data
代表 plugin 要处理的数据。
Plugins
一个 plugin,简单来说,它实现了 Plugin 接口中定义的方法:
1 | type Plugin interface { |
关键在于 RunTx
方法,AppTx 中的 Data 会赋值给 txBytes,Input 则用来填充 CallContext
。
注意到 RunTx
还接收一个 KVStore
类型参数 store
,它抽象化了底层默克尔树对 account 数据的操作,这样 plugin 可以直接更新 Basecoin 节点里面的 account 信息,也可以存储其它信息用来来反馈区块链应用的最新状态。
通过 plugin 的方式,基于 Basecoin 的区块链应用可以得到很大扩展,甚至,可以实现类似于以太坊虚拟机那样的插件。这里 有些别人已经实现好的 plugin 例子。
Conclusion
本节我们演示了如何创建一个 plugin 来扩展现有 Basecoin 实现发送用户自定义交易到区块链,下一节,我们将介绍一个用于区块链跨链通信 IBC(Inter Blockchain Communication
) 的插件。