知乎专栏 | 多维度架构 |
目录
区块链技术发展至今,形成了公有链、联盟链和邦链三种种主流技术平台。
公有链:面向大众,用户可以匿名参与,非常方便,账本数据也公开,加上强大的智能合约,因此公有链极大地促进了区块链概念和技术的普及,比如比特币、Ethereum平台等。
联盟链:考虑到商业应用对安全、隐私、监管、审计、性能的需求,提高准入门槛,增加了安全、隐私、可监管审计等商业特性,是区块链技术在商业领域的应用探索。
邦链:暂时资料比较少。
概念
通道( Channel ):通道是构建在 Hyperledger Fabric 区块链网络上的私有区块链,实现了数据的隔离和保密。通道中的 Chaincode 和交易只有加入该通道的节点( Peer )可见。同一个节点可以加入多个通道,并为每个通道内容维护一个账本。每一个通道即为一条逻辑上的区块链。可以按照业务来划分通道,也可以按照行政职能和隐私策略来划分通道。
节点( Peer ): 维护账本的网络节点,通常区块链网络架构中存在多种角色,如 endorser 和 committer 。
排序服务或共识服务( Order Services ) : 提供排序服务或共识服务的网络节点,完成交易的排序和区块打包等工作,支持可插拔的共识组件,当前生产环境下使用 Kafka 进行交易排序。
分布式账本( Distribute Ledger ) :由网络中若干去中心化节点共同维护的数据账本。
组织( Org ) :联盟链中按照访问和使用账本的网络节点,一个联盟(或者一个区块链网络)有多个组织(成员),一个组织内可以有多个节点( Peer ),每个节点参与账本和世界状态维护。
智能合约( Smart Contract ):根据特定条件自动执行的合约程序。智能合约是区块链的重要特征,是用户与区块链进行交互,利用区块链实现业务逻辑的重要途径。
链码( Chaincode ):链码是 Hyperledger Fabric 对智能合约的一种实现方式,是运行于 Hyperledger Fabric 网络之上一段应用程序代码,也是用户与 Hyperledger Fabric 交互的唯一途径。
链( Chain ):一个链即是一个由若干区块通过特定指向链接、摘要算法或加密算法锚定组成的数据集合。
curl -s https://raw.githubusercontent.com/oscm/shell/master/virtualization/docker/docker.centos7.ce.sh | bash curl -s https://raw.githubusercontent.com/oscm/shell/master/virtualization/docker/registry-mirror.sh | bash or curl -fsSL https://get.docker.com/ | sh 创建2个docker网络,如下: docker network create fabric_noops docker network create fabric_pbft
安装 docker-compose
curl -s https://raw.githubusercontent.com/oscm/shell/master/virtualization/docker/docker-compose/docker-compose.sh | bash
运行后 hyperledger 相关镜像被安装到 Docker 中
cd /usr/local/src curl -s https://raw.githubusercontent.com/hyperledger/fabric/release/scripts/bootstrap-1.1.0.sh | bash
由于上面脚本会安装所有节点,速度较慢,作者建议你参考下一章节,手工安装所需最低配置节点。
对于开发环境,最小化的环境,包括 1 个 peer 节点、1 个 Orderer 节点、1 个 CA 节点。
准备一个服务器或者虚拟机,安装 CentOS 操作系统。
如果你是在已有的Docker上安装,建议你删除所有容器后在安装。以免出现冲突等情况。
docker stop $(docker ps -q) && docker rm $(docker ps -aq)
[root@localhost ~]# docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: netkiller Password: Login Succeeded
docker pull hyperledger/fabric-baseimage:latest \ && docker pull hyperledger/fabric-membersrvc:latest \ && docker pull hyperledger/fabric-peer:latest \ && docker pull hyperledger/fabric-orderer:latest \ && docker pull hyperledger/fabric-ca:latest \ && docker pull hyperledger/blockchain-explorer:latest
安装会出现下面问题
[root@localhost ~]# docker search fabric-peer | grep hyperledger/fabric-peer hyperledger/fabric-peer Fabric Peer docker image for Hyperledger Pro… 69 [root@localhost ~]# docker pull hyperledger/fabric-peer:latest Error response from daemon: manifest for hyperledger/fabric-peer:latest not found
可以 search 到的镜像 pull 不了,原因是 fabric-peer:latest,latest 不存在,你需要指定版本号。
docker pull hyperledger/fabric-ca:x86_64-1.1.0 \ && docker pull hyperledger/fabric-peer:x86_64-1.1.0 \ && docker pull hyperledger/fabric-orderer:x86_64-1.1.0 \ && docker pull hyperledger/fabric-couchdb:x86_64-1.1.0 \ && docker pull hyperledger/fabric-tools:x86_64-1.1.0 docker tag hyperledger/fabric-ca:x86_64-1.1.0 hyperledger/fabric-ca \ && docker tag hyperledger/fabric-peer:x86_64-1.1.0 hyperledger/fabric-peer \ && docker tag hyperledger/fabric-orderer:x86_64-1.1.0 hyperledger/fabric-orderer \ && docker tag hyperledger/fabric-couchdb:x86_64-1.1.0 hyperledger/fabric-couchdb \ && docker tag hyperledger/fabric-tools:x86_64-1.1.0 hyperledger/fabric-tools
查看镜像
[root@localhost src]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hyperledger/fabric-orderer latest 368c78b6f03b 2 months ago 151MB hyperledger/fabric-orderer x86_64-1.1.0 368c78b6f03b 2 months ago 151MB hyperledger/fabric-peer latest c2ab022f0bdb 2 months ago 154MB hyperledger/fabric-peer x86_64-1.1.0 c2ab022f0bdb 2 months ago 154MB hyperledger/fabric-membersrvc latest b3654d32e4f9 15 months ago 1.42GB
git config --global core.autocrlf false $ git clone https://github.com/hyperledger/fabric.git $ make docker $ git clone https://github.com/hyperledger/fabric-ca.git $ make docker cd fabric/devenv vagrant box add hyperledger/fabric-baseimage centos7.box vagrant up yum -y install epel-release yum -y install git yum -y install golang yum -y install python-pip pip install --upgrade backports.ssl_match_hostname pip install docker-compose docker-compose -version
体验 Hyperledger Fabric 在 https://github.com/hyperledger/fabric/tree/release/examples 下面有一些例子供用户学习。这里我选择的是 fabric-samples
这里我们最小化启动,需要四个节点,分别是 ca, peer, order, couchdb。
创建文件 docker-compose.yml
[root@localhost ~]# mkdir -p docker [root@localhost ~]# cd docker [root@localhost docker]# vim docker-compose.yml # # Copyright IBM Corp All Rights Reserved # # SPDX-License-Identifier: Apache-2.0 # version: '2' networks: basic: services: ca.example.com: image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_CA_NAME=ca.example.com - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/4239aa0dcd76daeeb8ba0cda701851d14504d31aad1b2ddddbac6a57365e497c_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start -b admin:adminpw -d' volumes: - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca.example.com networks: - basic orderer.example.com: container_name: orderer.example.com image: hyperledger/fabric-orderer environment: - ORDERER_GENERAL_LOGLEVEL=debug - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_GENESISMETHOD=file - ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer command: orderer ports: - 7050:7050 volumes: - ./config/:/etc/hyperledger/configtx - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/msp/orderer - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peerOrg1 networks: - basic peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer environment: - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_PEER_ID=peer0.org1.example.com - CORE_LOGGING_PEER=debug - CORE_CHAINCODE_LOGGING_LEVEL=DEBUG - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 # # the following setting starts chaincode containers on the same # # bridge network as the peers # # https://docs.docker.com/compose/networking/ - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_basic - CORE_LEDGER_STATE_STATEDATABASE=CouchDB - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984 # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD # provide the credentials for ledger to connect to CouchDB. The username and password must # match the username and password set for the associated CouchDB. - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= working_dir: /opt/gopath/src/github.com/hyperledger/fabric command: peer node start # command: peer node start --peer-chaincodedev=true ports: - 7051:7051 - 7053:7053 volumes: - /var/run/:/host/var/run/ - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/msp/peer - ./crypto-config/peerOrganizations/org1.example.com/users:/etc/hyperledger/msp/users - ./config:/etc/hyperledger/configtx depends_on: - orderer.example.com - couchdb networks: - basic couchdb: container_name: couchdb image: hyperledger/fabric-couchdb # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. environment: - COUCHDB_USER= - COUCHDB_PASSWORD= ports: - 5984:5984 networks: - basic cli: container_name: cli image: hyperledger/fabric-tools tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp - CORE_CHAINCODE_KEEPALIVE=10 working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: /bin/bash volumes: - /var/run/:/host/var/run/ - ./../chaincode/:/opt/gopath/src/github.com/ - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ networks: - basic #depends_on: # - orderer.example.com # - peer0.org1.example.com # - couchdb
启动 Docker
[root@localhost docker]# docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
查看进程
[root@localhost docker]# docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------------- ca.example.com sh -c fabric-ca-server sta ... Up 0.0.0.0:7054->7054/tcp cli /bin/bash Up couchdb tini -- /docker-entrypoint ... Up 4369/tcp, 0.0.0.0:5984->5984/tcp, 9100/tcp orderer.example.com orderer Up 0.0.0.0:7050->7050/tcp peer0.org1.example.com peer node start Up 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp
[root@localhost fabcar]# curl http://localhost:5984 {"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}}http://localhost:5984/_utils/
Hyperledger Fabric Channel 可以理解为 vlan (交换机术语) 用来实现区块隔离。
[root@localhost docker]# docker-compose exec peer0.org1.example.com bash root@dcb09db1cbc8:/go/src/github.com/hyperledger/fabric#
root@595ec455c0ff:/opt/gopath/src/github.com/hyperledger/fabric# peer channel list 2018-02-07 03:24:41.151 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-02-07 03:24:41.152 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-02-07 03:24:41.154 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized 2018-02-07 03:24:41.155 UTC [msp/identity] Sign -> DEBU 004 Sign: plaintext: 0A85070A5B08031A0B08F9E2E9D30510...631A0D0A0B4765744368616E6E656C73 2018-02-07 03:24:41.156 UTC [msp/identity] Sign -> DEBU 005 Sign: digest: 238CBAB61A0524954DC3C511588EB8FC1F886E636A8800131EBE16FB95FB0C9A 2018-02-07 03:24:41.167 UTC [channelCmd] list -> INFO 006 Channels peers has joined to: 2018-02-07 03:24:41.167 UTC [channelCmd] list -> INFO 007 mychannel 2018-02-07 03:24:41.167 UTC [main] main -> INFO 008 Exiting.....
CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/configtx/channel.tx
[root@localhost basic-network]# docker-compose exec cli bash root@b1ded848f967:/opt/gopath/src/github.com/hyperledger/fabric/peer#
安装合约
CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode install -n fabcar -v 1.0 -p github.com/fabcar
实例化合约
CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n fabcar -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
初始化合约
CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[""]}'
root@b1ded848f967:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"queryCar","Args":["CAR9"]}' 2018-02-07 05:11:59.737 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-02-07 05:11:59.737 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-02-07 05:11:59.738 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-02-07 05:11:59.738 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-02-07 05:11:59.738 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A93070A6908031A0C089F95EAD30510...0A0871756572794361720A0443415239 2018-02-07 05:11:59.739 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: 84E6F021BEA8C5F2D97B1C8BFEA4BB07B91DBC167E0BBD188260B234DC4620E8 Query Result: {"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"} 2018-02-07 05:11:59.771 UTC [main] main -> INFO 007 Exiting.....
调用合约,新增一条记录,然后做查询操作。
peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"createCar","Args":["CAR15", "Toyota", "Rezi", "White", "Neo"]}' peer chaincode query -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"queryCar","Args":["CAR15"]}'
演示结果
root@b1ded848f967:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"createCar","Args":["CAR15", "Toyota", "Rezi", "White", "Neo"]}' 2018-02-07 05:16:57.415 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-02-07 05:16:57.415 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-02-07 05:16:57.417 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-02-07 05:16:57.417 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-02-07 05:16:57.418 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A93070A6908031A0C08C997EAD30510...52657A690A0557686974650A034E656F 2018-02-07 05:16:57.418 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: D9BDF565353FFAD37CDC64DBFBD06DA8B5A049AA32305E1668A695E6522C3043 2018-02-07 05:16:57.443 UTC [msp/identity] Sign -> DEBU 007 Sign: plaintext: 0A93070A6908031A0C08C997EAD30510...4B5F674D96D8DE9BE699613B72ED46B1 2018-02-07 05:16:57.443 UTC [msp/identity] Sign -> DEBU 008 Sign: digest: 2951E3522A902D2644E08508E52A1D833AF9E11A420EE933851CC5673B005375 2018-02-07 05:16:57.451 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> DEBU 009 ESCC invoke result: version:1 response:<status:200 message:"OK" > payload:"\n \327\324\006\316\004\230\3262{\300\\|\275\035\336\243\316L\232\247x\020n`2\346\334\031\n(<\262\022\204\001\nn\022T\n\006fabcar\022J\032H\n\005CAR15\032?{\"make\":\"Toyota\",\"model\":\"Rezi\",\"colour\":\"White\",\"owner\":\"Neo\"}\022\026\n\004lscc\022\016\n\014\n\006fabcar\022\002\010\001\032\003\010\310\001\"\r\022\006fabcar\032\0031.0" endorsement:<endorser:"\n\007Org1MSP\022\200\006-----BEGIN -----\nMIICGjCCAcCgAwIBAgIRAPlwF/rUZUP9mqN4wSml4iswCgYIKoZIzj0EAwIwczEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\ncmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMTcwODMxMDkxNDMyWhcNMjcwODI5MDkxNDMy\nWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN\nU2FuIEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMS5leGFtcGxlLmNvbTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHihxW6ks3B2+5XdbAVq3CBgxRRRZ22x\nzzpqnD86nKkz7fBElBuhlXl2K6rTxyY2OBOB0ts8keqZ93xueRGymrajTTBLMA4G\nA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIEI5qg3Ndtru\nuLoM2nAYUdFFBNMarRst3dusalc2Xkl8MAoGCCqGSM49BAMCA0gAMEUCIQD4j0Rn\ne1rrd0FSCzsR6u+IuuPK5dI/kR/bh7+VLf0TNgIgCfUtkJvfvzVEwZLFoFyjoHtr\ntvwzNUS1U0hEqIaDeo4=\n-----END -----\n" signature:"0E\002!\000\364q\r\026\267\205\357\245\006\364\354v\333r92\022l\2267[Yb@F\263N\230\324\351.\025\002 \022K\275P\234\262A\3338\244\337\216\340q%-K_gM\226\330\336\233\346\231a;r\355F\261" > 2018-02-07 05:16:57.451 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00a Chaincode invoke successful. result: status:200 2018-02-07 05:16:57.451 UTC [main] main -> INFO 00b Exiting..... root@b1ded848f967:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"queryCar","Args":["CAR15"]}' 2018-02-07 05:17:07.383 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-02-07 05:17:07.383 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-02-07 05:17:07.383 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-02-07 05:17:07.383 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-02-07 05:17:07.384 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A93070A6908031A0C08D397EAD30510...0871756572794361720A054341523135 2018-02-07 05:17:07.384 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: FBFD595C716FB185BABBBD3709040F6D1538964931BA47A8B653E878C2084C4B Query Result: {"colour":"White","make":"Toyota","model":"Rezi","owner":"Neo"} 2018-02-07 05:17:07.411 UTC [main] main -> INFO 007 Exiting.....