从0到1学习区块链-手动搭建部署Hyperledger Fabric区块链网络
1. 创建文件夹并进入文件夹内操作,这里以frstfabric为例
make firstfabric && cd frstfabric
2. 使用cryptogen工具创建配置文件,根据默认配置模板创建crypto-config.yaml文件
cryptogen showtemplate > crypto-config.yaml
3. 修改生成的默认模板配置文件crypto-config.yaml中的配置项EnableNodeOUs: true
# ---------------------------------------------------------------------------# "OrdererOrgs" - 管理排序节点的组织定义# ---------------------------------------------------------------------------OrdererOrgs: # --------------------------------------------------------------------------- # Orderer 定义Orderer组织结构 # --------------------------------------------------------------------------- - Name: Orderer # Orderer名称 Domain: example.com # 组织的域 EnableNodeOUs: true # 如果设置了EnableNodeOUs,就在msp下生成config.yaml文件 # --------------------------------------------------------------------------- # "Specs" - 参见下面的PeerOrgs以获得完整的描述 # --------------------------------------------------------------------------- Specs: - Hostname: orderer# ---------------------------------------------------------------------------# "PeerOrgs" - 管理对等节点的组织定义# ---------------------------------------------------------------------------PeerOrgs: # --------------------------------------------------------------------------- # Org1 组织1 # --------------------------------------------------------------------------- - Name: Org1 # 组织名称 Domain: org1.example.com # 组织域 EnableNodeOUs: true # 如果设置了EnableNodeOUs,就在msp下生成config.yaml文件 # --------------------------------------------------------------------------- # "CA" # ---------------------------------------------------------------------------# 取消注释此部分以启用此CA的显式定义# 组织。这个条目是一个规格,详细信息请参阅下面的“规格”部分。 # --------------------------------------------------------------------------- # CA: # Hostname: ca # implicitly ca.org1.example.com # Country: US # 国家 # Province: California # 省 # Locality: San Francisco # 位置 # OrganizationalUnit: Hyperledger Fabric # 组织 # StreetAddress: address for org # default nil # 街道地址,可以为空 # PostalCode: postalCode for org # default nil # 邮政编码,可以为空 # --------------------------------------------------------------------------- # "Specs" 规格 # ---------------------------------------------------------------------------#取消注释此部分以启用显式定义的主机配置,大多数用户都想使用下面的模板 # Specs是Spec条目的数组。每个Spec条目包含两个字段: # - Hostname: (必选)需要的主机名,没有域。 # - CommonName: (可选)指定CN的模板或显式覆盖。 # 默认情况下,这是模板: # # "{{.Hostname}}.{{.Domain}}" ## 它分别从Spec.Hostname和Org获取其值和域。 # - SANS: (可选)指定要在结果x509中设置的一个或多个Subject Alternative Names。 # 接受模板变量 {{.Hostname}}, {{.Domain}}, {{.CommonName}}。 # 此处提供的IP地址将被正确识别。 # 其他值将作为DNS名称。 # 注意:为您创建了两个隐式条目: # - {{ .CommonName }} # - {{ .Hostname }} # --------------------------------------------------------------------------- # Specs: # - Hostname: foo # implicitly "foo.org1.example.com" # CommonName: foo27.org5.example.com # 覆盖上面设置的基于主机名的FQDN # SANS: # - "bar.{{.Domain}}" # - "altfoo.{{.Domain}}" # - "{{.Hostname}}.org6.net" # - 172.16.10.31 # - Hostname: bar # - Hostname: baz # --------------------------------------------------------------------------- # "Template" # --------------------------------------------------------------------------- # 允许定义一个或多个从模板中顺序创建的主机。 # 默认情况下,这看起来像从0到Count-1的“peer%d”。 # 可以覆盖节点数(Count)、起始索引(Start)或用于构造名称(Hostname)的模板。 # # 注意:模板和规格不是互斥的。 # 您可以定义这两个部分,聚合节点将为您创建。 # 注意名称冲突 # --------------------------------------------------------------------------- Template: Count: 1 # 表示生成几个Peer # Start: 5 # Hostname: {{.Prefix}}{{.Index}} # default # SANS: # - "{{.Hostname}}.alt.{{.Domain}}" # --------------------------------------------------------------------------- # "Users" # --------------------------------------------------------------------------- # Count: 除Admin外的用户帐号数;普通User # --------------------------------------------------------------------------- Users: Count: 1 # --------------------------------------------------------------------------- # Org2: 有关完整规范,请参考“Org1” # --------------------------------------------------------------------------- - Name: Org2 Domain: org2.example.com EnableNodeOUs: true Template: Count: 1 Users: Count: 1
4. 使用cryptogen工具指定修改后的配置crypto-config.yaml文件,生成密钥材料
cryptogen generate --config=crypto-config.yaml
5. 生成后,在当前项目的目录下会有一个新的crypto-config文件夹,里面包含了Orderer节点、Peer节点相关配置。
.├── ordererOrganizations│ └── example.com│ ├── ca│ │ ├── ca.example.com-cert.pem│ │ └── priv_sk│ ├── msp│ │ ├── admincerts│ │ ├── cacerts│ │ │ └── ca.example.com-cert.pem│ │ ├── config.yaml│ │ └── tlscacerts│ │ └── tlsca.example.com-cert.pem│ ├── orderers│ │ └── orderer.example.com│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ ├── keystore│ │ │ │ └── priv_sk│ │ │ ├── signcerts│ │ │ │ └── orderer.example.com-cert.pem│ │ │ └── tlscacerts│ │ │ └── tlsca.example.com-cert.pem│ │ └── tls│ │ ├── ca.crt│ │ ├── server.crt│ │ └── server.key│ ├── tlsca│ │ ├── priv_sk│ │ └── tlsca.example.com-cert.pem│ └── users│ └── Admin@example.com│ ├── msp│ │ ├── admincerts│ │ ├── cacerts│ │ │ └── ca.example.com-cert.pem│ │ ├── config.yaml│ │ ├── keystore│ │ │ └── priv_sk│ │ ├── signcerts│ │ │ └── Admin@example.com-cert.pem│ │ └── tlscacerts│ │ └── tlsca.example.com-cert.pem│ └── tls│ ├── ca.crt│ ├── client.crt│ └── client.key└── peerOrganizations ├── org1.example.com │ ├── ca │ │ ├── ca.org1.example.com-cert.pem │ │ └── priv_sk │ ├── msp │ │ ├── admincerts │ │ ├── cacerts │ │ │ └── ca.org1.example.com-cert.pem │ │ ├── config.yaml │ │ └── tlscacerts │ │ └── tlsca.org1.example.com-cert.pem │ ├── peers │ │ └── peer0.org1.example.com │ │ ├── msp │ │ │ ├── admincerts │ │ │ ├── cacerts │ │ │ │ └── ca.org1.example.com-cert.pem │ │ │ ├── config.yaml │ │ │ ├── keystore │ │ │ │ └── priv_sk │ │ │ ├── signcerts │ │ │ │ └── peer0.org1.example.com-cert.pem │ │ │ └── tlscacerts │ │ │ └── tlsca.org1.example.com-cert.pem │ │ └── tls │ │ ├── ca.crt │ │ ├── server.crt │ │ └── server.key │ ├── tlsca │ │ ├── priv_sk │ │ └── tlsca.org1.example.com-cert.pem │ └── users │ ├── Admin@org1.example.com │ │ ├── msp │ │ │ ├── admincerts │ │ │ ├── cacerts │ │ │ │ └── ca.org1.example.com-cert.pem │ │ │ ├── config.yaml │ │ │ ├── keystore │ │ │ │ └── priv_sk │ │ │ ├── signcerts │ │ │ │ └── Admin@org1.example.com-cert.pem │ │ │ └── tlscacerts │ │ │ └── tlsca.org1.example.com-cert.pem │ │ └── tls │ │ ├── ca.crt │ │ ├── client.crt │ │ └── client.key │ └── User1@org1.example.com │ ├── msp │ │ ├── admincerts │ │ ├── cacerts │ │ │ └── ca.org1.example.com-cert.pem │ │ ├── config.yaml │ │ ├── keystore │ │ │ └── priv_sk │ │ ├── signcerts │ │ │ └── User1@org1.example.com-cert.pem │ │ └── tlscacerts │ │ └── tlsca.org1.example.com-cert.pem │ └── tls │ ├── ca.crt │ ├── client.crt │ └── client.key └── org2.example.com ├── ca │ ├── ca.org2.example.com-cert.pem │ └── priv_sk ├── msp │ ├── admincerts │ ├── cacerts │ │ └── ca.org2.example.com-cert.pem │ ├── config.yaml │ └── tlscacerts │ └── tlsca.org2.example.com-cert.pem ├── peers │ └── peer0.org2.example.com │ ├── msp │ │ ├── admincerts │ │ ├── cacerts │ │ │ └── ca.org2.example.com-cert.pem │ │ ├── config.yaml │ │ ├── keystore │ │ │ └── priv_sk │ │ ├── signcerts │ │ │ └── peer0.org2.example.com-cert.pem │ │ └── tlscacerts │ │ └── tlsca.org2.example.com-cert.pem │ └── tls │ ├── ca.crt │ ├── server.crt │ └── server.key ├── tlsca │ ├── priv_sk │ └── tlsca.org2.example.com-cert.pem └── users ├── Admin@org2.example.com │ ├── msp │ │ ├── admincerts │ │ ├── cacerts │ │ │ └── ca.org2.example.com-cert.pem │ │ ├── config.yaml │ │ ├── keystore │ │ │ └── priv_sk │ │ ├── signcerts │ │ │ └── Admin@org2.example.com-cert.pem │ │ └── tlscacerts │ │ └── tlsca.org2.example.com-cert.pem │ └── tls │ ├── ca.crt │ ├── client.crt │ └── client.key └── User1@org2.example.com ├── msp │ ├── admincerts │ ├── cacerts │ │ └── ca.org2.example.com-cert.pem │ ├── config.yaml │ ├── keystore │ │ └── priv_sk │ ├── signcerts │ │ └── User1@org2.example.com-cert.pem │ └── tlscacerts │ └── tlsca.org2.example.com-cert.pem └── tls ├── ca.crt ├── client.crt └── client.key93 directories, 85 files
配置组织相关文件1. 打开测试网络测试配置文件(https://github.com/hyperledger/fabric-samples/blob/release-2.2/test-network/configtx/configtx.yaml)
2. 把配置文件下载到本地(configtx.yaml)
3. 修改配置文件(configtx.yaml)中的所有MSP相关的配置路径
# 修改前Organizations: - &OrdererOrg MSPDir: ../organizations/ordererOrganizations/example.com/msp - &Org1 MSPDir: ../organizations/peerOrganizations/org1.example.com/msp - &Org2 MSPDir: ../organizations/peerOrganizations/org2.example.com/msp
# 修改后Organizations: - &OrdererOrg MSPDir: crypto-config/ordererOrganizations/example.com/msp - &Org1 MSPDir: crypto-config/peerOrganizations/org1.example.com/msp - &Org2 MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
4. 修改配置文件(configtx.yaml)中的所有Raft证书相关的配置路径
# 修改前Orderer: &OrdererDefaults OrdererType: etcdraft Addresses: - orderer.example.com:7050 EtcdRaft: Consenters: - Host: orderer.example.com Port: 7050 ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
# 修改后Orderer: &OrdererDefaults OrdererType: etcdraft Addresses: - orderer.example.com:7050 EtcdRaft: Consenters: - Host: orderer.example.com Port: 7050 ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
5. 修改配置文件(configtx.yaml)分别在Org1和Org2下面添加,如果不添加将会出现错误:
Error on inspectChannelCreateTx: org 'Org1MSP' does not have any anchor peers defined
AnchorPeers:- Host: peer0.org1.example.comPort: 7051---AnchorPeers:- Host: peer0.org2.example.comPort: 9051
# 添加后Organizations: - &Org1 AnchorPeers: - Host: peer0.org1.example.com Port: 7051 - &Org2 AnchorPeers: - Host: peer0.org2.example.com Port: 9051
6. 配置后的完整configtx.yaml文件
Organizations: - &OrdererOrg Name: OrdererOrg ID: OrdererMSP # 修改 MSPDir: crypto-config/ordererOrganizations/example.com/msp Policies: Readers: Type: Signature Rule: "OR('OrdererMSP.member')" Writers: Type: Signature Rule: "OR('OrdererMSP.member')" Admins: Type: Signature Rule: "OR('OrdererMSP.admin')" OrdererEndpoints: - orderer.example.com:7050 - &Org1 Name: Org1MSP ID: Org1MSP # 修改 MSPDir: crypto-config/peerOrganizations/org1.example.com/msp Policies: Readers: Type: Signature Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" Writers: Type: Signature Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" Admins: Type: Signature Rule: "OR('Org1MSP.admin')" Endorsement: Type: Signature Rule: "OR('Org1MSP.peer')"# 新添加 AnchorPeers: - Host: peer0.org1.example.com Port: 7051 - &Org2 Name: Org2MSP ID: Org2MSP # 修改 MSPDir: crypto-config/peerOrganizations/org2.example.com/msp Policies: Readers: Type: Signature Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')" Writers: Type: Signature Rule: "OR('Org2MSP.admin', 'Org2MSP.client')" Admins: Type: Signature Rule: "OR('Org2MSP.admin')" Endorsement: Type: Signature Rule: "OR('Org2MSP.peer')"# 新添加 AnchorPeers: - Host: peer0.org2.example.com Port: 9051Capabilities: Channel: &ChannelCapabilities V2_0: true Orderer: &OrdererCapabilities V2_0: true Application: &ApplicationCapabilities V2_0: trueApplication: &ApplicationDefaults Organizations: Policies: Readers: Type: ImplicitMeta Rule: "ANY Readers" Writers: Type: ImplicitMeta Rule: "ANY Writers" Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" LifecycleEndorsement: Type: ImplicitMeta Rule: "MAJORITY Endorsement" Endorsement: Type: ImplicitMeta Rule: "MAJORITY Endorsement" Capabilities: <<: *ApplicationCapabilitiesOrderer: &OrdererDefaults OrdererType: etcdraft Addresses: - orderer.example.com:7050# 修改ClientTLSCert,ServerTLSCert EtcdRaft: Consenters: - Host: orderer.example.com Port: 7050 ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt BatchTimeout: 2s BatchSize: MaxMessageCount: 10 AbsoluteMaxBytes: 99 MB PreferredMaxBytes: 512 KB Organizations: Policies: Readers: Type: ImplicitMeta Rule: "ANY Readers" Writers: Type: ImplicitMeta Rule: "ANY Writers" Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" BlockValidation: Type: ImplicitMeta Rule: "ANY Writers"Channel: &ChannelDefaults Policies: Readers: Type: ImplicitMeta Rule: "ANY Readers" Writers: Type: ImplicitMeta Rule: "ANY Writers" Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" Capabilities: <<: *ChannelCapabilitiesProfiles: TwoOrgsOrdererGenesis: <<: *ChannelDefaults Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Capabilities: <<: *OrdererCapabilities Consortiums: SampleConsortium: Organizations: - *Org1 - *Org2 TwoOrgsChannel: Consortium: SampleConsortium <<: *ChannelDefaults Application: <<: *ApplicationDefaults Organizations: - *Org1 - *Org2 Capabilities: <<: *ApplicationCapabilities
生成创世区块、通道、锚节点相关文件1. 使用configtxgen工具生成创世块文件;生成创世块的ChannelID要与后面的不同
configtxgen -profile TwoOrgsOrdererGenesis \-outputBlock ./channel-artifacts/genesis.block \-channelID fabric-channel
2. 使用configtxgen工具生成通道文件
configtxgen -profile TwoOrgsChannel \-outputCreateChannelTx ./channel-artifacts/channel.tx \-channelID mychannel
3. 使用configtxgen工具生成相关组织的锚节点文件;创建一个更新锚节点的配置更新(仅在默认通道创建时有效,并仅用于第一次更新)
# 生成组织1锚节点文件configtxgen -profile TwoOrgsChannel \-outputAnchorPeersUpdate ./channel-artifacts/org1MSPanchors.tx \-channelID mychannel -asOrg Org1MSP# 生成组织2锚节点文件configtxgen -profile TwoOrgsChannel \-outputAnchorPeersUpdate ./channel-artifacts/org2MSPanchors.tx \-channelID mychannel -asOrg Org2MSP
配置并创建peer节点1. 打开测试网络docker-compose-test-net.yaml文件(https://github.com/hyperledger/fabric-samples/blob/release-2.2/test-network/docker/docker-compose-test-net.yaml)
2. 把配置文件下载到本地(docker-compose-test-net.yaml)改名为docker-compose.yaml
3. 修改配置文件(docker-compose.yaml)中image的tag(版本号为:2.2)
# 修改前image: hyperledger/fabric-orderer:latestimage: hyperledger/fabric-peer:latestimage: hyperledger/fabric-tools:latest# 修改后image: hyperledger/fabric-orderer:2.2image: hyperledger/fabric-peer:2.2image: hyperledger/fabric-tools:2.2修改配置文件(docker-compose.yaml)中networks中的名称
4. 修改配置文件(docker-compose.yaml)中networks中的名称
# 修改前networks: test: name: fabric_test---peer0.org1.example.com:environment:- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test---peer0.org2.example.com:environment:- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test
# 修改后networks: test: name: firstfabric_test---peer0.org1.example.com:environment:- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=firstfabric_test---peer0.org2.example.com:environment:- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=firstfabric_test
5. 修改配置文件(docker-compose.yaml)中volumes中的映射地址
修改前services: orderer.example.com: volumes: - ../system-genesis-block/genesis.block:/var/hyperledger/orderer/orderer.genesis.block - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls - orderer.example.com:/var/hyperledger/production/orderer peer0.org1.example.com: volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org1.example.com:/var/hyperledger/production peer0.org2.example.com: volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org2.example.com:/var/hyperledger/production
# 修改后services: orderer.example.com: volumes: - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls - orderer.example.com:/var/hyperledger/production/orderer peer0.org1.example.com: volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org1.example.com:/var/hyperledger/production peer0.org2.example.com: volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp - ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org2.example.com:/var/hyperledger/production
6. 修改配置文件(docker-compose.yaml)中cli,为每个Org创建一个对应的cli,并对本地目录映射org1的管理节点:cli1org2的管理节点:cli2
# 修改前cli: container_name: cli image: hyperledger/fabric-tools:latest tty: true stdin_open: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - FABRIC_LOGGING_SPEC=INFO #- FABRIC_LOGGING_SPEC=DEBUG working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: /bin/bash volumes: - /var/run/:/host/var/run/ - ../organizations:/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations - ../scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ depends_on: - peer0.org1.example.com - peer0.org2.example.com networks: - test
# 修改后 cli1: container_name: cli1 image: hyperledger/fabric-tools:2.2 tty: true stdin_open: true environment: - GOPATH=/opt/gopath - GOPROXY=https://goproxy.io,direct - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - FABRIC_LOGGING_SPEC=INFO #- FABRIC_LOGGING_SPEC=DEBUG # 启用对服务端的TLS身份验证 - CORE_PEER_TLS_ENABLED=true # Peer节点的X.509证书文件路径 - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt # Peer节点的私钥文件路径 - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key # Peer节点证书的验证链根证书文件路径 - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt # Peer节点的本地MSP配置文件的路径 - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp # Peer节点ID - CORE_PEER_ID=cli1 # Peer节点连接地址 - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 # 本地MSP标识ID - CORE_PEER_LOCALMSPID=Org1MSP working_dir: /opt/hyperledger/fabric command: /bin/bash volumes: - /var/run/:/host/var/run/ - ./crypto-config:/etc/hyperledger/fabric/peer/crypto - ./channel-artifacts:/opt/hyperledger/fabric/channel-artifacts - ./chaincode/:/opt/hyperledger/fabric/chaincode depends_on: - peer0.org1.example.com - peer0.org2.example.com networks: - test cli2: container_name: cli2 image: hyperledger/fabric-tools:2.2 tty: true stdin_open: true environment: - GOPATH=/opt/gopath - GOPROXY=https://goproxy.io,direct - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - FABRIC_LOGGING_SPEC=INFO #- FABRIC_LOGGING_SPEC=DEBUG # 启用对服务端的TLS身份验证 - CORE_PEER_TLS_ENABLED=true # Peer节点的X.509证书文件路径 - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt # Peer节点的私钥文件路径 - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key # Peer节点证书的验证链根证书文件路径 - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt # Peer节点的本地MSP配置文件的路径 - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp # Peer节点ID - CORE_PEER_ID=cli2 # Peer节点连接地址 - CORE_PEER_ADDRESS=peer0.org2.example.com:9051 # 本地MSP标识ID - CORE_PEER_LOCALMSPID=Org2MSP working_dir: /opt/hyperledger/fabric command: /bin/bash volumes: - /var/run/:/host/var/run/ - ./crypto-config:/etc/hyperledger/fabric/peer/crypto - ./channel-artifacts:/opt/hyperledger/fabric/channel-artifacts - ./chaincode/:/opt/hyperledger/fabric/chaincode depends_on: - peer0.org1.example.com - peer0.org2.example.com networks: - test
7. 运行修改后的docker-compose
docker-compose up -d
8. 运行命令查看运行结果
docker ps -a
分别在cli1和cli2中操作Channel使用命令docker exec -it cli1 /bin/bash、docker exec -it cli2 /bin/bash分别进入相关组织的管理节点
1. 使用peer channel create命令在cli1创建Channel并生成Channel的Block文件
peer channel create \-o orderer.example.com:7050 \-f ./channel-artifacts/channel.tx \-c mychannel \--outputBlock ./channel-artifacts/mychannel.block \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2. 使用peer channel join命令分别对cli1和cli2加入Channel
# 在cli1加入Channelpeer channel join -b ./channel-artifacts/mychannel.block# 把cli2加入Channelpeer channel join -b ./channel-artifacts/mychannel.block
3. 使用peer channel update命令分别对cli1和cli2更新锚节点文件
# cli1peer channel update \-o orderer.example.com:7050 \-c mychannel \-f ./channel-artifacts/Org1MSPanchors.tx \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem# cli2peer channel update \-o orderer.example.com:7050 \-c mychannel \-f ./channel-artifacts/Org2MSPanchors.tx \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
打包、安装、批准、提交链码1. 创建链码目录:在本地创建chaincode目录,结构如下:
mkdir -p chaincode/gomkdir -p chaincode/output# 文件夹结构.├── go└── output
2. 下载链码:打开测试网络中的sacc文件(https://github.com/hyperledger/fabric-samples/tree/release-2.2/chaincode/sacc);把里面的sacc.go复制到chaincode/go/sacc/目录下
3. 为项目生成modules
cd chaincode/go/sacc# 初始化modules相关文件go mod init sacc# 更新项目所使用的包go mod tidy
4. 打包链码:使用peer lifecycle chaincode package命令打包链码并指定输出的文件名和label;这一步可以被一个或者每一个组织完成,可以在cli1或者cli2中打包链码
# 跳转到链码所在容器内的位置cd /opt/hyperledger/fabric/chaincode/go/sacc# 更新链码项目所使用的包go mod tidy# 对链码进行打包peer lifecycle chaincode package ./chaincode/output/sacc.tar.gz \--path /opt/hyperledger/fabric/chaincode/go/sacc \--label sacc_1
5. 安装链码在你的peer节点上:使用peer lifecycle chaincode install命令安装链码,每一个用链码的组织需要完成这一步。分别在cli1和cli2中给对应的peer节点安装链码,并复制保存生成的Package-ID
# 在cli1中给对应的peer节点安装链码peer lifecycle chaincode install ./chaincode/output/sacc.tar.gzsubmitInstallProposal -> INFO 002 Chaincode code package identifier: sacc_1:abf526549b6cd9639d4449f58aca40041882c34e8a3e314493189fc3a2187527 # 在cli2中给对应的peer节点安装链码peer lifecycle chaincode install ./chaincode/output/sacc.tar.gzsubmitInstallProposal -> INFO 002 Chaincode code package identifier: sacc_1:abf526549b6cd9639d4449f58aca40041882c34e8a3e314493189fc3a2187527
6. 为你的组织批准链码定义:使用peer lifecycle chaincode approveformyorg命令批准链码;使用链码的每一个组织需要完成这一步。在cli1和cli2中为你的组织批准链码定义
# cli1peer lifecycle chaincode approveformyorg \--orderer orderer.example.com:7050 \--channelID mychannel \--name sacc \--version 1.0 \--init-required \--package-id <这里需要填入安装链码生成的Package-ID> \--sequence 1 \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem# cli2peer lifecycle chaincode approveformyorg \--orderer orderer.example.com:7050 \--channelID mychannel \--name sacc \--version 1.0 \--init-required \--package-id <这里需要填入安装链码生成的Package-ID> \--sequence 1 \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
7. 检查链码是否批准:使用命令peer lifecycle chaincode checkcommitreadiness检查各个组织中的peer节点是否批准链码;可以在任意cli中运行
peer lifecycle chaincode checkcommitreadiness \--orderer orderer.example.com:7050 \--channelID mychannel \--name sacc \--version 1.0 \--init-required \--sequence 1 \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \--output json# 结果如下代表两个组织都批准成功{"approvals": {"Org1MSP": true,"Org2MSP": true}}
8. 提交链码定义到链上:使用peer lifecycle chaincode commit命令为所有组织提交链码;一旦有足够数量的组织批准其组织的链码定义(默认为多数),一个组织可以为已批准组织的peer节点的提交链码定义到连上。可以在任意cli中运行
peer lifecycle chaincode commit \--orderer orderer.example.com:7050 \--channelID mychannel \--name sacc \--version 1.0 \--sequence 1 \--init-required \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \--peerAddresses peer0.org1.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \--peerAddresses peer0.org2.example.com:9051 \--tlsRootCertFiles /etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
初始化和测试链码是否安装成功1. 使用命令peer chaincode invoke --isInit对变量进行赋值并初始化链码
# 调用版本1.0名为sacc的链码,# 该链码位于peer0.org1.example.com:7051和peer0.org2.example.com:9051#(节点由 –peerAddresses 上的通道mychannel中,添加变量name并赋值为德意洋洋)peer chaincode invoke \--orderer orderer.example.com:7050 \--isInit \--ordererTLSHostnameOverride orderer.example.com \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \--peerAddresses peer0.org1.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \--peerAddresses peer0.org2.example.com:9051 \--tlsRootCertFiles /etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \--channelID mychannel \--name sacc \-c '{"Args":["name","德意洋洋"]}'
2. 使用命令peer chaincode query对变量进行查询检查是否赋值成功
peer chaincode query --channelID mychannel --name sacc -c '{"Args":["query","name"]}'# 结果德意洋洋
3. 使用命令peer chaincode invoke对变量进行修改
peer chaincode invoke \--orderer orderer.example.com:7050 \--tls true \--cafile /etc/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \--peerAddresses peer0.org1.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \--peerAddresses peer0.org2.example.com:9051 \--tlsRootCertFiles /etc/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \--channelID mychannel \--name sacc \-c '{"Args":["set","name","德意洋洋牛逼"]}'
4. 使用命令peer chaincode query对变量进行查询检查是否修改成功
peer chaincode query --channelID mychannel --name sacc -c '{"Args":["query","name"]}'# 结果德意洋洋牛逼
项目整体目录结构.├── chaincode│ ├── go│ │ └── sacc│ │ ├── go.mod│ │ ├── go.sum│ │ ├── sacc.go│ │ └── sacc_test.go│ └── output│ ├── sacc.tar.gz├── channel-artifacts│ ├── channel.tx│ ├── genesis.block│ ├── mychannel.block│ ├── org1MSPanchors.tx│ └── org2MSPanchors.tx├── configtx.yaml├── crypto-config│ ├── ordererOrganizations│ │ └── example.com│ │ ├── ca│ │ │ ├── ca.example.com-cert.pem│ │ │ └── priv_sk│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ └── tlscacerts│ │ │ └── tlsca.example.com-cert.pem│ │ ├── orderers│ │ │ └── orderer.example.com│ │ │ ├── msp│ │ │ │ ├── admincerts│ │ │ │ ├── cacerts│ │ │ │ │ └── ca.example.com-cert.pem│ │ │ │ ├── config.yaml│ │ │ │ ├── keystore│ │ │ │ │ └── priv_sk│ │ │ │ ├── signcerts│ │ │ │ │ └── orderer.example.com-cert.pem│ │ │ │ └── tlscacerts│ │ │ │ └── tlsca.example.com-cert.pem│ │ │ └── tls│ │ │ ├── ca.crt│ │ │ ├── server.crt│ │ │ └── server.key│ │ ├── tlsca│ │ │ ├── priv_sk│ │ │ └── tlsca.example.com-cert.pem│ │ └── users│ │ └── Admin@example.com│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ ├── keystore│ │ │ │ └── priv_sk│ │ │ ├── signcerts│ │ │ │ └── Admin@example.com-cert.pem│ │ │ └── tlscacerts│ │ │ └── tlsca.example.com-cert.pem│ │ └── tls│ │ ├── ca.crt│ │ ├── client.crt│ │ └── client.key│ └── peerOrganizations│ ├── org1.example.com│ │ ├── ca│ │ │ ├── ca.org1.example.com-cert.pem│ │ │ └── priv_sk│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.org1.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ └── tlscacerts│ │ │ └── tlsca.org1.example.com-cert.pem│ │ ├── peers│ │ │ └── peer0.org1.example.com│ │ │ ├── msp│ │ │ │ ├── admincerts│ │ │ │ ├── cacerts│ │ │ │ │ └── ca.org1.example.com-cert.pem│ │ │ │ ├── config.yaml│ │ │ │ ├── keystore│ │ │ │ │ └── priv_sk│ │ │ │ ├── signcerts│ │ │ │ │ └── peer0.org1.example.com-cert.pem│ │ │ │ └── tlscacerts│ │ │ │ └── tlsca.org1.example.com-cert.pem│ │ │ └── tls│ │ │ ├── ca.crt│ │ │ ├── server.crt│ │ │ └── server.key│ │ ├── tlsca│ │ │ ├── priv_sk│ │ │ └── tlsca.org1.example.com-cert.pem│ │ └── users│ │ ├── Admin@org1.example.com│ │ │ ├── msp│ │ │ │ ├── admincerts│ │ │ │ ├── cacerts│ │ │ │ │ └── ca.org1.example.com-cert.pem│ │ │ │ ├── config.yaml│ │ │ │ ├── keystore│ │ │ │ │ └── priv_sk│ │ │ │ ├── signcerts│ │ │ │ │ └── Admin@org1.example.com-cert.pem│ │ │ │ └── tlscacerts│ │ │ │ └── tlsca.org1.example.com-cert.pem│ │ │ └── tls│ │ │ ├── ca.crt│ │ │ ├── client.crt│ │ │ └── client.key│ │ └── User1@org1.example.com│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.org1.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ ├── keystore│ │ │ │ └── priv_sk│ │ │ ├── signcerts│ │ │ │ └── User1@org1.example.com-cert.pem│ │ │ └── tlscacerts│ │ │ └── tlsca.org1.example.com-cert.pem│ │ └── tls│ │ ├── ca.crt│ │ ├── client.crt│ │ └── client.key│ └── org2.example.com│ ├── ca│ │ ├── ca.org2.example.com-cert.pem│ │ └── priv_sk│ ├── msp│ │ ├── admincerts│ │ ├── cacerts│ │ │ └── ca.org2.example.com-cert.pem│ │ ├── config.yaml│ │ └── tlscacerts│ │ └── tlsca.org2.example.com-cert.pem│ ├── peers│ │ └── peer0.org2.example.com│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.org2.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ ├── keystore│ │ │ │ └── priv_sk│ │ │ ├── signcerts│ │ │ │ └── peer0.org2.example.com-cert.pem│ │ │ └── tlscacerts│ │ │ └── tlsca.org2.example.com-cert.pem│ │ └── tls│ │ ├── ca.crt│ │ ├── server.crt│ │ └── server.key│ ├── tlsca│ │ ├── priv_sk│ │ └── tlsca.org2.example.com-cert.pem│ └── users│ ├── Admin@org2.example.com│ │ ├── msp│ │ │ ├── admincerts│ │ │ ├── cacerts│ │ │ │ └── ca.org2.example.com-cert.pem│ │ │ ├── config.yaml│ │ │ ├── keystore│ │ │ │ └── priv_sk│ │ │ ├── signcerts│ │ │ │ └── Admin@org2.example.com-cert.pem│ │ │ └── tlscacerts│ │ │ └── tlsca.org2.example.com-cert.pem│ │ └── tls│ │ ├── ca.crt│ │ ├── client.crt│ │ └── client.key│ └── User1@org2.example.com│ ├── msp│ │ ├── admincerts│ │ ├── cacerts│ │ │ └── ca.org2.example.com-cert.pem│ │ ├── config.yaml│ │ ├── keystore│ │ │ └── priv_sk│ │ ├── signcerts│ │ │ └── User1@org2.example.com-cert.pem│ │ └── tlscacerts│ │ └── tlsca.org2.example.com-cert.pem│ └── tls│ ├── ca.crt│ ├── client.crt│ └── client.key├── crypto-config.yaml├── docker-compose.yaml
- 免责声明
- 世链财经作为开放的信息发布平台,所有资讯仅代表作者个人观点,与世链财经无关。如文章、图片、音频或视频出现侵权、违规及其他不当言论,请提供相关材料,发送到:2785592653@qq.com。
- 风险提示:本站所提供的资讯不代表任何投资暗示。投资有风险,入市须谨慎。
- 世链粉丝群:提供最新热点新闻,空投糖果、红包等福利,微信:juu3644。