parity是一个彻头彻尾的以太坊节点,其特点包括正确性/可验证性、模块化、低内存占用和高性能。它是用Rust 编程语言编写的,Rust是一种混合式的、面向对象的函数式语言的语言,注重效率,由Parity Technologies公司开发。在写本书时,parity的最新版本是1.7.0,我们将使用这个版本学习创建联盟区块链需要的内容。如要深入学习 parity,请参考官方文档。
parity的功能比go-ethereum多,例如有web3 DApp浏览器和更先进的账户管理功能等。不过parity的特别之处在于它既支持PoA,也支持PoW。parity目前支持Aura和 Tendermint PoA协议,未来还可能支持更多的PoA协议。目前,parity推荐使用Aura,而不推荐Tendermint,因为Tendermint仍处于开发 阶段。
对于获得许可权限的区块链来说,Aura是一个比PoW好得多的选择,因为它的区块时间更好,且在私有网络中提供了更好的安全性。
9.3.1 Aura的工作原理
让我们从一定高度看看Aura是如何工作的。Aura要求每个节点中都指明同样的验证器列表,这是参与共识的账户地址的列表。一个节点可能是验证节点,也可能不是验证节点,即使是验证节点,也需要有这个列表,这样它自己才能达成共识。
这个列表可以在创世文件中作为静态列表提供(如果验证器的列表永远保持不变),或者在智能合约中提供(这样它可以被动态更新且让每一个节点都知道它)。在智能合约中,对于谁可以添加新的验证器,可以设置不同的策略。
区块时间可以在创世文件中配置。用户可以自己决定区块时间。在私有网络中,低至3s的区块时间运行良好。在Aura 中,每过3s就选择验证器中的一个,该验证器负责创建、验证、签署和广播区块。用户不需要深入理解实际的选择算法,因为这不会影响DApp开发。这是计算 下一个验证器的公式:(UNIX_TIMESTAMP/BLOCK_TIME%NUMBER_OF_TOTAL_VALIDATORS)。选择算法很智 能,它给所有人同等的机会。当其他节点接收一个区块时,它们要检查区块是否来自下一个合法的验证器;如果不是,就拒绝它。与PoW不同,验证器创建区块的 时候,不能得到以太币回报。在Aura中,由用户决定在没有交易时是否生成空区块。
如果由于一些原因,下一个验证器节点创建和广播下一个区块失败了,情况会如何?让我们看一个例子:假设A是下一个区块 (即第5个区块)的验证器,B是第6个区块的验证器。假设区块时间是5s。如果A广播区块失败,则5s之后轮到B广播区块。所以事实上不会发生什么要紧 事,区块时间戳将揭示这些细节。
在PoW中两个矿工同时挖矿,最后网络是否有可能产生多个不同的区块链?是的,很多情况下都可能导致这样的结果。让我 们看个例子来理解一种可能发生的情况以及网络自动解决冲突的方法。假设共有5个验证器:A、B、C、D和E。区块时间是5s。假设A首先被选中并广播一个 区块,但是由于一些原因区块没有到达D和E,所以它们会认为A没有广播区块。现在假设选择算法选择B来生成下一个区块,则B将在A区块之上生成下一个区块 并广播给所有的节点。D和E将拒绝它,因为前一个区块哈希不匹配。由此,D和E将形成一个不同的链,而A、B和C将形成一个不同的链。A、B和C将拒绝来 自D和E的区块,而D和E将拒绝来自A、B和C的区块。这个问题可以这样解决,假设定义来自A、B和C的区块比来自D和E的区块更准确,因此D和E将用 A、B和C版本的区块链替换自己的区块链。两个版本的区块链有不同的准确分,第一个区块链的分数高于第二个。当B广播它的区块时,它还将提供其区块链评 分,因为其分数高,D和E就用B的区块链替换自己的区块链。这就是冲突的解决方法。区块链的分数使用 (U128_max*BLOCK_NUMBER_OF_LATEST_BLOCK- (UNIX_TIMESTAMP_OF_LATEST_BLOCK/BLOCK_TIME))计算。首先用长度评分(区块越多越好),对于有同样长度的 链,选择最后一个区块比较旧的链。
如果更深入地学习Aura,参见https://github.com/paritytech/parity/wiki/Aura 。
9.3.2 运行parity
parity需要安装Rust版本1.16.0才能创建。推荐通过rustup安装Rust。
1.安装rust
如果还没有rustup,可以按照如下方式进行安装。
(1)Linux
在以Linux为基础的操作系统上,运行如下命令:
parity还要求安装gcc、g++、libssl-dev/openssl、libudev-dev和pkg-config包。
(2)OS X
在OS X上,运行如下命令:
parity还要求安装clang。clang来自Xcode命令行工具,或者可以用Homebrew安装。
(3)Windows
确保安装可使用C++的Visual Studio 2015。下一步,从https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustupinit.exe 下载并运行rustup安装程序,启动VS2015 x64 Native Tools Command Prompt,并使用下面的命令安装和建立msvc工具链:
2.下载、安装和运行parity
在操作系统上安装好rust之后,可以运行如下简单的在线命令安装parity:
检测是否已经安装了parity,运行如下命令:
如果parity安装成功,就会看到一个子命令和选项列表。
9.3.3 创建私有网络
现在是时候建立联盟区块链了。使用Aura作为共识机制,创建两个彼此连接的验证节点。我们将在同一台计算机上建立这两个节点。
1.创建账户
首先,打开两个shell窗口。第一个针对第一个验证器,第二个针对第二个验证器。第一个节点包含两个账户,第二个节点包含一个账户。第一个节点的第二个账户将被赋予一些初始以太币,这样网络将拥有一些以太币。
在第一个shell窗口中,运行如下命令两次:
两次都会要求输入密码。现阶段,在两个账户中输入相同的密码。
在第二个shell中窗口,运行如下命令一次:
和刚才一样,输入密码。
2.创建规范文件
每个网络的节点都分享一个通用规范文件(specification file)。该文件告诉节点关于创世区块、谁是验证器等信息。我们将创建一个智能合约,其中包含验证器列表。有两种类型的验证器合约:non- reporting合约和reporting合约。我们只需要提供一个。
这两种验证器合约的区别是:non-reporting合约只返回一个验证器列表;而reporting合约可以对善意(善意行为可能仅仅是不从一个给定的验证器接收区块)和恶意行为(恶意行为可能是在同一步骤释放两个不同的区块)采取行动。
non-reporting合约至少应该有如下界面:
在每一个区块上调用getValidators函数,以决定当前列表。转换规则是由实现该方法的合约决定的。
reporting合约至少应该有如下界面:
当有善意或者恶意行为时,共识机器分别调用reportBenign和reportMalicious函数。
创建一个reporting合约的基本示例如下:
该代码无须解释说明。确保在验证器中,数组用验证器1的第一个地址和验证器2的第一个地址代替这些地址,因为我们将使用那些地址进行验证。现在编译上述合约。
现在创建规范文件。创建一个叫作spec.json的文件,放入下面的代码:
上述程序代码的工作原理如下:
·engine属性用于设置共识协议和协议具体参数。这里的engine是authority-Round,也就是 aura。gasLimitBoundDivisor决定gas上限调整,并有通常的以太坊值。在验证器属性中,有一个contract属性,即 reporting合约的地址。stepDuration是以秒为单位的区块时间。
·在params属性中,只有网络ID才是关键;在所有的链中,其他属性都是标准的。
·genesis属性对于authorityRound共识有一些标准数值。
·accounts属性用于列出网络中存在的最初账户和合约。前四个是标准以太坊内置合约,使用Solidity合约 编写语言应当包括这些。第五个是reporting合约。确保把字节码替换成constructor参数中的字节码。最后一个账户是在验证器1 shell生成的第二个账户。它的用途是向网络提供以太币。用户可以用自己的地址替换它。
在继续下一步操作之前,创建另一个文件node.pwds,在其中放入所创建的账户的密码。该文件将被验证器用来解锁账户,签署区块。
3.启动节点
现在已经具备各种条件启动验证节点了。在第一个shell窗口中,运行如下命令以启动第一个验证节点:
上述命令的工作原理如下:
·--chain用于指定规范文件的路径。
·-d用于指定数据目录。
·--force-sealing用于确保即使没有交易也产生区块。
·--engine-signer用于指定节点签署区块时使用的地址,即验证器的地址。如果可能有恶意机构,则推荐用--force-sealing,这将保证正确的链是最长的。确保把地址改为生成的那个地址,即在这个shell窗口生成的地址。
·--password用于指定密码文件。
在第二个shell窗口中,运行如下命令以启动第二个验证节点:
确保把地址修改为生成的那个地址,即在这个shell窗口生成的地址。
4.连接节点
最后需要连接两个节点。打开一个新的shell窗口,运行如下命令,URL会连接到第二个节点:
将得到类似这样的输出:
运行如下命令,把URL中的编码URL和IP地址修改为127.0.0.1:
得到如下输出:
该节点应当表示操作台中的0/1/25 peers,这意味着它们彼此没有连接。示意图如下:
9.3.4 许可和隐私
我们已经看到了parity是如何解决速度和安全问题的。parity目前并不提供专门的许可和隐私功能。让我们看看如何在parity中实现许可和隐私:
1)许可 。parity网络可以配置每个节点的服务端,只允许特定的IP地址建立连接,由此实现许可,即决定谁能加入、谁不能加入。即使IP地址没有被拦截,为了 连接到网络中的节点,新的节点也将需要一个enode地址,且这个地址是猜不到的。所以默认parity有基本保护。但是没有强制实施保护。网络中的每一 个节点需要在其终端关注此事。可以通过智能合约进行类似许可,即决定谁能创建区块以及谁不能创建区块。目前还不能设定哪种交易节点可以发送。
2)身 份隐私 。通过允许所有权查询,有办法实现身份隐私。在设定所有权时,所有者需要指定一个非确定性的、不对称的加密公钥。当它想通过所有权查询时,将提供一个加密的普通文本,合约对其解码,并查看账户是否是所有者。合约应当确保不会检查同样的加密数据两次。
3)数据隐私 。如果只是使用区块链存储数据,则可以使用对称的加密方式加密数据并存储,还可以与和人共享密钥。但是不能在加密数据上进行操作,如果需要在输入数据上进行操作,同时还想要保密,则各方需要建立一个完全不同的区块链网络。
来源:我是码农,转载请保留出处和链接!
本文链接:http://www.54manong.com/?id=524