├── images
├── I2P1.png
├── P2F1.png
├── P2F2.png
├── P2F3.png
├── P2F4.png
├── P2F5.png
├── P2F6.png
├── P2F7.png
└── P2T1.png
├── Docker容器与容器云.md
├── Chaincode
├── .idea
│ ├── misc.xml
│ ├── modules.xml
│ ├── Chaincode.iml
│ └── workspace.xml
└── test1.go
├── First App in Fabric.md
├── A First Look at Identity Management Schemes on the Blockchain.md
├── README.md
├── Chaincode Instructions.md
├── Fabric v1.1 Installation.md
├── Architecture of the Hyperledger Blockchain Fabric.md
├── Fabric v0.6 Installation.md
└── A Distributed Operating System for Permissioned Blockchains.md
/images/I2P1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/I2P1.png
--------------------------------------------------------------------------------
/images/P2F1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F1.png
--------------------------------------------------------------------------------
/images/P2F2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F2.png
--------------------------------------------------------------------------------
/images/P2F3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F3.png
--------------------------------------------------------------------------------
/images/P2F4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F4.png
--------------------------------------------------------------------------------
/images/P2F5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F5.png
--------------------------------------------------------------------------------
/images/P2F6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F6.png
--------------------------------------------------------------------------------
/images/P2F7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2F7.png
--------------------------------------------------------------------------------
/images/P2T1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dearkano/Blockchain/HEAD/images/P2T1.png
--------------------------------------------------------------------------------
/Docker容器与容器云.md:
--------------------------------------------------------------------------------
1 | 第二版(浙大)
2 |
3 | 百度云链接:https://pan.baidu.com/s/17cu_RvwXlNL1c2y3oxkAWw
4 |
5 | 密码:pze8
--------------------------------------------------------------------------------
/Chaincode/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/First App in Fabric.md:
--------------------------------------------------------------------------------
1 | ## 第一个App
2 | http://hyperledger-fabric.readthedocs.io/en/release-1.1/write_first_app.html
3 |
4 | 根据教程走
5 |
6 | 需要注意的是
7 | * npm install 很慢很慢 看起来和卡住一样 等着即可
8 | * 如果之前跑过byfn.sh 一定要清理干净 docker也是一样
--------------------------------------------------------------------------------
/Chaincode/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Chaincode/.idea/Chaincode.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/A First Look at Identity Management Schemes on the Blockchain.md:
--------------------------------------------------------------------------------
1 | # A First Look at Identity Management Schemes on the Blockchain
2 |
3 | 原文:https://arxiv.org/ftp/arxiv/papers/1801/1801.03294.pdf
4 |
5 | 作者 : Paul Dunphy and Fabien A. P. Petitcolas
6 | Innovation Centre, VASCO Data Security {paul.dunphy,fabien.petitcolas}@vasco.com
7 |
8 | 翻译 :Vayne Tian
9 |
10 | 1/10/2018
11 |
12 | ### 摘要
13 |
14 | 以区块链数据结构为基础的分布式账本技术(DLT)的出现,带来了新的识别身份手段的需求,这将颠覆传统的提供和使用数字身份的技术。这些身份管理(IdM)的新技术希望提高去中心化程度、透明度和涉及身份信息的交易中的用户控制。然而,面对多年来设计IdM遇到的重重困难,基于DLT的IdM能实现它们的远大目标吗?我们将会介绍基于DLT的IdM的展望,并使用对表征了那些成功的IdM特性的重要框架的分析来评估三个有代表性的建议:uPort,ShoCard,Sovrin。
15 |
16 | ### 关键字
17 |
18 | 分布式账本技术,身份和访问管理
19 |
20 | ## 简介
21 |
22 | 24年前, Peter Steiner 提出了著名的“在互联网上,没人知道你是一只狗”的论断,这句话如今仍然揭示着在互联网上身份验证存在的挑战。无论是七十年代公钥加密算法的发明者对公共目录的愿景,还是八十年代分级认证技术的宏大体系,我们都还有很长的路要走。
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### 记录在学习Hyperledger Fabric和Blockchain过程中遇到的问题和一些资源,以及一些论文的翻译。
2 |
3 | ### TIMELINE
4 |
5 | * 3/19/2018
6 |
7 | * **CREATE** Repository
8 |
9 | * 3/20/2018
10 | * **COMMIT** Instruction : *Fabric v0.6 Installation*
11 |
12 | * 3/31/2018
13 | * **COMMIT** Translation : *Architecture of the Hyperledger Blockchain Fabric*
14 |
15 | * 4/2/2018
16 | * **COMMIT** Translation : *Hyperledger Fabric:A Distributed Operating System for Permissioned Blockchains*
17 |
18 | * 4/4/2018
19 | * **UPLOAD** Book : *Docker容器与容器云*
20 |
21 | * 4/6/2018
22 | * **UPLOAD** Translation : *A First Look at Identity Management Schemes on the Blockchain*
23 |
24 | * 4/12/2018
25 | * **COMMIT** Code : *Fabric Chaincode Test*
26 |
27 | * 4/12/2018
28 | * **COMMIT** Instruction : *Fabric v1.1 Instruction*
--------------------------------------------------------------------------------
/Chaincode/test1.go:
--------------------------------------------------------------------------------
1 | package Chaincode
2 | import (
3 | "github.com/hyperledger/fabric/core/chaincode/shim"
4 | pb "github.com/hyperledger/fabric/protos/peer"
5 | "fmt"
6 | )
7 |
8 | type SimpleChaincode struct {
9 | }
10 |
11 | func main() {
12 | err := shim.Start(new(SimpleChaincode))
13 | if err != nil {
14 | fmt.Printf("Error starting Simple chaincode: %s", err)
15 | }
16 | }
17 | func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
18 | return shim.Success(nil)
19 | }
20 |
21 |
22 | func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
23 | function, args := stub.GetFunctionAndParameters()
24 | fmt.Println("invoke is running " + function)
25 | if function == "test1" {//自定义函数名称
26 | return t.test1(stub, args)//定义调用的函数
27 | }
28 | return shim.Error("Received unknown function invocation")
29 | }
30 | func (t *SimpleChaincode) test1(stub shim.ChaincodeStubInterface, args []string) pb.Response{
31 | return shim.Success([]byte("Called test1"))
32 | }
--------------------------------------------------------------------------------
/Chaincode Instructions.md:
--------------------------------------------------------------------------------
1 | ## go chaincode 部署的常用命令
2 | ### fabric v0.6 pbft
3 |
4 | * 启动网络
5 |
6 | docker-compose -f 4-peers.yml up
7 |
8 | * 查看容器
9 |
10 | Docker ps
11 |
12 | * 进入容器
13 |
14 | docker exec -it pbft_vp0_1 bash
15 |
16 | * 部署chaincode
17 |
18 | * 官方example02
19 |
20 | peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "2000"]}'
21 |
22 | * 自己的test1.go
23 |
24 | peer chaincode deploy -p test1.go -c '{"Function":"init", "Args": []}'
25 |
26 | * 查询
27 |
28 | peer chaincode query -n "ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" -c '{"Function": "query", "Args": ["a"]}'
29 |
30 |
31 | * 调用
32 |
33 | peer chaincode invoke -n "ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'
34 |
35 | * 打印日志
36 |
37 | docker logs -f pbft_vp0_1
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Fabric v1.1 Installation.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Blockchain_fabric
4 | Study hyperledger fabric
5 | ### Author:VayneTian 4/12/2018
6 | ## Hyperledger Fabric v1.1 安装与测试
7 | ## Prerequisites
8 | ### 操作系统
9 | 本文使用Ubuntu 16.04
10 |
11 | * `apt install git`
12 | * `curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -`
13 | * `apt install -y nodejs`
14 | * `apt install docker`
15 | * `apt install docker-compose`
16 | * `git clone https://github.com/hyperledger/fabric.git`
17 | * `git clone -b master https://github.com/hyperledger/fabric-samples.git`
18 | * `cd fabric/scripts`
19 | * `./bootstrap.sh`
20 | * https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/
21 | * 下载对应系统的v1.0.0二进制 并解压到fabric-samples下面
22 | * `cd fabric-samples/first-netword`
23 | * `./byfn.sh -m generate`
24 | * `./byfn.sh -m up`
25 |
26 |
27 | ## 下载测试代码
28 | `git clone -b master https://github.com/hyperledger/fabric-samples.git`
29 |
30 | ## 下载fabric源码
31 | 这段代码会下载fabric的文件并且使用脚本去拉取dockerhub上的镜像并全部标记latest
32 |
33 | * 如果你可以翻墙 一步ok
34 |
35 | `curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0`
36 |
37 | * 不能的话
38 |
39 | `git clone https://github.com/hyperledger/fabric.git`
40 |
41 | 打开script文件夹命令行
42 |
43 | `sh bootstrap.sh`
44 |
45 | ## 下载fabric二进制文件
46 |
47 | https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/
48 |
49 | 在源码下新建aberic文件夹 解压进去
50 | 这里注意 对应自己的系统去下载
51 |
52 | 然后将bin文件夹放在fabirc-samples下面
53 |
54 | ## 一些坑
55 |
56 | * 第一次up遇到这个bug
57 |
58 | After 5 attempts, PEER1 has failed to Join the Channel
59 |
60 | 是环境遗留问题 去./byfn.sh down mychannel一下再开
61 |
62 |
63 | * 如果提示port被占用,停止容器并删除
64 |
65 | docker stop $(docker ps -a -q)
66 |
67 | docker rm $(docker ps -a -q)
68 |
69 |
70 |
71 |
72 | * 如果是在阿里云机器上部署fabric ,在e2e_cli 启动网络时,遇到以下错误
73 |
74 | FAILED to execute End-2-End Scenario
75 |
76 | 用户则需要修改 /etc/resolv.conf 配置,将 options timeout:2 attempts:3 rotate single-request-reopen 这一行内容注释掉
77 |
78 | https://www.cnblogs.com/chenfool/p/8353425.html
79 |
80 | 这篇博客的debug内容还不错 其他一概推荐官方教程
81 |
82 | http://hyperledger-fabric.readthedocs.io/en/release-1.1/build_network.html
83 |
84 |
85 |
86 | ## 环境变量
87 |
88 |
89 | export CHANNEL_NAME=mychannel
90 |
91 |
92 | CORE_PEER_MSPCONFIGPATH=./crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
93 |
94 | CORE_PEER_ADDRESS=peer0.org1.example.com:7051
95 |
96 | CORE_PEER_LOCALMSPID="Org1MSP"
97 |
98 | CORE_PEER_TLS_ROOTCERT_FILE=./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
99 |
100 | peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
101 |
102 |
--------------------------------------------------------------------------------
/Architecture of the Hyperledger Blockchain Fabric.md:
--------------------------------------------------------------------------------
1 | # Hyperledger Fabric架构
2 | 原文:Architecture of the Hyperledger Blockchain Fabric
3 | 作者:Christian Cachin
4 | IBM Research - Zurich CH-8803 R¨uschlikon, Switzerland
5 | 翻译:Vayne Tian
6 | 这篇文章是读完论文后翻译过来的,也算是给自己加深印象,有翻译的不好的地方多多见谅。
7 | 原文地址:https://pdfs.semanticscholar.org/f852/c5f3fe649f8a17ded391df0796677a59927f.pdf
8 |
9 | # 总览
10 | 区块链可以被看作是状态机的复本。任何时间点对整个链进行快照,就可以将结果视为一种世界状态,而客户进行的操作——智能合约的调用的实质就是改变世界状态并产生一些输出。区块链通过分布式的网络节点,模拟了一种可信计算的服务系统。这个系统相当于或者产生了一笔资产,而所有的节点都持有它的股份。这些节点不需要信任对方,但有一个共同的目标,就是将这个服务持续运行下去。在一个没有准入机制的区块链里,比如加密货币比特币底层的架构,任何人都可以去操作一个节点,并且通过基于CPU运算(原文如此)的工作量证明参与其中。但从另一方面来说,如果一个区块链拥有准入机制,那么它就可以通过验证和协议来控制什么节点可以参与进来,这些节点通常拥有一致性并建立起联盟。
11 |
12 | # Hyperledger
13 | 超级账本是一个致力于建立企业级的开源分布式账本框架和代码库的合作项目。它的目标是通过实现一个分布式账本的跨行业开放式标准来发展区块链技术,这将改变全世界商业交易的方式。2016年初,Linux基金会成立了HyperLedger项目,目前已经有超过50名成员。(200+,2018)
14 |
15 | # Hyperledger Fabric
16 | HyperLedger Fabric是一种分布式账本平台的实现,它利用成熟的经过验证的技术和模块化的架构,来运行智能合约并允许实现各式可插拔的函数。它是 HyperLedger多个同时孵化中的子项目之一。2016年6月,Hyperledger Fabric v0.5开发版公布。(v1.1为现在的开发版 2018)
17 |
18 | HyperLedger Fabric的分布式账本协议是在peers上运行的。Fabric区分两种peer,一种是validating peer,作为网络上负责运行共识,验证交易和维持账本。另一种non-validating peer的作用则是作为代理服务器,连接其他的客户到validating peer,本质上就是发布交易。一个non-validating peer可能只是验证交易而并不会去执行交易。
19 |
20 | # Fabric v0.5的一些主要特性
21 |
22 | 1.拥有准入机制的区块链,交易发生后在极短时间内达成共识并产生最终结果
23 | 2.可以运行任意的智能合约(这里叫做chaincode 链码) 使用go语言实现
24 | 用户定义的链码被封装在docker容器中,系统级的链码则会同样以peer的形式运行
25 | 3.可插拔共识算法,使用实用拜占庭同错算法(PBFT),可用SIEVE的原型来部署非确定性链码,对于单peer可以使用NOOPS(一种协议存根)作为开发服务
26 | 4.通过证书颁发机构(CAs)发布TLS证书,注册证书和交易证书来保证安全性
27 | 5.利用RocksDb支持键值对存储接口实现持久状态
28 | 6.拥有支持预定义和自定义事件的框架
29 | 7.拥有nodejs接口实现的客户端SDK
30 | 8.支持REST APIs和CLIs
31 | 在v0.5-dev版本中,只实现了最低限度对non-validating peer的支持。
32 |
33 |
34 | # HyperLedger Fabric架构
35 |
36 | 这些validating peers将会通过拜占庭容错的共识算法运行一个状态机副本来接收三种交易信息
37 |
38 | 部署交易:将一个用go语言编写的链码(智能合约)当作参数,链码将会在peers上安装并准备执行。
39 |
40 | 执行交易:调用一段早先被部署在peers上的链码执行交易。参数与具体调用的链码类型有关。链码执行交易,将会在世界状态上进行读写,并指出这个交易是否成功。
41 |
42 | 查询交易:通过直接读取peer的状态返回一些条目,这个操作不会保证线性一致性。
43 |
44 | 每个链码可以定义在世界状态中自己的固有条目。区块链上的哈希链是基于已经执行的交易以及交易产生的状态计算出来的。
45 |
46 | 交易只有在重复执行链码并保证满足拜占庭容错的假设时才有效,举例来说,n个validating peer中有最多f<(1/3)*n个节点可能撒谎并产生任意行为,但其他的peer一定会正确运行。当在使用拜占庭容错算法上运行时,链码必须保证其确定性,否则peers的状态可能会产生分叉。一个可以分离出可能会导致分叉的非确定性交易的解决方案已经被证实,并且在实现在SIEVE协议中。
47 |
48 | Validating peers之间通过拜占庭容错算法建立的关系是静态的,并且在初始化阶段需要人为干预。对于动态变更节点的共识算法的支持将在未来版本中发布。
49 |
50 | 由于HyperLedger Fabric实现了拥有准入机制的账本,它得以包含了可以认证和授权的安全架构。支持通过公钥认证来注册和授权交易,通过带内加密保证链码的保密性。
51 |
52 | 更准确地说,为了连接到网络,每个peer需要通过成员服务中的注册证书颁发机构(CA)获取注册认证。它允许这个peer连接到网络并获取在交易时所需要的交易证书。交易证书颁发机构会发布交易证书并且支持对那些提交交易的节点进行匿名认证,从这个意义上讲,多个发布给同一个peer的交易证书(对于注册证书而言也是一样)不会互相产生联系。
53 |
54 | 对于所有拥有注册证书的peer,链码和状态的保密性是通过使用区块链专有的密钥对交易和状态进行对称加密实现的。在将来的版本中,将会扩展加密功能来为交易和状态提供更好的保密性。
55 |
56 |
57 | # 对HyperLedger Fabric的一些讨论
58 | 当前对于区块链的共识算法有非常激烈的争论,不仅仅是在学术界,对于一些金融科技的创业公司也是一样。例如tendermint,kadena。Fabric的设计使用了模块化的概念,对准了已经成熟的分布式计算中的共识系统。这将保证Fabric的区块链相关的特性将会独立地在不同的共识算法上发展,实用拜占庭容错(PBFT)由于它的知名,成为了在Fabric上首个实现的共识算法,这是在20年来对于系统级别的拜占庭容错研究经验上发展而来的,它和一些知名的共识算法有紧密的联系,比如Poxos和Viewstamped replication,这些算法都已经在许多环境中被实现或是写进了教科书中。
59 |
60 | # 小结
61 |
62 | 与极客推崇的完全去中心化的系统不同,HyperLedger Fabric是拥有准入机制的多中心化的基于商业用途的区块链平台。它开源,依据规范,并能运行用户定义的智能合约。它拥有很强的安全性以及身份特征,并且使用了模块化的框架与可插拔的分布式共识。
63 | 在Hyperledger项目的管理下,Fabric正在飞速进化和发展。
64 |
--------------------------------------------------------------------------------
/Fabric v0.6 Installation.md:
--------------------------------------------------------------------------------
1 | # Blockchain_fabric
2 | Study hyperledger fabric
3 | ### Author:VayneTian 3/19/2018
4 | ## Hyperledger Fabric v0.6 安装与测试
5 | ## Prerequisites
6 | ### 操作系统
7 | 本文使用Ubuntu 16.04
8 | ### 安装python
9 | `sudo apt-get install python`
10 | ### 安装golang
11 | `sudo apt-get install golang`
12 | ### 安装nodejs
13 | `sudo apt-get install nodejs`
14 | ### 安装curl
15 | `sudo apt-get install curl`
16 | ### 安装git
17 | `sudo apt-get install git`
18 |
19 | 最后记得update
20 | `sudo apt-get update`
21 | ### 安装docker与docker-compose
22 | 由于国内网络原因使用镜像
23 | https://www.cnblogs.com/tianhei/p/7802064.html
24 | 或
25 | https://www.cnblogs.com/studyzy/p/7492637.html
26 | ## Fabric
27 | ### 拉取Fabric v0.6镜像
28 |
29 | ```sh
30 | $ sudo docker pull yeasy/hyperledger-fabric-base:0.6-dp \
31 | && sudo docker pull yeasy/hyperledger-fabric-peer:0.6-dp \
32 | && sudo docker pull yeasy/hyperledger-fabric-membersrvc:0.6-dp \
33 | && sudo docker pull yeasy/blockchain-explorer:latest \
34 | && sudo docker tag yeasy/hyperledger-fabric-peer:0.6-dp hyperledger/fabric-peer \
35 | && sudo docker tag yeasy/hyperledger-fabric-base:0.6-dp hyperledger/fabric-baseimage \
36 | && sudo docker tag yeasy/hyperledger-fabric-membersrvc:0.6-dp hyperledger/fabric-membersrvc
37 | ```
38 | 注意多拉几次,全部拉成功,可能网络原因会连接失败
39 |
40 | 使用默认镜像(官方dockhub)进行拉取时,往往会遇到速度极慢或handshake timeout的情况
41 | 解决方案:换用国内仓库daocloud.如果你未遇到拉取过慢的情况,请跳过下面的内容
42 | ``echo "DOCKER_OPTS=\"\$DOCKER_OPTS --registry-mirror=http://f2d6cb40.m.daocloud.io\"" | sudo tee -a /etc/default/docker
43 | ``
44 | ``sudo service docker stop``
45 | 修改 /etc/defaut/docker 文件,增加参数实行强制普通模式避免新版docker使用第三方仓库报错:
46 | ``DOCKER_OPTS="--insecure-registry http://dl.dockerpool.com:5000"``
47 | 再重启服务:
48 | ``sudo service docker restart``
49 |
50 | ### clone demo
51 | `git clone https://github.com/yeasy/docker-compose-files`
52 |
53 | ### 启动peer
54 | `cd docker-compose-files/hyperledger_fabric/v0.6.0/pbft/`
55 | `docker-compose -f 4-peers.yml up`
56 | 可以看到终端中已经成功运行了peer网络
57 |
58 | ### 部署chaincode
59 | 在当前地址打开另一个终端
60 | `docker exec -it pbft_vp0_1 bash`
61 | 可以看到命令行发生了变化,变成了
62 | `root@vp0:/go/src/github.com/hyperledger/fabric#`
63 | 部署一个example
64 | `peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'`
65 | 这个示例是初始化两个账户a和b,a有余额100元,b有余额200元
66 | 我们可以看到部署成功并返回了ChainCode的ID
67 | 我这里是
68 | ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539
69 | ### 查询chaincode
70 | 下面我们把这个ID放入一个变量中:
71 | `CC_ID="ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539"`
72 | 下面我们来查询一下a账户的余额:
73 | `peer chaincode query -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}'`
74 | Query Result: 100
75 | 可以看到余额是100元
76 | ### 调用chaincode
77 | 接下来,我们让a给b转账10元,运行命令:
78 | `peer chaincode invoke -n ${CC_ID} -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'`
79 | 现在已经转账完毕,我们再来查询一下a账户的余额:
80 | `peer chaincode query -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}'`
81 | Query Result: 90
82 | 可以看到少了十元
83 |
84 | ### 使用REST在windows调用
85 | 首先安装chrome插件DHC
86 | 提供一个链接
87 | https://pan.baidu.com/s/1mSdtfURbKauk2WYYPn_YmA
88 | 解压以后把_metadata重命名metadata然后用chrome添加即可
89 | (下面是使用虚拟机的内容)
90 | 在ifconfig里找到虚拟机的IP,我这里地址是192.168.198.128:7050/chaincode,然后在DHC里发送http请求即可完成调用
91 | 一个示例
92 | body部分:
93 | ```sh
94 | {
95 | "jsonrpc": "2.0",
96 | "method": "deploy",
97 | "params": {
98 | "type": 1,
99 | "chaincodeID":{
100 | "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
101 | },
102 | "ctorMsg": {
103 | "function":"init",
104 | "args":["a", "1000", "b", "2000"]
105 | }
106 | },
107 | "id": 1
108 | }
109 | ```
110 | header部分:
111 | `Content-Type:text/javascript`
112 | 成功会返回code200,建议使用vmware,vbox可能出现主机ping不到客户机的情况。
113 |
114 | (下面是使用两台主机的内容)
115 | 在ifconfig里找到对应IP,注意以太网和无线局域网的IP是不同的,注意根据自己当前所使用网络类型区别(一般很容易分辨)
116 | 有必要强调的是,如果您使用浙大校园网(有线or无线),请务必使用通过上述命令查得的私有IP(10开头),而非其他第三方应用检测的公网IP
117 | 由于暂未知(可能是交换机限制)的原因,公网IP不仅ping不通,以其为目标的post请求也会失败
118 | 强烈建议您在进行post尝试前先运行ping命令进行检测,以避免不必要的麻烦
119 | 之后的操作(包括端口号和下级目录名)同虚拟机配置
120 |
121 |
122 |
--------------------------------------------------------------------------------
/Chaincode/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | true
47 | DEFINITION_ORDER
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/A Distributed Operating System for Permissioned Blockchains.md:
--------------------------------------------------------------------------------
1 | # Hyperledger Fabric : A Distributed Operating System for Permissioned Blockchains
2 |
3 | (全文约21000字)
4 |
5 | 原文:https://arxiv.org/pdf/1801.10228.pdf
6 |
7 | 作者:Elli Androulaki, Artem Barger, Vita Bortnikov, Christian Cachin, Konstantinos Christidis, Angelo De Caro, David Enyeart, Christopher Ferris, Gennady Laventman, Yacov Manevich, Srinivasan Muralidharan∗, Chet Murthy†, Binh Nguyen ∗, Manish Sethi, Gari Singh, Keith Smith, Alessandro Sorniotti, Chrysoula Stathakopoulou, Marko Vukoli´c, Sharon Weed Cocco, Jason Yellick
8 |
9 | IBM
10 | 2/1/2018
11 |
12 | 翻译:Vayne Tian
13 |
14 | ## 摘要
15 | Hyperledger Fabric是一个用来部署和操作拥有准入机制的区块链(私有链)的模块化可扩展的开源系统。Fabric目前已经被应用在超过400种跨行业的生产系统和分布式账本技术的原型与概念实现中。
16 |
17 | 在不存在万能解决方案的前提下,Fabric是第一个可扩展的运行分布式程序的区块链系统。它支持通过模块化的共识算法定制特定的使用场景和信任模型。Fabric还是第一个对原生加密货币没有系统依赖性,并应用通用编程语言编写分布式程序的区块链。这和一些现在的主流区块链平台形成了鲜明对比,这些平台要么依赖于特定领域语言编写的智能合约,要么依赖于加密货币。此外,它还使用可插拔的成员资格的概念实现了一个准入模型,这将可能会与身份管理系统的行业标准结合。为了支持这种灵活性,Fabric用一种全新的方式实现了私有链的设计,并且改变了区块链处理不确定性、资源枯竭和性能攻击的问题。
18 |
19 | 这篇文章描述了Fabric的架构,它的各种设计决定背后的原理,它的安全模型与保障,以及最显著的实现特征,和它的分布式系统编程模型。
20 |
21 | 我们还对Fabric进行了更深层次的评估,实现和测试一个比特币类的数字货币。结果显示,亚秒级延迟的情况下,在一个特定的合约部署中,Fabric实现了每秒超过3500个端到端交易的性能量级。
22 |
23 | ## 1.简介
24 |
25 | 区块链可以被如此定义:它是一个不可变账本,记录交易历史,维护一个毋须信任节点间的分布式网络。每个节点维护一个账本的副本。节点执行共识算法来验证交易,把它们分组进区块,并根据区块信息生成哈希链。这个过程将会给交易排序,这对于保证连续性和一致性是十分必要的。区块链技术已经从比特币的名号中脱颖而出,并被广泛地认为是一种在数字世界中进行信任通信的很有前景的技术。
26 |
27 |
28 | 在一个公有链中,任何一个没有特定身份的人都可以参与进来。公有链常常需要原生的加密货币,以及工作量证明作为共识算法和产生经济利益。
29 |
30 | 从另一方面来讲,私有链在一系列已知身份的节点中运行区块链。它可以通过在一组毋须信任对方但有相同目标的的实体中保证安全性,就像在商业中进行基金、信息和商品的交换(同样为了追求利益,而不需要信任对方)。由于节点身份已知,私有链可以使用传统的拜占庭容错作为共识算法。
31 |
32 | 区块链在智能合约(例如以太坊的实现)的帮助下,可以实现任意可编程的交易逻辑。比特币中的脚本是合约的前身。一个智能合约可以像一个可信分布式应用一样运作,通过区块链和节点间的共识算法获取安全性。这与知名的通过状态机副本建立应用的方式十分类似。然而,使用拜占庭容错算法的区块链技术与传统的状态机副本区别如下:
33 |
34 | 1.多个而不是只有一个分布式应用在并行运行。
35 | 2.应用可以被任何人动态的创建部署。
36 | 3.应用的代码是不受信任的甚至恶意的。
37 |
38 | 这些特性需要一个新的设计来实现。
39 |
40 | 目前实现智能合约的区块链很多是基于状态机复制的蓝图,实现了所谓的主动复制(active replication):
41 |
42 | 1.共识算法,或是原子广播,首先对交易进行排列,然后把他们按排列广播给所有节点
43 | 2.每个节点按照排序-执行进行交易
44 |
45 | 我们把这个叫做排序-执行架构,它要求节点要执行每一个交易,并且所有的交易都是确定的。这种排序-执行架构可以在几乎所有现存的区块链中找到,无论是公有链,比如基于工作量证明的以太坊(存疑,原文如此,以太坊使用的是权益证明),或者是使用拜占庭容错算法的私有链,像Tendermint,Chain,Quorum 。尽管如此,排序-执行的设计并不是被使用在所有的系统中,因为额外的交易可能会扰乱它,这种设计的局限性是它与生俱来的:每个节点都要执行所有的交易,并且所有的交易必须是确定的。
46 |
47 | 早先的私有链受到许多限制,这些限制来源于相似的公有链或是排序-执行架构。尤其是以下部分:
48 |
49 | 1.共识机制是在平台中硬编码的(难以修改),这和之前所说的没有一种万能的(BFT)共识算法相矛盾。
50 | 2.交易验证的信任模型是被共识算法所决定的,而这个模型不适应智能合约的一些要求。
51 | 3.智能合约必须使用固定的,不标准的,领域特定语言编写,这阻碍了它被进一步广泛的应用,并且可能导致一些编程错误。
52 | 4.全节点都对交易进行排序-执行过程会限制性能,并且还需要一些复杂的方法去防止对平台发起的拒绝攻击,这种攻击源自不可信的智能合约,比如 accounting for runtime with “gas” in Ethereum(这里还不太了解~)。
53 | 5.交易必须是确定的,但这很难以编程层面的方法去保证。
54 | 6.每个智能合约都在所有的节点上运行,这和它的保密特性相矛盾,并且禁止仅向一部分节点发送合约代码与状态。
55 |
56 | 在这篇文章中,我们将会介绍Hyperledger Fabric,一个突破了以上限制的区块链平台。Fabric是Linux基金会支持的超级账本项目下的子项目之一。Fabric已经在超过400种不同行业、不同用途的原型、概念或是分布式账本系统的开发中被使用。
57 |
58 | 这些用途包括但不仅限于解决争端,物流贸易,外汇网络,食品安全,合同管理,珠宝鉴定,积分管理,低流动性证券的交易和结算,身份管理,数字货币结算等。
59 |
60 | Fabric使用了新的区块链架构,具有弹性,灵活性,可扩展性和保密性。作为一种模块化可扩展的通用私有链,Fabric支持标准通用编程语言编写的分布式应用。这使得Fabric成为私有链的第一个分布式操作系统。
61 |
62 |
63 | 为了在不可信的环境中分布式执行不可信的代码,Fabric遵循一种新的排序-执行-验证(execute-order-validate)的范式。它将交易流程分为三个步骤:
64 | 1.执行交易并检查交易的正确性,从而将其合法化。(这与其他区块链中的验证交易环节相对应)
65 | 2.通过共识算法给交易排序,这里不考虑交易的内容。
66 | 3.根据特定背书策略进行交易的验证(这解决了由于并行产生的竞争问题),将相应区块写入区块链。
67 |
68 | Fabric的设计与排序-执行范式完全不同,它通常在按照交易顺序达成最终共识前就已经执行了交易。它结合了主动和被动两种手段生成副本。下文将会介绍它们。
69 |
70 | 首先,Fabric使用被动复制(passive replication)或主服务器备份,这是分布式数据库中很常见的手段,但Fabric通过基于中间件的非对称更新过程将其移植到存在拜占庭错误的不可信环境中。在Fabric中,依靠“执行-验证”拜占庭容错算法的副本,每个合法交易只会在一部分节点中执行,这考虑到了并行执行的情况并解决了潜在的不确定性。灵活的背书策略将指定哪些或多少节点需要对这个智能合约的正确执行进行担保。
71 |
72 | 其次,Fabric还结合了主动复制(active replication),在验证阶段,交易对账本状态的改变,只有在按照它们的全序达成一致后才被写入。Fabric根据交易背书来判断是否满足指定应用的背书策略。此外,为了达成一致性,状态更新的顺序被委派给了模块化的组件,比如原子广播(一个无状态的组件,并且与那些执行交易和维持账本的节点逻辑上是解耦的)。由于共识算法被模块化,因此可以根据特定的背书策略去自定义共识算法。虽然也可以直接通过区块链的节点去实现共识算法,但分开这两个角色显然可以更好地增加灵活性,并使得它可以直接使用非拜占庭容错CFT (Crash fault-tolerant) 或拜占庭容错BFT (Byzantine fault-tolerant) 的工具包进行排序。
73 |
74 | 综上,这个在拜占庭错误模型下结合了主动复制和被动复制的混合副本设计,以及顺序交易验证的范式,就是Fabric架构的主要创新点。它们解决了之前所说的问题,并使得Fabric成为一个在私有链中支持灵活的可信假设的可扩展系统。
75 |
76 | 为了实现这个架构,Fabric包含了以下模块化组件。
77 |
78 | **排序服务**:排序服务向所有节点原子广播状态的更新,并在交易顺序上建立共识。Apache Kafka/ZooKeeper 和 BFT-SMaRt 已经实现了排序服务。
79 |
80 | **身份与成员资格**:成员资格服务负责通过加密身份将节点联系起来,这项服务使得Fabric拥有准入机制。
81 |
82 | **可扩展的传播**:可选的点对点通信(gossip)服务通过对所有节点的排序服务传播来区块的输出。
83 |
84 | **智能合约的执行**:Fabric的智能合约在完全隔离的容器环境中执行。它们可以用通用编程语言编写,同时不与账本状态直接产生联系。
85 |
86 | **账本维护**:每个节点在本地以键值对的储存形式(KVS)用可追加的区块链来保存账本,并将它作为最新状态的快照。可以使用标准数据库实现这个键值对储存,比如LevelDB 或 Apache CouchDB。
87 |
88 | 文章的剩余部分将详细介绍Fabric的架构以及我们对它的理解。第二节总结了不同的设计并解释了这些不同设计背后的基础原理。第三节从细节上介绍了Fabric的架构和排序-执行-验证的方法,并详细阐述了交易流程。第四节定义了Fabric的关键组件,尤其是排序服务,成员管理服务,点对点通信,账本数据库和智能合约的API。第五节给出了在公开商业化云虚拟机的集群环境下,对Fabric进行使用类比特币的加密货币的性能评估的结果和领悟。结果显示,Fabric在常见的部署配置下,达到了超过3500 tps的吞吐量,算上延迟的情况下在几百毫秒内就可以达成最终共识。最后,在第六节,会讨论一些相关研究。
89 |
90 | ## 2.背景
91 |
92 | ### 2.1 区块链的排序-执行架构
93 |
94 | 无论是否有准入机制,早先的所有区块链系统都遵循排序-执行架构。这意味着区块链网络首先会使用共识算法对交易进行排序,然后在所有节点上按照这个排序线性执行交易。
95 |
96 | 例如,基于工作量证明的公有链比如以太坊使用以下方式结合智能合约和交易的执行。
97 |
98 | 1.每个节点(比如参与合约的节点)收集一个含有有效交易的区块。(为了达到有效,这个节点必须预先执行过这些交易)
99 | 2.节点尝试去解决一个数学难题完成工作量证明。
100 | 3.如果这个节点解决了数学难题,就会将区块通过传输协议分发到整个网络。
101 | 4.每个节点接收区块并验证数学难题的解以及区块中的所有交易是否合法。实际上,每个节点从第一步开始重复了那个解决谜题的幸运节点的执行内容。此外,所有节点线性执行所有的交易(在一个区块内以及区块间)。这个排序-执行架构如图1所示。
102 |
103 |
104 | 
105 |
106 |
107 |
108 | 现有的私有链,比如Tendermint,Chain或是Quorum通常使用了拜占庭容错的一致性,这个一致性是由实用拜占庭容错算法(PBFT)或其他的实现原子广播的协议。然而,他们都遵循同样的排序-执行的方法,并实现了传统的主动状态机副本的架构。
109 |
110 | ### 2.2 排序-执行的局限性
111 |
112 | 排序-执行架构从概念上理解很简单,因此被广泛的使用。然而,当将它应用在通用私有链中时会有许多缺陷。随后我们将讨论其中最重要的三点。
113 |
114 | **线性执行**
115 | 在所有的节点上线性执行交易限制了区块链所能达到的有效吞吐量。特别是由于吞吐量与执行操作的延迟成反比,这可能会成为所有智能合约(即使是最简单的合约)的瓶颈。此外,回想一下与传统的状态机副本(SMR)相比,区块链实现了一个通用的计算引擎,但它的载荷应用可能是被恶意部署的。拒绝(DoS)攻击严重降低了区块链的性能,将会直接导致智能合约需要非常久的时间才能执行。例如,一个产生无限循环的智能合约就可以有这样致命的效果,并且由于停机问题不可解,使得错误很难被自动识别到。
116 |
117 | 为了解决这类问题,公有可编程区块链使用加密货币来支付交易费用。例如,以太坊推行了交易执行中花费gas的概念,gas被转换成一定价值的加密货币并由交易的发起者支付。以太坊使用了一个很长的环节去完成这个过程,首先为每一个底层计算步骤分配费用,然后使用自己的虚拟机监视器去控制交易的执行。尽管这看起来是为公有链提供了一个可选的解决方案,然而对于不使用原生加密货币的为通用系统所设计的拥有准入机制的模型来说并不合适。
118 |
119 | **非确定性代码**
120 | 排序-执行架构存在的另一个重要问题是非确定性交易。在主动状态机副本(SMR)的共识算法中执行的操作必须是确定的,否则分布式账本会产生分叉,这会对区块链最基础的前提产生威胁——所有的节点必须保存相同的状态。这个问题通常是通过使用领域特定语言(比如以太坊的Solidity)编写合约来解决,这些语言足够编写这些区块链的应用但对于确定性合约的执行却增加了限制。设计这些语言对于实现者来说也是非常困难的,并且还要求程序员要额外学习知识去使用这个语言。然而使用通用编程语言(例如Go,Java,C/C++)很明显更加有吸引力,并且能加速区块链解决方案的落地。
121 |
122 | 不幸的是,通用编程语言在确保非确定性操作的执行时产生了很多问题。即使应用开发者不显式使用非确定性的操作,一些隐式实现的细节可能也会导致相同的破坏性的效应(例如,一个映射的迭代器在Go语言中是非确定性的)。尤其糟糕的是,在区块链上创建确定性应用的负载取决于潜在的不可信的程序员。仅仅一个非确定性的被恶意创建的合约已经足以将整个区块链停机。模块化的过滤这种破坏性操作的解决方案已经被研究出来,但很显然这在实际应用中开销太大。
123 |
124 | **操作执行的保密性**
125 | 根据公有链的蓝图,区块链需要在全部的节点上运行智能合约。然而,许多需要准入机制的用途都要求保密性,例如,对智能合约、交易信息或者账本状态的访问应当被限制。虽然从数据加密到零知识证明和可验证计算的加密技术可以帮助实现这种保密性,但这通常会带来非常大的开销,在实际生产中并不可取。
126 |
127 | 幸运的是,Fabric能满足把相同的状态散布到所有的节点,而不直接把相同的代码到处运行。因此,智能合约的执行可以被限制在对于这个任务来说可信的节点集中。这个设计与主动复制不同,它通过各式被动复制适应了区块链的信任模型。
128 |
129 | ### 2.3 现存架构的其他局限性
130 |
131 | **固定的信任模型**
132 | 大多数私有链依赖于异步BFT副本协议去建立共识。这样的协议通常依赖于一个假设:不多于1/3的节点是恶意节点,也就是所谓的拜占庭容错(even though one could actually restrict BFT execution to fewer peers ,待译)。然而,这样一个基于恶意节点数量,而且不考虑节点在系统中扮演的角色的信任假设,可能不会匹配智能合约执行时所要求的信任模型。在一个灵活的系统中,应用级别的信任和协议级别的信任不应被固定在同一水平。一个通用的区块链应该解耦这两个前提假设,并且允许在应用上使用更灵活的信任模型。
133 |
134 | **硬编码的共识算法**
135 | Fabric是第一个推行可插拔共识算法的区块链系统。在Fabric之前,几乎所有的区块链系统,无论是否拥有准入机制,都使用了硬编码的共识算法。然而,数十年来对共识算法的研究早已证明没有一种万能的算法可以适应所有场景。例如,当BFT算法被部署在一个潜在的对抗环境中时,性能可能会有相当大的差别。链通信特征协议展示的是它在对称和同质连接的LAN集群经过验证的最佳吞吐量,但这在其他的应用场景或非同质网络中可能会迅速降低。此外,在一个给定的部署中,一些外部因素,比如负载、网络参数、故障或者攻击随着时间变化可能会是多种多样的。由于以上原因,BFT算法应当天生可重构,理想情况下,甚至可以动态适应变化的环境。另一个重要的方面是,在一个给定的区块链部署方案中。共识算法可以去匹配算法的信任模型。实际上,希望取代BFT的算法以可选信任模型为基础,例如XFT,或是CFT协议,像是Pasxs/Raft和ZooKeeper,或是毋须准入机制的协议。
136 |
137 | ### 2.4顺序执行区块链的一些经验
138 | 在实现Fabric的排序-执行-验证架构之前,团队从其他建立在排序-执行模型下,使用PBFT共识算法的私有链平台中获取了一些经验。从一些概念性的应用的反馈来说,这种方式的局限性是十分明显的。例如,用户经常观测到节点上发散的状态然后反馈共识机制的漏洞,几乎所有情况下,深入的检测显示罪魁祸首都是那些非确定性的交易代码。其他的一些负面评论则是关于性能,例如,“一秒怎么只有五个交易被执行”,直到用户发现他们每一个交易平均花费200毫秒去执行。我们已经知道区块链系统的核心属性是一致性、安全性和高性能,而这些不能依赖于用户的知识或善意,因此区块链应当被运行在一个不可信的环境中。
139 |
140 | ## 3.架构
141 | 在这节中,我们将介绍有三个阶段的执行-排序-验证架构,随后解释交易流程。Fabric组件将会在下一节中讨论。
142 |
143 | ### 3.1 Fabric总览
144 | Fabric是一个在私有链上执行使用通用编程语言(例如Go,Java,Node.js)编写的分布式应用的分布式操作系统。它没有内置的加密货币,并能通过一个可追加的账本数据副本来安全地追踪交易记录。
145 |
146 | 基于上一节中提到的原因,Fabric推行排序-执行-验证的区块链架构而不是使用标准的排序-执行的设计。在一个极小的容器中,Fabric的分布式应用包含以下两个部分:
147 | * 智能合约,这里称作链码(chaincode),是一个实现了应用逻辑并在交易执行过程中运行的程序代码。链码是Fabric应用程序的核心部分,它可以被不可信的开发者编写。而那些用作管理区块链系统并保存一些参数的特殊链码,被称作系统链码。(4.6节)
148 | * 背书策略,在验证阶段中发挥作用。背书策略不能被那些不可信应用的开发者选择或是修改,这是系统的一部分。背书策略在Fabric的交易验证中扮演静态库的角色,它只能被链码参数化。只有那些指定的管理员可以去运行系统管理函数,或是修改背书策略。
149 |
150 | 常见的背书策略是让链码以节点集的形式指定一些为这笔交易背书的节点,这是背书过程所必需的。它使用集合的一些逻辑单调表达式,例如“五个中的三个”或是“A和B 或者 B和C”。自定义的背书策略可以实现任何逻辑,比如比特币类的加密货币。(5.1节)
151 |
152 | 客户根据背书策略将交易发送给指定的节点。然后交易被这些节点执行并记录结果,这个步骤就称作背书。执行结束后,交易将进入排序阶段,这时将会使用可插拔的共识算法在区块中产生一个所有已验证交易的全序。然后在通信组件的帮助下,它们被广播到所有的节点。与标准的主动副本把全部的交易输入都排序不同,Fabric将交易输出和执行阶段产生的状态结合并排序。接着,每个节点将根据背书策略和验证阶段产生的共识,来逐个验证那些经过背书的交易所产生的状态变化。所有节点将按照同样的顺序去验证交易,验证结果将是确定的。从这个意义上说,Fabric推行了一种全新的拜占庭模型下的混合副本范式,结合了被动复制(状态更新的预共识计算)和主动复制(执行结果和状态改变达成共识后验证)。
153 |
154 | 这个执行-排序-验证的架构如图2所示。
155 |
156 |
157 | 
158 |
159 |
160 |
161 | Fabric区块链包含节点集合组成的网络。由于Fabric拥有准入机制,所有的网络中的节点必须拥有身份,这个身份是由一个模块化的成员管理服务(MSP)提供的。Fabric网络中的物理节点有以下三个身份中的一种:
162 | * **客户节点**提交交易提案。帮助构建执行阶段,最后广播这些交易来完成排序。
163 | * **背书节点**执行交易提案并验证交易。同时,节点也负责保存区块链账本(一种可追加的数据结构,以哈希链的形式记录了所有的交易,也记录世界状态,这是一种对最新账本状态的简要记录)。并不是所有节点都执行全部的交易,只有一部分被这笔交易所属的背书策略选定的背书节点会这样做。但是,全部节点随后必须完成账本的更新。
164 | * **排序节点(OSN)**是排序服务中的节点。简而言之,Fabric的排序服务建立起所有交易的全序,每笔交易包含状态的更新和执行过程中计算得到的一些依赖,还包含那些用于计算的背书节点的加密签名。排序服务节点完全不知道应用的状态,也不参与进交易执行或是交易验证。这样设计是尽可能的将共识算法模块化并简化Fabric中替换共识算法的流程。
165 |
166 | 由于可以在一台物理节点上运行许多扮演不同角色的节点,Fabric同样可以像传统的点对点区块链系统一样运作(每个节点包含状态、交易调用、交易验证和交易排序)。这个Fabric使用不同类型节点的交易流程如图3所示。
167 |
168 |
169 | 
170 |
171 |
172 | 与迄今为止那些使用单一区块链的系统相比,Fabric网络实际上可以支持多条区块链连接到同一个排序服务上。每条这样的区块链叫做信道(channel),可能含有不同身份的成员节点。信道可以用来分隔区块链网络的状态,但是信道间的共识算法并不会做出相应调整,并且不同信道的交易全序也是不同的。对于特定部署而言,假如所有的排序节点都是可信任的,可以实现通过信道来访问控制节点。下文中我们提到信道时,只会简略地专注于单信道的情况。
173 |
174 | 下面的三节解释了Fabric的交易流程并阐明了执行、排序、验证的阶段。Fabric网络如图4所示。
175 |
176 | ### 3.2 执行阶段
177 |
178 | 在执行阶段中,客户向一个或多个背书节点发送交易提案。回想每个链码都通过背书策略隐式指定了一些背书节点。交易提案包括提交交易的客户身份(通过MSP获得)、执行操作形式的交易负载、参数、链码所有者的标识符、每个节点只用一次的现时标识(例如一个计数器或是一个随机数)和由链码标识符与现时标识生成的交易标识符。同样,客户还会对提案签名。
179 |
180 | 
181 |
182 | 背书节点通过在区块链上预安装的特定链码上执行操作来模拟交易提案。链码通过在Docker容器中运行,与背书进程相隔离。
183 |
184 | 模拟交易提案是为了在不与其他任何节点同步的情况下改变背书节点的本地区块链状态,此外,背书节点并不保存模拟交易后账本状态的改变。区块链的状态是以版本化控制的键值对形式储存在节点交易管理员(PTM)中的,这里会以单调递增的版本号来记录数据的一次次更新。(表4.4)链码创建的状态仅限于这个链码,并不能被其他链码直接访问。需要注意的是,链码不应该在程序代码中储存本地状态,只储存它可以被GetState,PutState和DelState这几个操作访问的区块链状态。在给予一定权限的情况下,同一信道内的链码可以调用另一个链码去访问自己的状态。
185 |
186 | 模拟交易会产生这样的结果:每个背书节点产生一个值的写入集(writeset),包括模拟导致的状态更新(比如修改过的key和他们新的value),还会产生一个读取集(readset),代表了交易提案模拟时的版本信息(比如所有的key在模拟中会通过他们的版本号读取数据)。模拟结束后,背书节点会加密生成一个叫做背书的信息,背书包含读取集和写入集(还有一些元数据例如交易ID,背书节点ID,背书节点的签名等),并把它们作为交易提案的回应发送回客户。客户节点会收集这些背书直到它们满足交易调用链码(见3.4节)的背书策略的要求。特别是,这就要求背书策略选取的所有节点对这笔交易必须产生相同的结果(例如相同的读取集和写入集)。接着,客户创建这笔交易并把它传递给排序服务。
187 |
188 | **对设计的一些讨论**
189 | 由于背书节点模拟交易提案时不与其他节点进行同步,两个背书节点可能会在不同账本状态下模拟交易然后产生了不同的结果。对于要求背书节点产生相同结果的标准背书策略而言,这意味着在对相同属性进行高竞争性访问操作时,客户也许不能满足背书策略的要求。与通过中间件来同步副本数据库的主备份方式比较时,这是一个全新的要素,根据这个假设自然得到这样的推论:区块链中交易的正确执行,不可信任任何单一节点。
190 |
191 | 我们采用了这个设计,是因为它相当大程度地简化了架构,而且对于传统的区块链应用来说非常合适。比特币的实验表明,分布式应用可以被公式化,因此对同一个属性的操作竞争可以被减少甚至完全避免(例如,比特币中,对同一个物品进行的2个修改操作是被禁止的,这叫做双花攻击)。
192 |
193 | 在排序阶段之前先执行交易,这对于允许第二节中所讨论的非确定性链码是至关重要的。Fabric中存在非确定性交易的链码只能对它自己产生威胁,例如,这个客户节点也许不能收集到足够的背书数量。由于顺序-执行架构中非确定性操作会导致节点状态产生矛盾,因此这在现实情景中远远比排序-执行架构更加合适,。
194 |
195 | 最后,一个背书节点的本地策略在怀疑有拒绝攻击(DoS)的可能性时可以很简单的终止交易执行,这使得Fabric可以解决不可信任的链码中那些非确定性操作可能进行拒绝攻击的问题。这将不会对系统的一致性产生威胁,与此相对,这种对某个执行单方终止的行为在排序-执行架构中也是不可能实现的。
196 |
197 | ### 3.3 排序阶段
198 |
199 | 当客户为一个交易提案收集到足够的背书时,它就会整合交易并提交给排序服务。交易信息包含了交易负载(例如,链码操作包含它需要的参数),交易元数据和一个背书集合。交易阶段中,排序节点会建立一个信道中所有被提交的交易的全序。换句话说,尽管可能会有错误的排序,排序节点依然会原子广播所有的背书并因此得以在这笔交易上建立共识。此外,排序服务会将多个交易在区块中打包并输出包含交易区块的哈希链。容错广播的一种常用方法是将交易组合或者是在不同区块中打包,这可以增加广播协议的吞吐量。
200 |
201 | 在上层应用中,排序服务的接口只支持两种操作。这些操作被节点调用并被一个信道标识符隐式地参数化:
202 | * broadcast(tx):客户调用这个操作把任意一个交易tx广播出去,为了传播给所有的节点,tx中还包括交易负载和客户签名。
203 | * B←deliver(s):客户调用这个操作使用一个非负数序列号s去找到区块B。这个区块包含一系列交易[tx1...txk]和一个哈希值h代表了序号是s-1的区块,例如,B=([tx1...txk],h)。客户可能会重复调用这个操作,只要区块有效返回值就是确定的,所以当节点通过第一次调用deliver(s)接收区块B时,之后依然可以通过s接收到B。
204 |
205 | 排序服务保证同一个信道上被提供的区块都是经过排序的。更确切地说,排序会保证每个信道上有以下的安全属性:
206 | * **一致性(单调性)**:对于任何两个区块,s提供的B和s'提供的B',如果s=s'那么B=B'。
207 | * **哈希链完整性**:当一个正确的节点通过序列号s返回了区块B而另一个正确的节点通过序列号s+1返回了B'=([tx1...txk],h'),那么h'=H(B)恒成立,H是加密哈希函数。
208 | * **无跳跃性**:如果正确的节点p通过s>0返回一个区块,那么在这之前,对于i=0,...,s-1,节点p已经通过i返回了对应区块。
209 | * **存在性**:当一个正确的节点通过序列号s返回了区块B,那么对于B中的每一笔交易,都已经被某个客户广播过了。
210 |
211 | 对于活性(liveness),排序服务支持至少以下的“最终”属性:
212 | * **合法性**:如果一个正确的客户调用了boardcast(tx),那么每个正确的节点最终都会通过某个序列号接收到包含交易tx的区块B。
213 | (附:在并行计算中,活性指并行系统的一些属性)
214 |
215 |
216 | 根据不同客户的需求,不同的排序服务允许使用自己的活性和公平性担保。
217 |
218 | 由于区块链网络中可能会有很多节点,但是只有很少一部分相关的节点实现排序服务,Fabric可以设置使用内置的通信组件把排序节点接收的区块分发给所有的节点(4.3节)。通信组件对于特定排序服务的实现是可扩展,而且它并不需要清楚具体应用的排序服务,因此它可以同CFT和BFT排序服务同时合作,来保证Fabric的模块化属性。
219 |
220 | 排序服务还可以执行访问权限检查来决定客户是否有权广播一些信息或是在给定信道上接收区块。这些以及其他排序服务的特性将会在4.2节更深入的讨论。
221 |
222 | **对设计的一些讨论**
223 | 排序服务不保存区块链的任何状态、验证和交易,这是十分重要的。这个架构对于Fabric来说是至关重要的决定性特征,使得Fabric成为第一个彻底分离了共识算法和交易、验证的区块链系统。这还使得共识算法模块化成为可能,并使得它在共识算法系统中实现了排序服务。
224 |
225 | ### 3.4 验证阶段
226 |
227 | 区块可以通过与排序服务直连或是通过传输协议被传递给节点。当新区块产生时,它会进入验证阶段,包括一下三个部分:
228 | * 1.背书策略的评估在一个区块中所有的交易同时运行时进行。评估是所谓验证系统链码(VSCC)的任务,它是区块链配置中的一个静态库,负责根据链码配置的相关背书策略来验证背书(4.6节)。如果不满足背书条件,交易会被标记为非法并撤销它造成的所有改变。
229 |
230 | * 2.所有交易的读写争议判定在区块中线性执行。对于每个交易,首先比较读取集和节点本地储存的当前账本状态中键的版本,保证它们是相同的。假如版本不匹配,交易会被标记为非法并撤销它造成的所有改变。
231 |
232 | * 3.最后是账本更新阶段,这时区块会被追加在本地储存的账本中,更新了区块链的状态。特别的是,当为账本追加区块时,前两步中的验证检查的结果还以位掩码的形式保留着,来指明区块中这些交易是有效的。随后这可以帮助重建账本状态。此外,状态更新都是通过将所有的键值对放进写入集添加到本地状态中来完成的。
233 |
234 | Fabric中默认的VSCC允许使用逻辑单调表达式去表示链码上的背书节点集。当交易背书的有效签名满足这个表达式时,VSCC评估就会验证通过这个节点集。不同的VSCC策略可以被静态设置。
235 |
236 | **对设计的一些讨论**
237 | Fabric账本包含了所有的交易,包括那些被认为是非法的。这是遵循了以上设计的结果,一方面因为排序服务是在不可知链码状态的情况下生成了区块链,另一方面则是因为验证过程是节点在达成共识后完成的。这个特性是在一些特定用途中所需的,比如有些时候需要在审计中追踪非法交易,这与只保存有效交易的其他区块链形成对比(例如比特币和以太坊)。
238 |
239 | 
240 |
241 | ## 4.Fabric组件
242 |
243 | Fabric是用Go语言编写的,并为客户间、节点间和排序服务节点间的信息沟通使用了gRPC框架。接下来我们会更细节地讲述一些重要的组件。图5显示了一个节点的组成部分。
244 |
245 | ### 4.1 成员管理服务
246 |
247 | 成员管理服务(MSP)负责保存系统中所有物理节点的身份,包括客户,节点和排序服务节点,并负责为节点发布认证和授权时需要的凭证。因为Fabric拥有准入机制,因此所有节点间通过信息传递的相互影响都是要经过验证的,通常是以数字签名的方式进行验证。成员管理服务由每个节点的部分组件组成,可以验证交易、检验交易完整性、签署背书、验证背书和核验其他的区块链操作。那些管理键和负责注册节点的工具也是MSP的一部分。
248 |
249 | MSP可以是不同执行实体的抽象。Fabric中默认的MSP的实现中基于数字签名处理了标准的PKI方法来实现验证,并能容纳商业的证书颁发机构(CAs)。Fabric还提供独立的CA,叫做Fabric-CA。此外,还设计了可选择的MSP实现,例如一种依赖匿名证书而不是连接节点身份来验证节点调用交易的实现方式。
250 |
251 | Fabric允许设置两种区块链网络的模式。离线模式中,CA会生成证书并通过不同频率分发给所有节点。节点和排序服务节点只能在离线模式下注册。登记用户时,Fabric-CA提供了离线模式来给它们发行加密证书。MSP的配置必须保证所有的物理节点(node),尤其是节点(peer)要能够识别相同的身份和认证。
252 |
253 | MSP允许身份联盟的存在,例如,当多个组织操纵一个区块链网络时,每个组织会发布它的成员的身份然后每个节点去识别所有组织的成员。使用多重MSP实体可以做到这一点,例如,在每个组织和MSP之间创建一个映射。
254 |
255 | ### 4.2 排序服务
256 |
257 | 排序服务管理多个信道。在每个信道上,会提供以下服务;
258 |
259 | * 1.**原子广播**实现了broadcast和deliver的方法调用,在所有的交易中建立排序。
260 |
261 | * 2.信道的**重新配置**,当信道的成员通过广播一个配置交易来更新配置。
262 |
263 | * 3.可选地,**访问限制**,是在那些排序服务扮演可信任实体的配置中,限制特定节点和客户广播交易和接收区块。
264 |
265 | 排序服务是在系统信道上通过创世区块自己生成的。这个区块携带定义了排序服务属性的交易配置。
266 |
267 | 当前的产品实现包括实现了以上操作并通过系统信道通信的排序服务节点(OSNs)。实际上,原子广播是通过基于ZooKeeper的Apache Kafka完成的。Apache Kafka提供了可扩展的发布-订阅通知,在节点崩溃情况下依然可以保持强一致性。Kafka可以在于OSNs分离出的物理节点上运行。OSNs在节点和Kafka间扮演代理服务器的角色。
268 |
269 | 一个OSN可以直接向原子广播(例如Kafka broker)中注入一个新接收到的交易。从另一方面说,节点会中打包从原子广播中接收到的交易并组建区块。一个区块在满足以下任意一个条件时立刻被切分:
270 |
271 | * 1.区块包含交易数达到上限
272 |
273 | * 2.区块在字节内存上已经达到上限
274 |
275 | * 3.距离接收新区块的第一个交易的时间点,交易已经超时
276 |
277 | 打包是确定性的,因此在所有节点上会产生相同的区块。给定从原子广播获取的交易流,以上所说的前两个条件很明显是确定性的。为了保证区块链在第三种情况中的确定性,节点会在它读取原子广播中的区块中的第一笔交易时打开一个计时器。如果计时器过期时区块仍没有被结束,节点会向信道广播一个特殊的带有中断信号的交易,交易指出了需要终止的区块的序列号。从另一方面说,节点在接收到带有中断信号的交易时会立刻根据序列号终结这个区块。由于交易被原子广播到了所有连接的节点,它们的这个区块中都包含了相同的交易列表。(在当前的总量为f的拜占庭容错OSNs中部署这个方案时,只有当接收到f+1个带有中断信号的交易时才会终结区块)
278 |
279 | 排序节点会直接在文件系统中保留一些最近接收到的区块,因此他们可以通过调用deliver恢复区块并回应给其他节点。
280 |
281 | 排序节点使用的Kafka是三种当前可行的排序服务方案之一。中心排序服务节点叫做Solo,在一个节点上运行并被用作部署。概念性的基于BFT-SMaRt的排序节点也是一种可行的方案,它能确保原子广播服务但现在还不能重新配置和控制访问。这也突出了Fabric共识算法的模块化特性。
282 |
283 | ### 4.3 通信组件
284 |
285 | 分离执行、排序、验证阶段的好处之一是它们可以被独立地延展。然而,由于大多数的共识算法(CFT和BFT模型)都有带宽约束,排序服务的吞吐量上限由节点的网络状况决定。共识算法并不能通过增加更多的节点来延展,因为这样将会降低吞吐量。然而,由于解耦了排序和验证阶段,在排序阶段后,我们对如何高效地向节点广播交易执行结果来进行验证更感兴趣。这就是通信组件最重要的目标,为了达成这一目标它使用了蔓延组播(epidemic multicast)。区块都是被排序服务节点签署的,意味着任何一个节点可以通过接收所有的区块,独立的组装一个区块链并验证其完整性。
286 |
287 | Fabric网络通过通信组件散布信息是非常健壮的并且对节点错误具有抵抗力,这与覆盖(应用层)网络(overlay networks)形成对比。随机选择节点可以让通信组件减少维持节点间联系的开销,此外,还减少了攻击面。通信组件在有准入机制的环境中运行地非常好,可以经受住女巫攻击(sybil attack)和信息伪造(message forgery)。
288 |
289 | 通信组件的通讯层是基于gRPC的,并且通过彼此验证利用了TLS协议,这让每一边都可以将TLS证书绑定到远程节点的身份。通信组件保存了实时更新的系统中所有在线节点的成员管理视图。所有的节点都独立的通过周期性散布成员数据来建立一个本地的视图。此外,在发生网络中断或是崩溃后,节点可以重连到视图。
290 |
291 | 通信组件的主要目的是可靠地分发数据,例如,排序阶段生成的区块在节点间使用了push-pull协议。它通过两个阶段进行信息分发:在push阶段,每个节点从成员视图中随机选择它的邻居们,然后向它们传递消息。在pull节点,每个节点周期性地搜索随机选择的节点请求丢失的消息。在[15,22]中显示,将这两种方法串联起来,可以最好地使用可用带宽并且保证所有的节点大概率可以接收到所有信息。
292 |
293 | 为了减少从排序节点向网络发送区块的负载,通信协议还会选举出一个领导节点代表其他节点从排序节点拉取区块并初始化通信组件。这个机制对于领导节点发送错误是有弹性的。
294 |
295 | 通信组件的另一个任务是将区块链的状态传递给新加入的节点,这个节点可能已经失联很长时间了。它们需要去接收区块链的所有区块。这个特性依赖于通过成员网络最长区块链的长度已经被分发给了所有的节点并储存。
296 |
297 | ### 4.4 账本
298 |
299 | 每个节点的账本组件长期储存了账本和区块链的数据,并且启动了模拟、验证和账本更新的过程。大体上,它包括了区块的储存和节点交易管理员(PTM)。
300 |
301 | * **账本区块储存**
302 | 账本区块仓库长期储存交易区块的数据,它是以一个可追加集合的形式实现的。由于区块是不可变的并且以恒定的顺序进入,这种可追加的结构能够发挥它最大的性能。另外,区块仓库会储存一些指向随机区块或者是区块中的一个交易的索引。
303 |
304 | * **节点交易管理员(PTM)**
305 | PTM保存了版本化键值对数据库的最新状态。对于链码储存的每一个主键,它储存了一个(键,值,版本)形式的元祖,包含它最新的值val和最新的版本ver。版本包括区块的序列号和区块中这笔(保存了条目的)交易的序列号。这使得版本号是唯一的并且单调递增。
306 |
307 | PTM使用一个本地的键值对数据库来实现版本控制的键值对储存,常常使用Go语言编写的LevelDB或者是Apache CoachDB储存。
308 |
309 | 在模拟交易时,PTM提供一个最新交易状态的稳定快照。在3.2节中我们提到,对于每个GetState访问的条目,PTM从读取集中记录了一个(键,版本)的元祖。对于每个PutState访问的条目,PTM从写入集记录了(键,值)的元祖。另外,PTM支持范围查询,会根据查询结果计算一个加密的哈希值并将查询语句和哈希值添加到读取集。
310 |
311 | 对于交易验证(3.4节),PTM在区块中顺序验证所有的节点。这会检查这笔交易是否与先前的交易(同一个区块的或更早的交易)相矛盾。对于读取集的任意一个键,如果读取集中记录的版本与当前最新状态的版本不同(假设之前所有有效交易都已经被提交),那么PTM会将这笔交易标记为无效。对于范围查询,PTM会重复执行查询并比较它和读取集中的哈希值,保证没有幻影读取被执行。这个读写的矛盾将导致单副本可串行性。(待重译 to ensure that no phantom reads occur.This read-write conflict semantics results in one-copy serializability)。
312 |
313 | 账本组件允许节点在更新账本时发生崩溃。在接收到新区块后,通过使用3.4节中提到的位掩码,PTM执行验证并在区块中标记这笔交易是否有效。然后账本将区块添加到账本储存中,并写入硬盘,随后更新区块索引。然后PTM会将写入集中有效交易的状态更改到本地版本化储存中。最终,它会计算并保存一个值的回滚点,这里记录了已经成功应用的区块链的最大长度。这个回滚点用来在崩溃后重建时,从保存的区块中恢复索引和最新的状态。
314 |
315 | ### 4.5 链码执行
316 |
317 | 链码在一个由其他松散联结的节点组成的环境中执行,支持一些添加其他编程语言编写链码的插件。当前有三种语言支持编写链码:Go,Java,Node.js。
318 |
319 | 每个用户层或应用级链码在Docker容器环境的分离进程中运行,这将链码和其他链码以及节点隔离开。这也简化了管理链码的生命周期(例如,启动,停止,废弃链码)。链码和节点通过gRPC信息通讯。通过这种松散的联结,节点实际上无法知道链码实现是使用的是什么编程语言。
320 |
321 | 与应用链码相对,系统链码直接在节点进程里运行。系统链码可以实现Fabric所需的特定函数,可能被用于一些隔离链码是过度限制的场景。下一节将会详细解释系统链码。
322 |
323 | ### 4.6 配置和系统链码
324 |
325 | Fabric的基本行为是通过信道配置和特殊的链码(系统链码)来自定义的。
326 |
327 | * **信道配置**
328 | 回想信道可以组成逻辑上的区块链,特殊的配置区块可以保存了一些元数据来记录信道的配置。每个配置区块都包含一个完整的信道配置并且不包含任何其他的交易。每个区块链都会以一个配置区块开头,叫做创世区块,用来建立信道。这个信道配置包括:
329 |
330 | * 参与节点的MSPs的定义
331 | * OSNs的网络地址
332 | * 共识算法实现和排序服务的公有配置,例如打包区块的大小和超时限制。
333 | * 访问排序服务操作的规则(广播,接收)。
334 | * 信道配置如何进行修改的规则。
335 |
336 | 这些信道的配置可以用信道配置更新交易来更新。这种交易包括所有需要更改的配置和签名。排序服务节点通过使用当前的配置检验修改使用的签名是否经过验证,来评估这个更新是否有效。然后排序节点生成一个新的配置区块,其中嵌入了新的配置以及配置更新交易。节点接收到这个区块后,检验是否经过当前配置的验证,如果有效,它们就会更新现有的配置。
337 |
338 | * **系统链码**
339 | 应用链码通过背书系统链码(ESCC)和验证系统链码(VSCC)来部署。这两种链码以一种对称的方式被选择调用,因此ESCC的输出(背书)可能会被作为VSCC输入的一部分。
340 |
341 | ESCC的输入是一个交易提案和模拟执行的结果。如果结果满足条件,ESCC会产生一个回应,包括结果和背书。对于默认的ESCC而言,这个背书只是一个基于节点本地身份的签名。
342 |
343 | VSCC的输入是交易本身,输出则是交易是否有效。对于默认的VSCC而言,收集背书并与链码指定的背书策略校对,就能验证交易是否有效。
344 |
345 | 其他的系统链码有别的作用,比如配置和链码的生命周期。
346 |
347 | ## 5.评估
348 |
349 | 虽然现在Fabric还没有进行性能优化和改良,但我们在这节中还是会报告一些当前的性能数据。Fabric是一个复杂的分布式系统,它的性能依赖于很多参数,包括分布式应用的选择和交易的大小,排序服务和共识算法的实现以及它们的参数,网络参数和节点网络的拓扑,运行的硬件,节点和信道的数量,其他的配置参数,以及网络的动态变化。因此,Fabric性能的深度评测将会延期到将来进行。
350 |
351 | 因为没有一个标准的区块链测试的基准点,我们使用最重要的区块链应用来测试Fabric,一种简单的使用了比特币数据模型铸造的加密货币,我们叫做Fabric Coin(Fabcoin)。这让我们可以将Fabric的性能和其他有准入机制的区块链比较,这些区块链往往是从比特币或者以太坊中分离出来的,这个应用也常被其他私有链的作为测试基准点。
352 |
353 | 接下来,我们首先会介绍Fabcoin(5.1节),这里会介绍如何自定义验证阶段和背书策略。在5.2节我们会展示基准点并讨论结果。
354 |
355 | ### 5.1 Fabcoin
356 |
357 | * **UTXO 加密货币**
358 |
359 | 比特币推行的数据模型被概括地定义为“未花费的交易输出”或者UTXO,这也被许多其他的加密货币或者分布式应用采用。UTXO中,数据对象演化时的每个步骤都是账本上的一个分离的原子状态。一个被这笔交易创建的状态会被随后另一个发生的交易消费或是摧毁。每个给定的交易都会摧毁一定数量的输入状态并生成一个或更多的输出状态。比特币是被一个coinbase的交易初始化创建的,并被奖励给挖出这个区块的矿工。从账本上看,其实就是一个币更改了状态,将矿工视为所有者。从这个意义上讲,花掉一个币,其实就是将所有权从原先的所有者转让给了新的所有者并更新了币的状态。
360 |
361 | 我们描述了Fabric中的键值对储存的UTXO模型,如下所示。每个UTXO状态对应一个唯一的先前创立(币的状态是未被花费的),或是已经摧毁(币的状态是已经花费的)的KVS条目。等价地,在创建后,每个被视为KVS条目的状态的版本号从0开始计算,当它被摧毁时,接收了版本号为1的状态。对同一个条目不应该有两条并行的更新(这叫做双花攻击)。
362 |
363 | UTXO模型中的值通过交易被转换成发布交易的某个实体的输入状态。实体本身有自己的状态,因为实体的公钥包含在实体状态内部。每个交易在KVS中创建了一条或者多条输出状态,新的所有者删除了KVS中原先的输入状态,并确保输入值的总数和输出值的总数相等。这里同样有决定如何创造价值(例如,比特币中的coinbase交易或者其他系统中的铸币操作)和销毁(例如,交易所花费的费用)的策略。
364 |
365 | * **Fabcoin的实现**
366 |
367 | 每个Fabcoin的状态都是键值对形式的元祖,(key,val)=(txid.j,(amount,owner,label)),其中货币的状态是标识符为txid的交易的第j个输出,配置amount数量个单元并用标签(Label)把它们标记给公钥是所有者的实体。标签是用来确定货币类型的字符串(例如,USD EUR FBC)。交易标识符是一些短的值可以唯一的标识每个Fabric的交易。Fabcoin的实现包含下面三个部分:1.客户钱包 2.Fabcoin链码 3.Fabcoin自定义的VSCC,实现自己的背书策略。
368 |
369 |
370 | * **客户钱包**
371 |
372 | 默认情况下,每个Fabric客户有一个Fabcoin钱包,里面本地储存了一串加密密钥使得用户可以花费这些货币。当创建一个花费交易去转移一个或者更多的货币,客户钱包将创建一个Fabcoin请求 request = (inputs,outputs,sigs)包含了:1.输入货币的状态列表 inputs=[in,...]知道你过了客户希望花费的数量 2.输出货币的状态列表 outputs=[(amount,owner,label),...]
373 |
374 | 客户钱包使用对应输入状态的私钥签署Fabcoin请求的一系列事件和一个随机数,这是每个Fabric交易的一部分,并且将签名假如一个sigs集合中。对于一个消费交易来说,当输入值大于输出值并且输出值为正数时有效。对于铸币交易来说,输入只包括一个叫做中央银行(CB)的特殊实体的标识符(公钥的引用),输出可以是任意的货币状态。为了验证交易的有效性,sigs中铸币操作的签名必须是基于这一系列相关操作和CB的公钥的加密签名以及上文提到的随机数。Fabcoin可以使用多个CBs或者从一些CBs中指定一个签名阈值。最终,客户钱包囊括了Fabcoin对交易的请求并将它发送给了选择的节点。
375 |
376 | * **Fabcoin链码**
377 |
378 | 节点会运行Fabcoin的链码,这些链码模拟交易并创建读取集和写入集。在一个极小容器中,进行消费交易时,对于任意输入的货币状态in,链码首先执行GetState(in),这里会将in和它当前Fabric KVS(4.4节)的版本号放进读取集。然后链码对每个in执行DelState(in),这同样会将in添加进写入集并将这个货币状态标记为已花费。最终,对于j=1,...,|outputs|,链码执行PutState(txid,j,out),j代表outputs中第j个输出out = (amount,owner,label)。另外,节点可选择地运行交易验证代码,这将在下面Fabcoin中VSCC阶段中描述。这个操作并不是必要的,因为自定义的VSCC实际上会验证交易,但它允许正确的节点先筛选出可能出错的交易。在我们的实现中,链码毋须加密验证加密就可以运行Fabcoin的VSCC。
379 |
380 | * **自定义VSCC**
381 |
382 | 最终,每个节点使用自定义VSCC验证了Fabcoin交易。首先根据对应密钥验证了sigs中加密签名并执行下面的验证操作。对于铸币交易而言,它会检查创建的输出状态中,是否匹配正确的交易标识符(txid)和输出是否都是正数。对于消费交易而言,VSCC额外验证:
383 | * 对于所有的输入货币状态,条目已经在读取集创建并且被添加到了写入集而且标记为已删除。
384 | * 所有的输入之和与输出之和相等
385 | * 输出和输出的货币标签匹配
386 |
387 | 这里VSCC通过从账本恢复当前的值来获取输入货币的数量。
388 |
389 | 注意Fabcoin的VSCC不会检查双花攻击,因为双花攻击是通过Fabric的标准验证追踪自定义VSCC时产生的。特别地,如果两笔交易尝试将同一笔未花费的货币转让给新的所有者,它们都会经过VSCC逻辑验证但随后会被PTM在读写集矛盾检查时发现。根据3.4节和4,4节,PTM会验证当前账本和读取集中的版本号是否匹配,因此在第一个交易以及改变了货币的版本号后,第二笔交易会被认为非法。
390 |
391 | ### 5.2 实验
392 |
393 | **设置**
394 | 除非显式说明,在我们的试验中:
395 | * 1.节点在Fabric v1.1-preview上运行通过本地登录进行性能测试。
396 | * 2.节点被寄存在一个的IBM云(SoftLayer)数据中心,这是1Gbps的专用的虚拟机网络。
397 | * 3.所有的节点都使用2.0GHz 16-vCPU的虚拟机,使用Ubuntu系统,拥有8G内存以及SSD作为本地硬盘。
398 | * 4.使用3个ZooKeeper节点,4个Kafka brokers和3个Fabric 排序节点在不同的虚拟机上运行单信道排序服务。
399 | * 5.一共有五个节点,全部都是Fabcoin的背书节点。
400 | * 6.签名使用默认的256位ECDSA策略。
401 |
402 | 为了衡量和展现多节点交易流程中的延迟,实验中节点的时钟使用NTP服务进行同步。所有Fabric节点间的通信被配置为使用TLS。
403 |
404 | **方法论**
405 | 在每个实验中,第一步我们调用只含有Fabcoin铸币操作的交易区产生货币,然后第二步调用消费操作的交易去花费先前产生的货币。(单输入,单输出的交易)。当报告吞吐量的测量时,我们使用递增数目的Fabric CLI客户(修改用作发布并行请求)在同一个虚拟机上运行,直到端到端吞吐量达到饱和,以及记录达到饱和前的吞吐量的状态。吞吐量的数量会使用实验迭代中的平均值,不考虑实验的最差情况,因为这时一些客户端已经完成了提交交易。每项试验中,客户端提交至少500k个铸币和消费请求。
406 |
407 | **选择区块大小**
408 | 一个有争议的Fabric配置参数是吞吐量和延迟就是区块大小。为了在随后的实验中固定区块大小并且评估区块大小对性能的影响,我们将测试从0.5MB到4MB大小的区块。结果如图6所示,显示了吞吐量峰值和对应平均端到端延迟的关系。
409 |
410 | 
411 |
412 |
413 | 我们可以观察到,吞吐量在区块大小超过2MB后并不会显著的提升,但是延迟变得更糟(符合预期)。因此,我们采用2MB作为接下来实验所使用的区块大小,去测量吞吐量的最大值,并假定端到端延迟在500ms是可接受的。
414 |
415 | **交易大小**
416 | 在实验中,我们同样观察铸币和消费交易区块的大小。特别是,当2MB区块包含了473个铸币交易和670个消费交易时,消费交易平均大小是3.06kB,铸币交易平均大小是4.33kB。通常来说,Fabric的交易比较大因为它们携带了证书信息。另外,Fabcoin的铸币交易比消费交易大是因为他们携带了CB证书。这都是将来Fabric和Fabcoin可以改良的地方。
417 |
418 | * **节点CPU的影响**
419 | Fabric节点会运行许多集中在CPU上进行的加密操作。为了测试CPU对于吞吐量的影响,我们执行了一系列分别在4,8,16,32 vCPU的虚拟机上运行4节点的情况,同时为了更好的确认瓶颈,将粗糙地展示区块验证延迟。我们的实验专注于验证阶段,因为Kafka排序服务在我们的实验中从来没有遇到瓶颈。验证阶段,特别是Fabcoin的VSCC验证,由于许多数字签名验证在这个阶段执行的,因此是集中化计算的。
420 |
421 |
422 | 
423 |
424 |
425 | 2MB的区块的结果在图7中显示。但消费交易延迟没有在图7中显示,因为它与铸币交易的延迟规模相似。我们可以观察到Fabcoin VSCC验证与CPU成线性关系,因为Fabric VSCC验证是尴尬地并行运行。然而,读写检查和账本访问阶段都是线性的,因此CPU的核心数成为了主导因素。这显示将来版本的Fabric可以从验证阶段的传递途径(现在是线性的)来改良性能,还可以优化稳态储存的访问,还可以并行进行读写依赖检查。
426 |
427 | 最终,在这个实验中,在32-vCPU节点上,我们测试了每秒超过3560笔交易的吞吐量。一般来说,铸币吞吐量稍低于消费交易吞吐量,但是差别在10%以内。
428 |
429 |
430 | 
431 |
432 |
433 | * **阶段性剖析延迟**
434 | 在先前吞吐量峰值的实验中,我们还进行了粗糙地延迟分析。结果在表1中显示.排序阶段包括广播-接收的延迟和验证开始前节点的内部延迟。表中显示了铸币和消费交易的平均延迟,标准差和尾延迟(99%和99.9%)。
435 |
436 | 我们可以观察到排序是总延迟的主要因素。我们还观察到在次秒级尾延迟的情况下,平均延迟低于550ms。特别是,实验中最高的端到端延迟来自第一个区块建立负载的时候。低负载的延迟可以通过利用排序服务的超时打包参数(3.3节)去校准和减少,而这我们没有在实验中使用,因为我们已经将它设置为了一个很大的值。
437 |
438 | * **SSD vs. RAM disk**
439 | 为了评估使用本地SSD进行稳态储存的开销,我们在所有的节点虚拟机上使用RAM disks(tmpfs)重复了先前的实验。优化并不明显,因为tmpfs只能帮助改善节点上的账本验证阶段。我们测试到在32-vCPU节点上进行消费交易的峰值是3870tps,仅仅比SSD高了9%。
440 |
441 |
442 | ## 6.相关工作
443 |
444 | Fabric的架构和Kemme或Alonso这样的中间件副本数据库很相似。然而,这些现存的产品只能处理崩溃错误,并没有将对应BFT系统的分布式信任加入进去。例如,一个非对称更新的副本数据库依赖于节点去执行全部操作,而这在区块链上是不可行的。Fabric的排序-执行-验证架构可以被解释为这些产品的实际应用分布式账本的拜占庭模型的延伸版本。
445 |
446 | 从BFT数据库副本的角度来看,Byzantium和HRDB是Fabric的两个前身。Byzantium允许交易并行运行并使用主动复制,但是完全使用BFT中间件对BEGIN和COMMIT/ROLLBACK进行排序。在它的改良版本中,操作是可以被主副本调整的。如果主副本被怀疑是Byzantine,那么所有的副本会对主副本执行交易并触发一个花费巨大的协议去更换主副本。与Fabric对比,这两个系统都使用了主动复制。然而,他们的数据库API比Fabric的KVS模型要丰富的多。
447 |
448 | Eve,是一个也扩展使用BFT模型的SMR相关架构。它的节点并行执行交易并且当他们都输出相同的结果时验证交易。如果产生分叉,就会回滚并线性执行。Eve包括独立执行的元素,同样在Fabric中也存在,但是并没有给予它其他的特性。
449 |
450 | 最近很多基于私有链分布式账本平台发布,我们不可能去把它们全部比较一遍(许多重要的平台比如Tendermint,Quorum,Chain Core,Multichain,HyperLedger Sawtooth,Volt proposal,还有很多。)所有的这些平台都遵循排序-执行架构,这在第二节中已经讨论过。作为一个有代表性的例子,Quorum,一个以太坊的企业级版本。它的共识算法基于Raft,利用通信组件将交易分发给所有节点,Raft Leader(minter)会整合有效交易并写入区块,然后利用Raft分发消息。所有的节点会按照minter决定的顺序只想你个交易。因此会受到我们在1.2节中提到的局限性的限制。
451 |
452 |
453 | ## 参考文献
454 |
455 | [1] P.-L. Aublin, R. Guerraoui, N. Kneˇzevi´c, V. Qu´ema, and M. Vukoli´c. The next 700 BFT protocols. ACM Trans. Comput. Syst., 32(4):12:1–12:45, Jan. 2015.
456 |
457 | [2] E. Ben-Sasson, A. Chiesa, C. Garman, M. Green, I. Miers, E.Tromer,andM.Virza. Zerocash:Decentralizedanonymous payments from bitcoin. In IEEE Symposium on Security & Privacy, pages 459–474, 2014.
458 |
459 | [3] A. N. Bessani, J. Sousa, and E. A. P. Alchieri. State machine replication for the masses with BFT-SMART. In InternationalConferenceonDependableSystemsandNetworks (DSN), pages 355–362, 2014.
460 |
461 | [4] G.BrachaandS.Toueg. Asynchronousconsensusandbroadcast protocols. J. ACM, 32(4):824–840, 1985.
462 |
463 | [5] E.Buchman. Tendermint:Byzantinefaulttoleranceintheage of blockchains. M.Sc. Thesis, University of Guelph, Canada, June 2016.
464 |
465 | [6] N.Budhiraja,K.Marzullo,F.B.Schneider,andS.Toueg. The primary-backupapproach.InS.Mullender,editor,Distributed Systems (2nd Ed.), pages 199–216. ACM Press/AddisonWesley, 1993.
466 |
467 | [7] C.Cachin,R.Guerraoui,andL.E.T.Rodrigues. Introduction to Reliable and Secure Distributed Programming (2. ed.). Springer, 2011.
468 |
469 | [8] C. Cachin, S. Schubert, and M. Vukoli´c. Non-determinism in byzantine fault-tolerant replication. In 20th International Conference on Principles of Distributed Systems (OPODIS), 2016.
470 |
471 | [9] C. Cachin and M. Vukoli´c. Blockchain consensus protocols in the wild. In A. W. Richa, editor, 31st Intl. Symposium on Distributed Computing (DISC 2017), pages 1:1–1:16, 2017.
472 |
473 | [10] J. Camenisch and E. V. Herreweghen. Design and implementation of the idemix anonymous credential system. In ACMConferenceonComputerandCommunicationsSecurity (CCS), pages 21–30, 2002.
474 |
475 | [11] M. Castro and B. Liskov. Practical Byzantine fault tolerance and proactive recovery. ACM Trans. Comput. Syst., 20(4):398–461, Nov. 2002.
476 |
477 | [12] Chain. Chain protocol whitepaper. https://chain.com/ docs/1.2/protocol/papers/whitepaper, 2017.
478 |
479 | [13] B. Charron-Bost, F. Pedone, and A. Schiper, editors. Replication: Theory and Practice, volume 5959 of Lecture Notes in Computer Science. Springer, 2010.
480 | 14 2018/2/1
481 |
482 |
483 | [14] K. Croman, C. Decker, I. Eyal, A. E. Gencer, A. Juels, A. Kosba, A. Miller, P. Saxena, E. Shi, E. G. Sirer, et al. On scaling decentralized blockchains. In International Conference on Financial Cryptography and Data Security (FC), pages 106–125. Springer, 2016.
484 |
485 | [15] A. Demers, D. Greene, C. Hauser, W. Irish, J. Larson, S. Shenker, H. Sturgis, D. Swinehart, and D. Terry. Epidemic algorithms for replicated database maintenance. In ACM Symposium on Principles of Distributed Computing (PODC), pages 1–12. ACM, 1987.
486 |
487 | [16] T. T. A. Dinh, R. Liu, M. Zhang, G. Chen, B. C. Ooi, and J. Wang. Untangling blockchain: A data processing view of blockchain systems. e-print, arXiv:1708.05665 [cs.DB], 2017.
488 |
489 | [17] R. Garcia, R. Rodrigues, and N. M. Preguic¸a. Efficient middleware for Byzantine fault tolerant database replication. In European Conference on Computer Systems (EuroSys), pages 107–122, 2011.
490 |
491 | [18] R.Guerraoui,R.R.Levy,B.Pochon,andV.Qu´ema.Throughput optimal total order broadcast for cluster environments. ACM Trans. Comput. Syst., 28(2):5:1–5:32, 2010.
492 |
493 | [19] J. P. Morgan. Quorum whitepaper. https://github.com/ jpmorganchase/quorum-docs, 2016.
494 |
495 | [20] F. P. Junqueira, B. C. Reed, and M. Serafini. Zab: Highperformance broadcast for primary-backup systems. In International Conference on Dependable Systems & Networks (DSN), pages 245–256, 2011.
496 |
497 | [21] M. Kapritsos, Y. Wang, V. Qu´ema, A. Clement, L. Alvisi, and M. Dahlin. All about Eve: Execute-verify replication for multi-core servers. In Symposium on Operating Systems Design and Implementation (OSDI), pages 237–250, 2012.
498 |
499 | [22] R. Karp, C. Schindelhauer, S. Shenker, and B. Vocking. Randomized rumor spreading. In Symposium on Foundations of Computer Science (FOCS), pages 565–574. IEEE, 2000.
500 |
501 | [23] B. Kemme. One-copy-serializability. In Encyclopedia of Database Systems, pages 1947–1948. Springer, 2009.
502 |
503 | [24] B. Kemme and G. Alonso. A new approach to developing and implementing eager database replication protocols. ACM Transactions on Database Systems, 25(3):333–379, 2000.
504 |
505 | [25] B. Kemme, R. Jim´enez-Peris, and M. Pati˜no-Mart´ınez. Database Replication. Synthesis Lectures on Data Management. Morgan & Claypool Publishers, 2010.
506 |
507 | [26] A. E. Kosba, A. Miller, E. Shi, Z. Wen, and C. Papamanthou. Hawk: The blockchain model of cryptography and privacypreserving smart contracts. In 37th IEEE Symposium on Security & Privacy, 2016.
508 |
509 | [27] S. Liu, P. Viotti, C. Cachin, V. Qu´ema, and M. Vukoli´c. XFT: practical fault tolerance beyond crashes. In Symposium on OperatingSystemsDesignandImplementation(OSDI),pages 485–500, 2016.
510 |
511 | [28] S. Nakamoto. Bitcoin: A peer-to-peer electronic cash system. http://www.bitcoin.org/bitcoin.pdf, 2009.
512 |
513 | [29] D. Ongaro and J. Ousterhout. In search of an understandable consensus algorithm. In USENIX Annual Technical Conference (ATC), pages 305–320, 2014.
514 |
515 | [30] F. Pedone and A. Schiper. Handling message semantics with Generic Broadcast protocols. Distributed Computing, 15(2):97–107, 2002.
516 |
517 | [31] F. B. Schneider. Implementing fault-tolerant services using the state machine approach: A tutorial. ACM Comput. Surv., 22(4):299–319, 1990.
518 |
519 | [32] S. Setty, S. Basu, L. Zhou, M. L. Roberts, and R. Venkatesan. Enabling secure and resource-efficient blockchain networks with VOLT. Technical Report MSR-TR-2017-38, Microsoft Research, 2017.
520 |
521 | [33] A.Singh,T.Das,P.Maniatis,P.Druschel,andT.Roscoe. BFT protocols under fire. In Symposium on Networked Systems Design & Implementation (NSDI), pages 189–204, 2008.
522 |
523 | [34] J. Sousa, A. Bessani, and M. Vukoli´c. A Byzantine faulttolerant ordering service for the Hyperledger Fabric blockchain platform. Technical Report arXiv:1709.06921, CoRR, 2017.
524 |
525 | [35] B. Vandiver, H. Balakrishnan, B. Liskov, and S. Madden. Tolerating Byzantine faults in transaction processing systems using commit barrier scheduling. In ACM Symposium on Operating Systems Principles (SOSP), pages 59–72, 2007.
526 |
527 | [36] M. Vukoli´c. The quest for scalable blockchain fabric: Proofof-work vs. BFT replication. In International Workshop on Open Problems in Network Security (iNetSec), pages 112– 125, 2015.
528 |
529 | [37] J.Yin,J.Martin,A.Venkataramani,L.Alvisi,andM.Dahlin. Separating agreement from execution for Byzantine fault tolerant services. In ACM Symposium on Operating Systems Principles (SOSP), pages 253–267, 2003.
530 |
--------------------------------------------------------------------------------