098-搞定Hyperledger (二)

 

 

刚刚配置好了镜像加速器

现在我们来安装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都创建好了

然后我们看下目录吧

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值