区块链开源实现fabric快速部署及CLI体验

2018年05月22日 09:53:41 阅读数:1359 标签: hyperledgerfabric区块链联盟链PBFT 更多

个人分类: 区块链技术分享linux算法

本文描述fabric快速部署的步骤,及演示基于官方example02的智能合约进行CLI命令行体验。区块链涉及服务很多,且大量使用docker容器技术,所以请严格遵守以下步骤去部署,以减少各种问题的出现,方便我们先对联盟链有个大概的感觉。本文描述环境是centos7操作系统,请其他版本更正相关的安装工具(如ubuntu操作系统请把yum命令换成apt-get)。

1、搭建e2e_cli环境快速部署fabric的11个步骤:

1、安装docker_ce版。

如果已经安装了老版docker,请先卸载。

yum remove docker docker-common docker-selinux docker-engine

再来安装docker:

  1. sudo yum install -y yum-utils device-mapper-persistent-data lvm2

  2. sudo yum-config-manager --add-repo \

  3. https://download.docker.com/linux/centos/docker-ce.repo

  4. sudo yum-config-manager --enable docker-ce-edge

  5. sudo yum-config-manager --enable docker-ce-test

  6. sudo yum-config-manager --disable docker-ce-edge

  7. sudo yum makecache fast

  8. sudo yum install docker-ce

最后启动docker服务:

  1. service docker start

  2. chkconfig docker on

2、配置好docker加速器。

