16

Fabric 2.0 instal guide

 4 years ago
source link: https://learnblockchain.cn/article/1035
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

你需要docker, docker-compose,go,git 以及 强悍的网络, 然后你就可以体验官方一键搞定的网络(链环境)和链码(智能合约), 并用官方为你写好的sdk和调用sdk的demo代码体验与链码交互

基本环境准备

  • Docker
  • docker-compose
  • docker 阿里镜像加速
  • Git

对于 Mac

上诉环境只需要下载 docker的 dmg 安装后即可拥有 docker 和 docker-compose

对于 CentOs

docker

sudo yum update
# 移除旧版本
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

#安装 docker
sudo yum install docker-ce
sudo systemctl start docker
# 开机启动
sudo systemctl enable docker
# 验证
docker --version

docker-compose

curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-(uname−s)−(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version

git

sudo yum install -y git

go

wget -c https://studygolang.com/dl/golang/go1.14.linux-amd64.tar.gz
tar -C /usr/local/ -zxvf go1.14.linux-amd64.tar.gz
vi /etc/profile
# 新增
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=/root/go/

source /etc/profile
#验证 
go version

下载文件及 docker 镜像

一键脚本

curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.0.0 1.4.4 0.4.18
  • 2.0.0:表示Hyperledger Fabric的版本号
  • 1.4.4:表示Fabric CA的版本号
  • 0.4.18:表示第三方引用的版本号

加速技巧

首先自己整个科学上网, 设置好 http 代理端口(如 1087)

然后在docker 偏好设置中设置代理, 如下图

MRnEZzB.jpg!web

设置完成后点击 Apply & Restart 重启生效.

若没有科学上网, 则可以手动执行 docker pull 命令, 单个执行不容易卡住

docker pull hyperledger/fabric-peer:2.0.0
docker pull hyperledger/fabric-orderer:2.0.0
docker pull hyperledger/fabric-ccenv:2.0.0
docker pull hyperledger/fabric-tools:2.0.0
docker pull hyperledger/fabric-nodeenv:2.0.0
docker pull hyperledger/fabric-baseos:2.0.0
docker pull hyperledger/fabric-javaenv:2.0.0
docker pull hyperledger/fabric-ca:1.4.4
docker pull hyperledger/fabric-zookeeper:0.4.18
docker pull hyperledger/fabric-kafka:0.4.18
docker pull hyperledger/fabric-couchdb:0.4.18

最后检查

cd fabric-samples/bin
ls -l
export PATH=$PATH:$(pwd)
orderer version
1.存在 bin 目录
2.bin 下存在 orderer 等可执行文件
3.将 bin 添加到 PATH 下
4.检查 orderer 版本是否正确

测试网络

cd fabric-samples/test-network
#注意会删除全部容器
docker stop $(docker ps -q) 
docker rm $(docker ps -aq)
./network.sh up
1.进入测试网络目录
2.停止并删除之前的容器防止命名冲突
3.运行测试网络(通过 docker-compose)

链码入门示例(智能合约)

启动环境及安装 npm

cd fabric-samples/fabcar
#将启动 first-network 环境, 然后将早已存在镜像中的链码代码打包, 安装, 验证, 提交, 使其可执行
./startFabric.sh javascript
cd javascript
# 自行安装cnpm
cnpm i

测试链码

官方提示

JavaScript:

  Start by changing into the "javascript" directory:
    cd javascript

  Next, install all required packages:
    npm install

  Then run the following applications to enroll the admin user, and register a new user
  called user1 which will be used by the other applications to interact with the deployed
  FabCar contract:
    node enrollAdmin
    node registerUser

  You can run the invoke application as follows. By default, the invoke application will
  create a new car, but you can update the application to submit other transactions:
    node invoke

  You can run the query application as follows. By default, the query application will
  return all cars, but you can update the application to evaluate other transactions:
    node query

通过SDK(js) 调用合约

#添加 admin 用户和普通用户 user1
node enrollAdmin.js
node registerUser.js
# 执行合约的 queryAll 方法
node query.js
# 执行合约的 createCar 方法
node invoke.js
# 重新查询
node query.js

实际合约(js 代码)

fabric-samples/chaincode/fabcar/javascript/lib/fabcar.js

/*
 * SPDX-License-Identifier: Apache-2.0
 */

'use strict';

const { Contract } = require('fabric-contract-api');

class FabCar extends Contract {

    async initLedger(ctx) {
        console.info('============= START : Initialize Ledger ===========');
        const cars = [
            {
                color: 'blue',
                make: 'Toyota',
                model: 'Prius',
                owner: 'Tomoko',
            },
            {
                color: 'red',
                make: 'Ford',
                model: 'Mustang',
                owner: 'Brad',
            },
            {
                color: 'green',
                make: 'Hyundai',
                model: 'Tucson',
                owner: 'Jin Soo',
            },
            {
                color: 'yellow',
                make: 'Volkswagen',
                model: 'Passat',
                owner: 'Max',
            },
            {
                color: 'black',
                make: 'Tesla',
                model: 'S',
                owner: 'Adriana',
            },
            {
                color: 'purple',
                make: 'Peugeot',
                model: '205',
                owner: 'Michel',
            },
            {
                color: 'white',
                make: 'Chery',
                model: 'S22L',
                owner: 'Aarav',
            },
            {
                color: 'violet',
                make: 'Fiat',
                model: 'Punto',
                owner: 'Pari',
            },
            {
                color: 'indigo',
                make: 'Tata',
                model: 'Nano',
                owner: 'Valeria',
            },
            {
                color: 'brown',
                make: 'Holden',
                model: 'Barina',
                owner: 'Shotaro',
            },
        ];

        for (let i = 0; i < cars.length; i++) {
            cars[i].docType = 'car';
            await ctx.stub.putState('CAR' + i, Buffer.from(JSON.stringify(cars[i])));
            console.info('Added <--> ', cars[i]);
        }
        console.info('============= END : Initialize Ledger ===========');
    }

    async queryCar(ctx, carNumber) {
        const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
        if (!carAsBytes || carAsBytes.length === 0) {
            throw new Error(`${carNumber} does not exist`);
        }
        console.log(carAsBytes.toString());
        return carAsBytes.toString();
    }

    async createCar(ctx, carNumber, make, model, color, owner) {
        console.info('============= START : Create Car ===========');

        const car = {
            color,
            docType: 'car',
            make,
            model,
            owner,
        };

        await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
        console.info('============= END : Create Car ===========');
    }

    async queryAllCars(ctx) {
        const startKey = 'CAR0';
        const endKey = 'CAR999';
        const allResults = [];
        for await (const {key, value} of ctx.stub.getStateByRange(startKey, endKey)) {
            const strValue = Buffer.from(value).toString('utf8');
            let record;
            try {
                record = JSON.parse(strValue);
            } catch (err) {
                console.log(err);
                record = strValue;
            }
            allResults.push({ Key: key, Record: record });
        }
        console.info(allResults);
        return JSON.stringify(allResults);
    }

    async changeCarOwner(ctx, carNumber, newOwner) {
        console.info('============= START : changeCarOwner ===========');

        const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
        if (!carAsBytes || carAsBytes.length === 0) {
            throw new Error(`${carNumber} does not exist`);
        }
        const car = JSON.parse(carAsBytes.toString());
        car.owner = newOwner;

        await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
        console.info('============= END : changeCarOwner ===========');
    }

}

module.exports = FabCar;

基本环境准备

  • Docker
  • docker-compose
  • docker 阿里镜像加速
  • Git

对于 Mac

上诉环境只需要下载 docker的 dmg 安装后即可拥有 docker 和 docker-compose

对于 CentOs

docker

sudo yum update
# 移除旧版本
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

#安装 docker
sudo yum install docker-ce
sudo systemctl start docker
# 开机启动
sudo systemctl enable docker
# 验证
docker --version

docker-compose

curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-(uname−s)−(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version

git

sudo yum install -y git

go

wget -c https://studygolang.com/dl/golang/go1.14.linux-amd64.tar.gz
tar -C /usr/local/ -zxvf go1.14.linux-amd64.tar.gz
vi /etc/profile
# 新增
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=/root/go/

source /etc/profile
#验证 
go version

下载文件及 docker 镜像

一键脚本

curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.0.0 1.4.4 0.4.18
  • 2.0.0:表示Hyperledger Fabric的版本号
  • 1.4.4:表示Fabric CA的版本号
  • 0.4.18:表示第三方引用的版本号

加速技巧

首先自己整个科学上网, 设置好 http 代理端口(如 1087)

然后在docker 偏好设置中设置代理, 如下图

MRnEZzB.jpg!web

设置完成后点击 Apply & Restart 重启生效.

若没有科学上网, 则可以手动执行 docker pull 命令, 单个执行不容易卡住

docker pull hyperledger/fabric-peer:2.0.0
docker pull hyperledger/fabric-orderer:2.0.0
docker pull hyperledger/fabric-ccenv:2.0.0
docker pull hyperledger/fabric-tools:2.0.0
docker pull hyperledger/fabric-nodeenv:2.0.0
docker pull hyperledger/fabric-baseos:2.0.0
docker pull hyperledger/fabric-javaenv:2.0.0
docker pull hyperledger/fabric-ca:1.4.4
docker pull hyperledger/fabric-zookeeper:0.4.18
docker pull hyperledger/fabric-kafka:0.4.18
docker pull hyperledger/fabric-couchdb:0.4.18

最后检查

cd fabric-samples/bin
ls -l
export PATH=$PATH:$(pwd)
orderer version
1.存在 bin 目录
2.bin 下存在 orderer 等可执行文件
3.将 bin 添加到 PATH 下
4.检查 orderer 版本是否正确

测试网络

cd fabric-samples/test-network
#注意会删除全部容器
docker stop $(docker ps -q) 
docker rm $(docker ps -aq)
./network.sh up
1.进入测试网络目录
2.停止并删除之前的容器防止命名冲突
3.运行测试网络(通过 docker-compose)

链码入门示例(智能合约)

启动环境及安装 npm

cd fabric-samples/fabcar
#将启动 first-network 环境, 然后将早已存在镜像中的链码代码打包, 安装, 验证, 提交, 使其可执行
./startFabric.sh javascript
cd javascript
# 自行安装cnpm
cnpm i

测试链码

官方提示

JavaScript:

  Start by changing into the "javascript" directory:
    cd javascript

  Next, install all required packages:
    npm install

  Then run the following applications to enroll the admin user, and register a new user
  called user1 which will be used by the other applications to interact with the deployed
  FabCar contract:
    node enrollAdmin
    node registerUser

  You can run the invoke application as follows. By default, the invoke application will
  create a new car, but you can update the application to submit other transactions:
    node invoke

  You can run the query application as follows. By default, the query application will
  return all cars, but you can update the application to evaluate other transactions:
    node query

通过SDK(js) 调用合约

#添加 admin 用户和普通用户 user1
node enrollAdmin.js
node registerUser.js
# 执行合约的 queryAll 方法
node query.js
# 执行合约的 createCar 方法
node invoke.js
# 重新查询
node query.js

实际合约(js 代码)

fabric-samples/chaincode/fabcar/javascript/lib/fabcar.js

/*
 * SPDX-License-Identifier: Apache-2.0
 */

'use strict';

const { Contract } = require('fabric-contract-api');

class FabCar extends Contract {

    async initLedger(ctx) {
        console.info('============= START : Initialize Ledger ===========');
        const cars = [
            {
                color: 'blue',
                make: 'Toyota',
                model: 'Prius',
                owner: 'Tomoko',
            },
            {
                color: 'red',
                make: 'Ford',
                model: 'Mustang',
                owner: 'Brad',
            },
            {
                color: 'green',
                make: 'Hyundai',
                model: 'Tucson',
                owner: 'Jin Soo',
            },
            {
                color: 'yellow',
                make: 'Volkswagen',
                model: 'Passat',
                owner: 'Max',
            },
            {
                color: 'black',
                make: 'Tesla',
                model: 'S',
                owner: 'Adriana',
            },
            {
                color: 'purple',
                make: 'Peugeot',
                model: '205',
                owner: 'Michel',
            },
            {
                color: 'white',
                make: 'Chery',
                model: 'S22L',
                owner: 'Aarav',
            },
            {
                color: 'violet',
                make: 'Fiat',
                model: 'Punto',
                owner: 'Pari',
            },
            {
                color: 'indigo',
                make: 'Tata',
                model: 'Nano',
                owner: 'Valeria',
            },
            {
                color: 'brown',
                make: 'Holden',
                model: 'Barina',
                owner: 'Shotaro',
            },
        ];

        for (let i = 0; i < cars.length; i++) {
            cars[i].docType = 'car';
            await ctx.stub.putState('CAR' + i, Buffer.from(JSON.stringify(cars[i])));
            console.info('Added <--> ', cars[i]);
        }
        console.info('============= END : Initialize Ledger ===========');
    }

    async queryCar(ctx, carNumber) {
        const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
        if (!carAsBytes || carAsBytes.length === 0) {
            throw new Error(`${carNumber} does not exist`);
        }
        console.log(carAsBytes.toString());
        return carAsBytes.toString();
    }

    async createCar(ctx, carNumber, make, model, color, owner) {
        console.info('============= START : Create Car ===========');

        const car = {
            color,
            docType: 'car',
            make,
            model,
            owner,
        };

        await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
        console.info('============= END : Create Car ===========');
    }

    async queryAllCars(ctx) {
        const startKey = 'CAR0';
        const endKey = 'CAR999';
        const allResults = [];
        for await (const {key, value} of ctx.stub.getStateByRange(startKey, endKey)) {
            const strValue = Buffer.from(value).toString('utf8');
            let record;
            try {
                record = JSON.parse(strValue);
            } catch (err) {
                console.log(err);
                record = strValue;
            }
            allResults.push({ Key: key, Record: record });
        }
        console.info(allResults);
        return JSON.stringify(allResults);
    }

    async changeCarOwner(ctx, carNumber, newOwner) {
        console.info('============= START : changeCarOwner ===========');

        const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
        if (!carAsBytes || carAsBytes.length === 0) {
            throw new Error(`${carNumber} does not exist`);
        }
        const car = JSON.parse(carAsBytes.toString());
        car.owner = newOwner;

        await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
        console.info('============= END : changeCarOwner ===========');
    }

}

module.exports = FabCar;

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 2分钟前
  • 阅读 ( 3 )
  • 学分 ( 0 )
  • 分类:Fabric

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK