转载请注明出处:www.huamo.online
字节杭州 求贤若渴:
end-to-end验证提供了一个示例fabric网络,包括2个组织,每个组织包含2个peer节点,以及1个基于Kafka的排序服务。
这个验证用到了2个基础工具,用来创建一个带有数字签名验证的和访问控制的实用交易网络:
每一个工具用到一个yaml配置文件,在里面我们指定了网络的拓扑结构(cryptogen需用到),以及用于各种配置操作的证书的位置(configtxgen需用到)。当这些工具都已被成功运行后,我们就可以发布这个网络了。工具的更多细节和网络的架构在下文描述。现在,让我们开始吧…
前置操作【Prerequisites】
编译二进制包
先生成特定平台的,
cryptogen和configtxgen二进制包1
2$ cd $GOPATH/src/github.com/hyperledger/fabric
$ make release该命令将会在
fabric/release文件夹中输出特定平台的二进制包。接下来,编译
Fabric镜像。这一般需要5 ~ 10分钟,所以耐心等候【国内需要更大的耐心…】:1
2$ cd $GOPATH/src/github.com/hyperledger/fabric
$ make docker
在终端运行命令docker images,如果这些镜像都被成功编译,你应该能够看到类似于下面的输出:
1 | REPOSITORY TAG IMAGE ID CREATED SIZE |
如果在编译过程中失败了,可以修复错误,然后执行
make clean,最后再make docker。
Cryptogen工具
我们将使用cryptogen工具来为我们的各种网络实体生成加密内容(x509证书)。证书基于PKI标准实现,通过回溯到一个共同的信任锚点来实现验证。
它是如何工作的?
Cryptogen使用一个文件 - crypto-config.yaml - 包含了网络的拓扑结构,并且允许我们为组织以及组织中的各种组件,生成一系列的证书。每个组织被提供了一个唯一的根证书(ca-cert),将指定的组件(peers和orderers)绑定到了该组织上。Fabric中的交易和通讯都由一个实体的私钥(keystore)进行签名,然后由相应的公钥(signcerts)进行验证。在这个yaml文件中你会看到一个count变量。我们使用这个值指定了每个组织的peer数量;这里我们指定了2个peer。这个模板的其它部分都是非常浅显易懂的。
在我们运行了工具之后,证书会被放在crypto-config目录下。
Configtxgen工具
configtxgen工具用来生成4种文件:orderer节点的启动块(bootstrap block),fabric channel的配置交易(channel configuration transaction),以及2个锚peer交易(anchor peer transactions)– 一个Peer组织一个。
orderer block是排序服务的创世块,channel交易文件会在channel创建时广播给orderer节点。而锚peer节点交易,就像名字表示的那样,在这个channel上为每个组织指定一个锚peer节点。
它是如何工作的?
Configtxgen读取一个文件 - configtx.yaml - 文件中包含了样例网络的定义。有3个成员 - 一个Orderer组织(OrdererOrg),和2个Peer组织(Org1和Org2)每个都管理和维护2个peer节点。这个文件也指定了一个联盟 - SampleConsortium - 包含我们的2个Peer组织的联盟。对文件顶部的Profiles区域中内容多留意下。你会发现我们有2个不同的顶级属性。一个是给orderer创世块用的 - TwoOrgsOrdererGenesis - 另一个是给channel用的 - TwoOrgsChannel。这些顶级属性是很重要的,当我们创建配置文件时我们会把它们作为参数传入进去。这个yaml文件还包含了2个值得注意的额外规范。首先,我们为每一个Peer组织指定了锚peer节点(peer0.org1.example.com和peer0,org2.example.com)。然后,我们为每一个成员指定了MSP文件夹路径,这就使我们可以在orderer创世块中按顺序的存储每个组织的根证书。这是一个很关键的概念。现在任何与排序服务通信的网络实体都能够被orderer验证其数字签名了。
运行shell脚本
确认你在examples/e2e_cli目录下,这是shell脚本所在的位置。为你的channel起一个独特的名字,然后替换掉下方的<channel-ID>参数。如果你不提供一个名字,那么这个脚本会运行失败。
1 | $ cd examples/e2e_cli |
这个脚本的输出有些多,因为它会生成加密库和多个文件。但是,你会在终端里看到5个截然不同的说明信息,如下所示:
1 | ########################################################## |
这些配置交易将会绑定参与成员和它们的网络组件的加密内容,并且生成1个orderer创世块和3个channel交易文件。对于启动一个Fabric网络,以及创建一个channel来在上面做交易,这些文件都是必要的。
用Docker运行end-to-end测试
确保你在/e2e_cli目录下。然后使用docker-compose创建网络实体运行测试。注意你可以使用TIMEOUT变量(以秒为单位),以便你的cli容器不会在脚本结束后立马退出。你可以使用任何数值:
1 | # TIMEOUT变量是可选的 |
如果你创建了一个特定的channel名称,确保将它传入到了参数中。比如,
1 | $ CHANNEL_NAME=abc TIMEOUT=1000 docker-compose -f docker-compose-cli.yaml up -d |
等待,大概60s左右。在后台,有交易发送给peers。执行docker ps命令来查看你激活的容器。你应该能够看到如下的输出:
1 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
如果你设置了一个比较大的TIMEOUT值,你还可以看到你的cli容器。
后台究竟发生了什么?
一个脚本 -
script.sh- 被放在了cli容器中。这个脚本会使用提供的channel名字,以及用于channel设置的channel.tx文件,执行createChannel命令。createChannel的输出是一个创世块 -<your_channel_name>.block- 会存在peers的文件系统中,并且包含了由channel.tx指定的channel配置。joinChannel命令用于所有4个peer节点,用上一步产生的创世块作为输入。该命令指示这些peer节点加入<your_channel_name>,并且创建一个以<your_channel_name>.block开始的链。现在我们有了一个包含4个
peer节点,和2个组织的链。这就是我们TwoOrgsChannel描述的样子。peer0.org1.example.com和peer1.org1.example.com隶属于Org1;peer0.org2.example.com和peer1.org2.example.com隶属于Org2。这些关系都定义在
crypto-config.yaml文件中,并且MSP路径在我们的docker-compose文件中指定了。Org1MSP(
peer0.org1.example.com)和Org2MSP(peer0.org2.example.com)的锚peer随后都会被更新,我们实现这一步是通过将Org1MSPanchors.tx和Org2MSPanchors.tx配置传入到orderer服务中实现的,同时传入的还有我们的channel名称。一个
chaincode-chaincode_example02- 被安装在了peer0.org1.example.com和peer0.org2.example.com上。这个
chaincode随后在peer0.org2.example.com被instantiate。初始化操作会将这个chaincode添加到channel中,针对目标peer启动docker容器,并且用和chaincode相关的key-value对进行初始化。在这个例子中初始化值为["a","100","b","200"]。初始化结束后,以dev-peer0.org2.example.com-mycc-1.0为名字的容器开始运行。对
a键的query发送到了peer0.org1.example.com上。相关的chaincode前面已经安装在了peer0.org1.example.com上,所以这将会为Org1 peer0运行一个名为dev-peer0.org1.example.com-mycc-1.0的容器。query的结果也会被返回。由于并没有发生写操作,所以对a的query依然会返回值100。有一个
invoke调用发送到了peer0.org1.example.com上,该调用是”a向b转10块钱”。这个
chaincode随后还被安装在了peer1.org2.example.com上。有一个对
a的query操作发送到了peer1.org2.example.com上。这会启动第3个chaincode容器,名为dev-peer1.org2.example.com-mycc-1.0。并返回值90,这正确的反映了之前的交易,即将a的值减10。
这证明了什么?
证明了chaincode必须要安装在一个peer上,以便于它能够成功地在账本上执行读/写操作。并且,一个peer上的chaincode不会马上就启动容器,直到有一个init操作或者有交易发生时才会运行 - 读/写操作 - 都是和chaincode相关的(比如:对a的query操作)。交易可以使容器开始运行。另外,在一个channel中的所有peer都会维护一个完全相同的账本拷贝,这个账本由区块链构成,存储了不可篡改的,在区块中有序记录的数据,并且还维护了一个状态数据库,来维持当前的fabric状态。这包含了那些没有安装chaincode的peer(比如:上面例子中的peer1.org1.example.com),它们依然也有账本拷贝和状态数据库。最后,这个被安装后的合约就是可以访问的(比如:上面例子中的peer1.org2.example.com),因为它在peer0.org2.example.com上已经被初始化了。
我如何查看这些交易?
可以查看CLI容器的logs:
1 | $ docker logs -f cli |
你会看到如下输出:
1 | 2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP |
我如何查看chaincode的logs
可以查看每一个chaincode容器的logs,来检查发生在各个容器上面的每一笔交易。下面是各个容器的集合输出:
1 | $ docker logs dev-peer0.org2.example.com-mycc-1.0 |
我全都要(ALL in one)
你也可以生成配置文件和加密资料,并且使用单独的shell脚本进行测试。crptogen,configtxgen,以及docker-compose命令都集合到了脚本里。如果你不提供一个channel ID,那么脚本就会使用默认名字mychannel。cli容器的超时参数是一个可选值;如果你不去设置它,那么cli容器将在脚本结束时退出。
1 | $ ./network_setup.sh up |
或者
1 | $ ./network_setup.sh up <channel-ID> <timeout-value> |
全部清理可以用以下命令:
1 | $ ./network_setup.sh down <channel-ID> |
参考文章
转载请注明出处:www.huamo.online