官方docker非常慢,请一定在阿里云等提供docker仓库加速器的网站注册好帐户(比如https://cr.console.aliyun.com/#/accelerator),配置好加速器。

3、安装好pip。

yum install python-pip -y

4、用pip安装docker-compose。

pip install docker-compose

5、新建存放测试、部署代码的目录。

mkdir -p /opt/gopath/src/github.com/hyperledger

6、安装git。

yum install git -y

7、拉取fabric代码。

  1. cd /opt/gopath/src/github.com/hyperledger

  2. git clone https://github.com/hyperledger/fabric.git

请切换到最新的1.1分支上。

8、拉取docker镜像(时间较长)及一些可执行文件。

./opt/gopath/src/github.com/hyperledger/fabric/scripts/bootstrap.sh

9、安装go语言。

yum install golang -y

并通过在/etc/profile最后追加两行设置好工作目录:

  1. export PATH=$PATH:/usr/local/go/bin

  2. export GOPATH=/opt/gopath

最后执行下:

source /etc/profile

10、修改一个阻塞执行的bug

修改/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/base/peer-base.yaml文件:

  1. 将:

  2. - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=e2ecli_default

  3. 修改为:

  4. - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=e2e_cli_default

11、启动服务。

进入/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli目录,执行:

bash network_setup.sh up

如果最后出现下图则部署成功:

2、体验fabric系统功能

当服务在一台server上启动后,可以看到以下docker实例:

可以看到,默认安装了:4个peer(2个是org1的,2个是org2的)节点、4节点构成的kafka集群、3节点构成的zookeeper集群、1个orderer节点。这是因为:fabric提供的共识机制,PBFT目前还未达到生产级别的应用,只能靠kafka+zookeeper实现PAXOS算法下的共识机制(不能有作恶结点)。一般zookeeper是3或者5个结点,

fabric提供了SDK和CLI两种交互方式,本文不讨论SDK。

可以进入cli里执行peer命令。如果cli长时间未用退出后,可先启动cli:

docker start cli

再进入cli实例里:

docker exec -it cli bash

接着可执行peer命令,体验区块链的命令行使用方式。

2.1、 peer命令

peer命令含有五个子命令,如下:

  1. peer chaincode [option] [flags]

  2. peer channel [option] [flags]

  3. peer logging [option] [flags]

  4. peer node [option] [flags]

  5. peer version [option] [flags]

每个子命令可使用--help查看详细帮助。

在fabric里,所有的交易必须通过智能合约才能操作,而chaincode链码就是智能合约。chaincode支持以下option操作:

  • package 智能合约需要打包后才能使用
  • install    智能合约必须安装后才能使用
  • instantiate   置初始状态。比如设系统一开始用户a有100元,用户b有200元
  • invoke  调用智能合约
  • query    查询状态
  • signpackage  包签名
  • upgrade    智能合约升级
  • list        显示智能合约

智能合约需要先install才能使用。

peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

其中-n表示合约名字,-p指向合约文件目录路径,-v是版本号。

2.2 example02智能合约

每个智能合约实现Init和Invoke两个方法,其中前者用于初始化,后者是日常调用。

2.2.1 初始化

example02的Init方法接收4个参数(包括帐户A,余额pA,帐户B,余额pB),比如:

peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR    ('Org1MSP.peer','Org2MSP.peer')"

其中,-C指向channel名字,-c则是初始构造json格式的消息,-P是背书策略,-o指定共识节点。这里置帐户a初始余额为100,帐户b初始余额为200。其代码实现如下:

  1. func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {

  2. fmt.Println("ex02 Init")

  3. //用args取得命令行的参数

  4. _, args := stub.GetFunctionAndParameters()

  5. var A, B string // Entities

  6. var Aval, Bval int // Asset holdings

  7. var err error

  8. //简单的例子么,只接收4个参数,包括帐户A,余额pA,帐户B,余额pB

  9. if len(args) != 4 {

  10. return shim.Error("Incorrect number of arguments. Expecting 4")

  11. }

  12. // Initialize the chaincode

  13. A = args[0]

  14. Aval, err = strconv.Atoi(args[1])

  15. if err != nil {

  16. return shim.Error("Expecting integer value for asset holding")

  17. }

  18. B = args[2]

  19. Bval, err = strconv.Atoi(args[3])

  20. if err != nil {

  21. return shim.Error("Expecting integer value for asset holding")

  22. }

  23. fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

  24. //将A及其余额写入状态数据库

  25. err = stub.PutState(A, []byte(strconv.Itoa(Aval)))

  26. if err != nil {

  27. return shim.Error(err.Error())

  28. }

  29. //将B及其余额写入状态数据库

  30. err = stub.PutState(B, []byte(strconv.Itoa(Bval)))

  31. if err != nil {

  32. return shim.Error(err.Error())

  33. }

  34. return shim.Success(nil)

  35. }

2.2.2 查询余额

接着查询余额,例如查询a帐户的余额:

peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

这里需要说明,example02的Invoke共支持3种指令:

  1. func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {

  2. fmt.Println("ex02 Invoke")

  3. function, args := stub.GetFunctionAndParameters()

  4. if function == "invoke" {

  5. // 从A向B帐户转账

  6. return t.invoke(stub, args)

  7. } else if function == "delete" {

  8. // 从状态数据库中删除帐户

  9. return t.delete(stub, args)

  10. } else if function == "query" {

  11. // 查询状态数据库中某帐户的余额

  12. return t.query(stub, args)

  13. }

  14. return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")

  15. }

因此,上述查询我们会得出类似结果:

为何结果格式是这样的呢?看下t.query的实现:

  1. func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {

  2. var A string // Entities

  3. var err error

  4. if len(args) != 1 {

  5. return shim.Error("Incorrect number of arguments. Expecting name of the person to query")

  6. }

  7. A = args[0] //获取帐户的名字

  8. // 从状态数据库中获取帐户的值

  9. Avalbytes, err := stub.GetState(A)

  10. if err != nil {

  11. jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"

  12. return shim.Error(jsonResp)

  13. }

  14. if Avalbytes == nil {

  15. jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"

  16. return shim.Error(jsonResp)

  17. }

  18. jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"

  19. //这里是显示在命令行的格式:Query Response:90

  20. fmt.Printf("Query Response:%s\n", jsonResp)

  21. return shim.Success(Avalbytes)

  22. }

2.2.3 转帐

比如由B向A转帐50:

peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  -C mychannel -n mycc -c '{"Args":["invoke","b","a","50"]}'

成功后我们会在输屏结果中找到这一行:ESCC invoke result: version:1 response:<status:200 message:"OK" >

其实现为从A和B帐户下用GetStat方法从状态数据库取出余额,与query类似,接着加减相应的值50后,再调用PutStat方法写入状态数据库。

此时我们可以再次查询,可以获得正确结果。

小结:以上只适用于简单体验fabric的功能,对于智能合约、共识算法、世界状态等在接下来的文章中我们再分析。

区块链开源实现fabric快速部署及CLI体验相关推荐

  1. 区块链开源实现hyperledger fabric架构详解

    hyperledger fabric是区块链中联盟链的优秀实现,主要代码由IBM.Intel.各大银行等贡献,目前v1.1版的kafka共识方式可达到1000/s次的吞吐量.本文中我们依次讨论:区块链 ...

  2. 这就是区块链开源底层软件平台——长安链ChainMaker

    本文已参与「开源摘星计划」,欢迎正在阅读的你加入. 活动链接:https://github.com/weopenprojects/WeOpen-Star 这就是区块链开源底层软件平台--长安链Chai ...

  3. 盘点10大热门区块链开源软件,你知道几个?

    越来越多的企业将开源软件作为其构建基础信息系统的重要选择,"低成本.安全性高.灵活自由.高可用性.协同性好--"一连串的技术优势,让越来越多的企业无法拒绝. 在区块链领域,又有哪些 ...

  4. 数字广东:共建区块链开源生态,实现高水平科技自立自强

    近日,在2023年第1季社区Task挑战赛中,众多开发者为FISCO BCOS开源项目及周边组件贡献了丰富的代码和教程.其中,作为金链盟开源工作组成员,数字广东网络建设有限公司科技发展部的数字信任中心 ...

  5. 区块链单组群多节点部署

    区块链单组群多节点部署 环境配置 配置 最低配置 推荐配置 CPU 1.5GHz 2.4GHz 内存 1GB 8GB 核心 1核 8核 带宽 1Mb 10Mb 本次试验使用Ubuntu16.04版本, ...

  6. oracle区块链开源项目,区块链Oracle原理及实现

    区块链本身是封闭的.区块链的确定性模型基于这样一个事实:在交易执行时区块链不能执行任何来自外部的逻辑,所有的外部数据只能通过交易进入到系统中.预言机/Oracle就是通过交易为智能合约提供可信数据的服 ...

  7. 从黑客文化看区块链开源社区的自我组织与成功之道

    来源 | 链闻 ChainNews 撰文 | 李画 原书作者 | 埃里克·斯蒂芬·雷蒙 出品 | 区块链大本营(blockchain_camp) 「要尊重能力,要珍视和捍卫自由.」--罗伯特·安森·海 ...

  8. 区块链原理和fabric概念介绍

    一.区块链的基本原理 区块链包括三个基本概念: 1.交易(transaction):一次对账本的操作,导致账本状态的一次改变,如添加一次转账记录: 2.区块(block):记录一段时间内发生的所有交易 ...

  9. 京东数科区块链开源底层JD Chain版本升级,获工信部功能测试证书

    点击「京东数科技术说」可快速关注 京东数科区块链开源底层引擎JD Chain自2019年第一季度正式开源后,得到了诸多企业研发人员.个人开发者的使用反馈.结合这些来自实际应用场景方面的宝贵意见,攻城狮 ...

最新文章

  1. 解析mediaTypes+viewResolvers+viewResolvers
  2. debug LUW3 - callback workflow - ABAP工作流的调试(第三部分)
  3. php 脏数据,使用 PHP Masked Package 屏蔽敏感数据
  4. 一起学Python:列表介绍
  5. DML和DDL含义和区别-一定要搞明白
  6. Windows小工具广告弹窗杀手+源码
  7. Hibernate缓存 - 第一级缓存
  8. 分块-洛谷P3203 [HNOI2010]BOUNCE 弹飞绵羊
  9. 【java】SPI机制详解
  10. 用mysql制作一个登录_连接数据库制作一个简单的登入页面1
  11. 计算机桌面屏保字幕设置,win7系统屏保设置成字幕保护的操作方法
  12. 白话空间统计之二十五:空间权重矩阵(四)R语言中的空间权重矩阵(1)
  13. AVR单片机计算器C语言源程序,基于AVR单片机的简易计算器设计
  14. 谷木美身粥要怎样做?谷木美身粥功效真的那么神奇?
  15. PHP 该网页无法正常运作情况原因记录 code 500
  16. 这两省软考电子版证书下载已开通
  17. 微信商家收款码怎么申请
  18. StringBuffer的使用
  19. C语言项目 电话查询系统 哈希表实现(项目要求 + 运行界面 + 代码分析 + 完整代码)
  20. 这10个问题帮你搞清楚SaaS是什么!

热门文章

  1. offsetof宏和container_of宏
  2. 视频在计算机中的存储
  3. android studio socket 失败,Android应用开发Android Studio建立Socket连接失败解决方法
  4. java安全管理器视频_java安全-安全管理器
  5. Maven如何用Eclipse创建一个Maven项目【笔记自用】
  6. cmake之 ADD_LIBRARY()
  7. C++类模板(二)用类模板实现可变长数组
  8. python super 变参数问题(六)
  9. C 语言 链表的创建与打印
  10. 判断两个字符串是否为旋转词