098-搞定Hyperledger (二)

    科技2022-07-20  102

     

     

    刚刚配置好了镜像加速器

    现在我们来安装fabric镜像

     

    地址

    https://hyperledger-fabric.readthedocs.io/en/release-1.1/samples.html#binaries

     

    官方使用curl

     

     

    但是这里的http://goo.gl我们不能打开

     

    所以我们去官方推荐的github上看这个sh脚本

    If you get an error running the above curl command, you may have too old a version of curl that does not handle redirects or an unsupported environment.

    Please visit the Prerequisites page for additional information on where to find the latest version of curl and get the right environment. Alternately, you can substitute the un-shortened URL: https://github.com/hyperledger/fabric/blob/master/scripts/bootstrap.sh

     

     

    然后我们下载一下这个bootstrap.sh脚本文件

    本来是可以用比如xhtp 直接把这个sh文件拖到服务器里面的

    但是我这里网速太慢了

    所以我就用

    touch bootstrap.sh 创建了文件

    然后复制了进去

     

     

    然后我们修改一下他的权限

    chmod 777 bootstrap.sh

    777就是

    1.Owner 4+2+1=7

    2.Group 4+2+1=7

    3. Other 4+2+1=7

     

     

    修改完权限了

    我们来运行吧

    ./bootstrap.sh

     

     

     

     

    什么叫良心解说

    什么叫良心解说

    什么叫良心解说

     

    我买了杭州60块的轻量级

    结果速度100K

    现在买了24块的香港轻量级

    这速度,这速度,这速度

    开心啊

     

     

    不过呢,这里又踩了一个坑

    如果是香港的,就不要配阿里镜像加速了

     

     

     

     

     

     

     

     

    完成啦

    看到这个速度

    确实是非常爽啊

     

     

     

     

    现在我们来看一下docker的所有镜像

    docker images

     

     

     

     

     

     

    现在我们来看一下fabric给的示例代码

     

    我们看一下test-network这个文件夹

     

    我们来看一下network.sh这个脚本文件

    cat network.sh

     

     

     

     

    然后我们需要安装docker-compose

    https://github.com/docker/compose

     

     

     

     

     

     

    然后我们启动network.sh

    ./network.sh up

     

     

    这样这个network示例算是运行成功了

    整个过程下来虽然看上去简单

    但是确实很恶心

     

     

     

     

     

    然后我们装一下nodejs

    这边我们使用的是nodesource提供的脚本安装

    https://github.com/nodesource/distributions/blob/master/README.md

     

    我们看下官网的版本

     

    LTS是12

    现在是14

     

    我们就选12就好了

     

     

    执行一下

    # Using Ubuntu curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - sudo apt-get install -y nodejs

     

     

     

     

    现在nodejs安装好了

    我们来写chaincode,也就是智能合约

    我们创建一下文件夹

    然后用npm init初始化一下

     

     

     

     

     

    然后使用npm 安装一下fabric-shim

    npm install --save fabric-shim

     

     

     

     

     

    看一下目录

     

     

    然后我们来写代码吧

    我们先看一下fabric-shim的官方介绍

    https://www.npmjs.com/package/fabric-shim

     

     

     

    然后我们复制一下他们的官方示例代码

    const shim = require('fabric-shim'); const Chaincode = class { async Init(stub) { // use the instantiate input arguments to decide initial chaincode state values // save the initial states await stub.putState(key, Buffer.from(aStringValue)); return shim.success(Buffer.from('Initialized Successfully!')); } async Invoke(stub) { // use the invoke input arguments to decide intended changes // retrieve existing chaincode states let oldValue = await stub.getState(key); // calculate new state values and saves them let newValue = oldValue + delta; await stub.putState(key, Buffer.from(newValue)); return shim.success(Buffer.from(newValue.toString())); } }; shim.start(new Chaincode());

     

     

     

    我们看这个Init方法和Invoke方法

    其实很简单

    把状态放到stub里面,

    然后从stub里面取出来处理一下

     

     

    然后我们把index.js拷贝到目录下面

     

     

     

     

    现在Init和Invoke这两个最基本的函数有了

    然后我们写一下查询的函数

    async query(stub, args) { let productId = args[0]; let productBytes = await stub.getState(productId); console.log(productBytes.toString()); return productBytes; }

     

     

     

    然后是initLedger 初始化账本

    async initLedger(stub, args) { console.log('====================Init Ledger Start===================='); let products = []; products.push({ id: '001', name: 'apple', price: '10' }); products.push({ id: '002', name: 'banana', price: '20' }); products.push({ id: '003', name: 'orange', price: '30' }); for (let i = 0; i < products.length; i++) { await stub.putState('Product' + i, Buffer.from(JSON.stringify(products[i]))); console.log('Added <-->', products[i]); } console.log('====================Init Ledger End====================') }

     

     

     

     

    然后写一个插入

    async insert(stub, args) { console.log('====================START : Insert===================='); let product = { id: args[1], name: args[2], price: args[3] }; await stub.putState(args[0], Buffer.from(JSON.stringify(product))); console.log('====================END : Insert===================='); }

     

     

     

     

     

    然后写一个查询所有

    async queryAll(stub, args) { let startKey = 'Product0'; let endKey = 'Product999'; let iterator = await stub.getStateByRange(startKey, endKey); let allResults = []; while (true) { let next = iterator.next(); if (next.value && next.value.value.toString()) { let jsonNext = {}; jsonNext.Key = next.value.key; jsonNext.Record = JSON.parse(next.value.value.toString('utf-8')); allResults.push(jsonNext); } if (next.done) { console.log('End of data'); await iterator.close(); console.log(allResults); return Buffer.from(JSON.stringify(allResults)); } } }

     

     

     

     

     

    然后看一下我们现在的chaincode代码

    const shim = require('fabric-shim'); const Chaincode = class { async Init(stub) { // use the instantiate input arguments to decide initial chaincode state values // save the initial states await stub.putState('state', Buffer.from('init')); return shim.success(Buffer.from('Initialized Successfully!')); } async Invoke(stub) { // use the invoke input arguments to decide intended changes // retrieve existing chaincode states let oldValue = await stub.getState('state'); // calculate new state values and saves them let newValue = 'invoke'; await stub.putState('state', Buffer.from(newValue)); return shim.success(Buffer.from(newValue.toString())); } async query(stub, args) { let productId = args[0]; let productBytes = await stub.getState(productId); console.log(productBytes.toString()); return productBytes; } async initLedger(stub, args) { console.log('====================START : Init Ledger===================='); let products = []; products.push({ id: '001', name: 'apple', price: '10' }); products.push({ id: '002', name: 'banana', price: '20' }); products.push({ id: '003', name: 'orange', price: '30' }); for (let i = 0; i < products.length; i++) { await stub.putState('Product' + i, Buffer.from(JSON.stringify(products[i]))); console.log('Added <-->', products[i]); } console.log('====================END : Init Ledger===================='); } async insert(stub, args) { console.log('====================START : Insert===================='); let product = { id: args[1], name: args[2], price: args[3] }; await stub.putState(args[0], Buffer.from(JSON.stringify(product))); console.log('====================END : Insert===================='); } async queryAll(stub, args) { let startKey = 'Product0'; let endKey = 'Product999'; let iterator = await stub.getStateByRange(startKey, endKey); let allResults = []; while (true) { let next = iterator.next(); if (next.value && next.value.value.toString()) { let jsonNext = {}; jsonNext.Key = next.value.key; jsonNext.Record = JSON.parse(next.value.value.toString('utf-8')); allResults.push(jsonNext); } if (next.done) { console.log('End of data'); await iterator.close(); console.log(allResults); return Buffer.from(JSON.stringify(allResults)); } } } }; shim.start(new Chaincode());

     

     

     

     

     

    chaincode代码写完了

    把index.js放到目录里面去

    现在fish目录有chaincode文件夹,

    我们再创建一个fishnetwork文件夹

     

     

     

     

     

    然后我们需要配置msp信息

    member service provider成员服务提供者

    crypto-config.yaml

     

     

     

     

    现在暂时还是根据视频来搞吧

    现在把crypto-config.yaml文件放到network里面

    OrdererOrgs: - Name: Orderer Domain: example.com - Specs: - Hostname: Orderer PeerOrgs: - Name: Org1 Domain: org1.example.com Template: Count: 1 - Users: Count: 1

     

     

     

     

     

     

    然后再看一下configtx.yaml文件

    Organizations: - &OrdererOrg Name: OrdererOrg ID: OrdererMSP MSPDir: crypto-config/ordererOrganizations/example.com/msp - &Org1 Name: Org1MSP ID: Org1MSP MSPDir: crypto-config/peerOrganizations/org1.example.com/msp Application: &ApplicationDefaults Organizations: Orderer: &OrdererDefaults OrdererType: solo Addresses: - orderer.example.com:7050 BatchTimeout: 2s BatchSize: MaxMessageCount: 10 AbsoluteMaxBytes: 99 MB PreferredMaxBytes: 512 KB Organizations: Profiles: OneOrgsOrdererGenesis: Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Consortiums: SampleConsortium: Organizations: - *Org1 OneOrgsChannel: Consortium: SampleConsortium Application: <<: *ApplicationDefaults Organizations: - *Org1

     

     

     

    也放到network里面

    现在看看

     

     

     

    然后我们要使用

    cryptogen generate --config ./crypto-config.yaml

    来创建

    但是我们发现出现了

    因为我们还没有配置cryptogen的环境变量

     

     

     

    那么我们配置一下环境变量

    export PATH=/root/howger/fabric-samples/bin:$PATH

     

     

     

     

    然后我们再来执行一下

     

    中间出了点小错误

    就是crypto-config.yaml文件的横杠- 出不出现的问题

    这个可能各个版本不一样

    反正加上或者删掉就可以了

     

     

     

     

    现在我们看

    有了crypto-config文件夹

     

     

    然后我们tree一下

    看看目录结构

     

    我们看到有

    ca

    msp

    org

    tlsca

    users

     

     

     

     

     

     

     

    然后我们生成创世区块

    现在发生了问题

    需要他妈的policies

    所以我们还是加上

    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 Capabilities: Channel: &ChannelCapabilities V2_0: true Orderer: &OrdererCapabilities V2_0: true Application: &ApplicationCapabilities V2_0: true Application: &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: <<: *ApplicationCapabilities Orderer: &OrdererDefaults OrdererType: solo Addresses: - orderer.example.com:7050 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: <<: *ChannelCapabilities Profiles: OneOrgsOrdererGenesis: <<: *ChannelDefaults Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Capabilities: <<: *OrdererCapabilities Consortiums: SampleConsortium: Organizations: - *Org1 OneOrgsChannel: Consortium: SampleConsortium <<: *ChannelDefaults Application: <<: *ApplicationDefaults Organizations: - *Org1 Capabilities: <<: *ApplicationCapabilities

     

     

    然后成功了

    创建了创世区块

     

     

     

    然后创建channel

    真的调了好久好久好久

    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 Capabilities: Channel: &ChannelCapabilities V2_0: true Orderer: &OrdererCapabilities V2_0: true Application: &ApplicationCapabilities V2_0: true Application: &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: <<: *ApplicationCapabilities Orderer: &OrdererDefaults OrdererType: solo Addresses: - orderer.example.com:7050 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 Consortium: SampleConsortium Policies: Readers: Type: ImplicitMeta Rule: "ANY Readers" Writers: Type: ImplicitMeta Rule: "ANY Writers" Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" Capabilities: <<: *ChannelCapabilities Application: <<: *ApplicationDefaults Organizations: - *Org1 Capabilities: <<: *ApplicationCapabilities Profiles: OneOrgsOrdererGenesis: <<: *ChannelDefaults Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Capabilities: <<: *OrdererCapabilities Consortiums: SampleConsortium: Organizations: - *Org1 OneOrgsChannel: Consortium: SampleConsortium <<: *ChannelDefaults Application: <<: *ApplicationDefaults Organizations: - *Org1 Capabilities: <<: *ApplicationCapabilities

     

     

     

    现在创世区块和channel都创建好了

    然后我们看下目录吧

     

     

     

     

     

     

     

     

     

     

     

    Processed: 0.014, SQL: 8