知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
目錄
區塊鏈技術發展至今,形成了公有鏈、聯盟鏈和邦鏈三種種主流技術平台。
公有鏈:面向大眾,用戶可以匿名參與,非常方便,賬本數據也公開,加上強大的智能合約,因此公有鏈極大地促進了區塊鏈概念和技術的普及,比如比特幣、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.....