Fabric2.0学习进阶——链码管理(四)

4.1 安装链码

Fabric-sample工程自带了很多示例链码,位于fabric-samples/chaincode目录中,本文测试安装abstore工程的go版本到org1.peer0和org2.peer0两个节点。

链码安装成功之后,就可以调用链码完成交易操作了。

image-20200630142347946

安装链码的所有操作均需要先进入cli容器,执行如下命令:

docker exec -it cli bash
4.1.1 链码打包

链码打包执行如下命令:

peer lifecycle chaincode package abs.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label abs_1

abs.tar.gz:打包合约包文件名

–path:智能合约路径

–lang:智能合约语言,支持golang、Java、node

–label:智能合约标签,起描述作用

执行成功之后,当前目录下将生成文件abs.tar.gz。

4.1.2 链码安装

本节将把上述打包的代码安装到org1.peer0和org2.peer0两个节点上,因此需要切换环境变量。

通过命令查看当前使用的是org1.peer0的环境。

image-20200630142514936

执行链码安装命令,则可以把上述打包的合约代码安装到org1.peer0节点上。

peer lifecycle chaincode install abs.tar.gz

执行结果如下:

image-20200630142825445

查看安装结果,执行命令:

peer lifecycle chaincode queryinstalled

image-20200630142852392

接下来为org2.peer0安装智能合约代码,执行如下命令切换环境变量:

source scripts/utils.sh
setGlobals 0 2

查看切换结果,如下图所示:

image-20200630143027014

执行链码安装命令,则可以把上述打包的合约代码安装到org2.peer0节点上。

peer lifecycle chaincode install abs.tar.gz
4.1.3 链码认证

链码安装完成之后需要被组织认证,认证通过之后才能将链码提交并运行,该过程又可以称为合约定义,定义了合约的名称、版本、序列号,后续合约升级即修改版本或序列号,重新定义合约。

执行如下代码,完成当前节点所在组织对上述安装链码的认证。

peer lifecycle chaincode approveformyorg --tls true --cafile $ORDERER_CA --channelID mychannel --name abs --version 1 --init-required --package-id abs_1:90786e8a73dbee43adfebeb316407387173f598a5f7e3cef7ddc754fe25e2ad6 --sequence 1 --waitForEvent

参照上节的方法切换环境,实现org2组织对上述安装链码的认证。

最后查看链码认证结果,执行如下命令:

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name abs --version 1 --sequence 1 --output json --init-required

image-20200630143125603

上图结果表示:通道mychannel中的两个组织Org1和Org2均已对智能合约链码abs认证通过。

4.1.4 链码提交

只有通过组织认证的链码才能被提交。执行如下命令提交链码:

peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA --channelID mychannel --name abs --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 1 --init-required

查看提交结果,执行如下命令:

peer lifecycle chaincode querycommitted --channelID mychannel --name abs

image-20200630143335170

4.2 调用链码

链码调用主要包括invoke和query两个操作,本节将演示智能链码数据初始化、数据查询以及数据更新。

4.2.1 链码初始化

执行如下命令调用链码初始化方法,并指定初始化参数和值。

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n abs --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --isInit -c '{"Args":["Init","a","100","b","100"]}'

image

4.2.2 数据查询

执行如下命令查询参数a的值。

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

image-20200630143356897

4.2.3 数据更新

执行如下命令调用合约的invoke方法,实现参数a的值减少10,参数b的值增加10。

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n abs --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'

执行结果如下图所示:

image-20200630143436878

4.3 升级链码

链码(合约)升级的关键之处在于合约定义,即4.1.3节的链码认证。升级链码之后将重新定义合约,修改合约的版本号或者序列号。

4.3.1 获取合约代码

巧妇难为无米之炊。升级链码的第一步应该是获取合约代码,获取合约代码有两种方式:

  • 根据4.1.1节链码打包命令参数–path指定的路径获取代码;

  • 通过peer脚本获取已安装的合约代码包,执行如下命令:

    #查看已安装的合约代码包,获取对应包的package-id值
    peer lifecycle chaincode queryinstalled
    

    执行结果如下图所示:

    image-20200630143822657

    #下载指定合约代码包
    peer lifecycle chaincode getinstalledpackage --package-id abs_1:90786e8a73dbee43adfebeb316407387173f598a5f7e3cef7ddc754fe25e2ad6
    

    执行结果如下图所示:

    image-20200630143851638

    上图中,我们可以看到当前目录下多了一个以package-id值命名的压缩文件,重命名该文件为abs.tar.gz,通过tar命令查看该压缩包包含一个json文件和一个压缩包。Json文件是对压缩包的描述,code.tar.gz则是合约源码,是我们本次的修改目标,将该包解压之后我们继续接下来的操作。

4.3.2 修改合约代码

假设大家已经把下载的合约源码包解压了,或者找到了样例自带源码的路径,接下来开始修改合约代码。

本次修改目标文件为:abstore.go,增加一个Add函数,具体内容如下:

func (t *ABstore) Add(ctx contractapi.TransactionContextInterface, A string, X int) error {
        var err error
        //Get the state from the leger
        Avalbytes, err := ctx.GetStub().GetState(A)
        if err != nil {
                return fmt.Errorf("Failed to get state for " + A)
        }

        if Avalbytes == nil {
                return fmt.Errorf("Nil amount for " + A)
        }

        var Aval int
        Aval, _ = strconv.Atoi(string(Avalbytes))
        Aval = Aval + X

        // Write the state back to the ledger
        err = ctx.GetStub().PutState(A, []byte(strconv.Itoa(Aval)))
        if err != nil {
                return err
        }

        return nil
}

修改后的文件内容如下图所示:

image-20200630143953242

4.3.3 重新打包合约

代码修改完成之后,重新打包,执行如下命令:

peer lifecycle chaincode package abs.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label abs_1

执行完成之后请自行检测当前目录是否生成代码包。

4.3.4 重新安装合约
# 安装链码
peer lifecycle chaincode install abs.tar.gz
# 查询链码安装结果
peer lifecycle chaincode queryinstalled

执行结果如下图所示:

image-20200630144047399

上图标红的内容为新打包安装成功的合约代码包。

参照4.1.2节,切换到另外的组织节点,进行新打包合约代码的安装。

4.3.5 修改合约定义

修改合约定义与4.1.3节链码认证执行一样的命令,只是指定参数值不一样。

package-id为最新合约包的Package ID,即上图红框中的内容;sequence参数设置为2,因为这是该合约相同版本的第2次安装。具体执行命令如下:

peer lifecycle chaincode approveformyorg --tls true --cafile $ORDERER_CA --channelID mychannel --name abs --version 1 --init-required --package-id abs_1:013a79f868db17429c3195acacc08ae376994c5a9fb32d2302bef7f49f0354f7 --sequence 2 --waitForEvent

参照4.1.3节,切换到另外的组织节点,进行新打包合约代码的定义。

最后查看新合约的定义(认证)结果,执行如下命令:

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name abs --version 1 --sequence 2 --output json --init-required

image-20200630144208687

上图结果表示:通道mychannel中的两个组织Org1和Org2对新打包的智能合约认证通过。

4.3.6 重新提交合约

重新提交合约与4.1.4节链码提交使用相同的命令,唯一不同的就是sequence参数值为2。

peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA --channelID mychannel --name abs --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 1 --init-required

查看提交结果,如下图所示:

image-20200630144256865

上图显示合约abs已经提交到通道mychannel,并展示了对应的版本、序列、背书插件、校验插件等信息。

4.3.7 检验新合约

本次校验步骤分为三步:

(1) 调用合约的query方法,查询参数a的值;

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

(2) 调用合约新增的add方法,将a的值增加30;

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n abs --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["add","a","30"]}'

(3) 再次调用合约的query方法,查询参数a的值,判断上一步是否正确执行;

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

上述过程的执行结果如下图所示:

image-20200630144428359

从上图的执行结果来看,a的原值为90,调用add方法给a值增加30,再次查询a的值为120,说明合约更新成功,新增的方法也调用成功。

4.4 其他节点补充安装链码

之前的操作仅在org1.peer0和org2.peer0两个节点上安装并升级了链码,org1.peer1和org2.peer1两个节点未安装链码。当运行基于Fabric SDK编写的Java代码时,调用查询方法失败,报错“abs链码未安装”,应该是客户端把请求发到了未安装链码的两个节点,基于此原因,补充本节内容。

补充安装链码的步骤如下:

(1) 从已安装的peer节点获取安装包

# 下载链码包
peer lifecycle chaincode getinstalledpackage --package-id abs_1:013a79f868db17429c3195acacc08ae376994c5a9fb32d2302bef7f49f0354f7
# 重命名链码包
mv abs_1\:013a79f868db17429c3195acacc08ae376994c5a9fb32d2302bef7f49f0354f7.tar.gz abs.tar.gz

(2)在org1.peer1和org2.peer1节点上安装链码

# 切换环境到org1.peer1
source scripts/utils.sh
setGablobs 1 1
# 执行安装命令
peer lifecycle chaincode queryinstalled
setGablobs 1 2
# 执行安装命令
peer lifecycle chaincode queryinstalled

(3) 获得org1和org2两个组织的认证

本过程最重要的是注意sequence参数值,该值必须在sequence最新值上增加1,查询该链码最新的sequence值,执行如下命令:

peer lifecycle chaincode querycommitted --channelID mychannel --name abs

假如链码abs的sequence最新值为2,则获取组织认证命令如下:

peer lifecycle chaincode approveformyorg --tls true --cafile $ORDERER_CA --channelID mychannel --name abs --version 1 --init-required --package-id abs_1:013a79f868db17429c3195acacc08ae376994c5a9fb32d2302bef7f49f0354f7 --sequence 3 --waitForEvent

切换到另外1个组织的任意节点,执行上述相同的命令。

最后查看认证结果,必须两个组织都认证通过才行。

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name abs --version 1 --sequence 3 --output json --init-required

(4) 提交链码

提交代码同样需要注意修改sequence参数即可,命令如下:

peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA --channelID mychannel --name abs --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 3 --init-required

当org1.peer1和org2.peer1两个节点成功安装链码之后,ContractAPI的样例代码才能运行成功,如果还是有问题,则需要检查证书文件。

区块链Hyperleger Fabric2.0 总结分享PPT下载

文章作者:xiaohui249
本文链接:http://javatech.wang/index.php/archives/153/
版本所有 ©转载时必须以链接形式注明作者和原始出处

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 下面是一个简单的 Hyperledger Fabric 2.0 Go语言链码示例: ``` package main import ( "fmt" "github.com/hyperledger/fabric-chaincode-go/shim" pb "github.com/hyperledger/fabric-protos-go/peer" ) // SimpleChaincode example simple Chaincode implementation type SimpleChaincode struct { } func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { fmt.Println("ex02 Init") _, args := stub.GetFunctionAndParameters() var A, B string // Entities var Aval, Bval int // Asset holdings var err error if len(args) != 4 { return shim.Error("Incorrect number of arguments. Expecting 4") } // Initialize the chaincode A = args[0] Aval, err = strconv.Atoi(args[1]) if err != nil { return shim.Error("Expecting integer value for asset holding") } B = args[2] Bval, err = strconv.Atoi(args[3]) if err != nil { return shim.Error("Expecting integer value for asset holding") } fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // Write the state to the ledger err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return shim.Error(err.Error()) } return shim.Success(nil) } func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { fmt.Println("ex02 Invoke") function, args := stub.GetFunctionAndParameters() if function == "invoke" { // Make payment of X units from A to B return t.invoke(stub, args) } else if function == "delete" { // Deletes an entity from its state return t.delete(stub, args) } else if function == "query" { // the old "Query" is now implemtned in invoke return t.query(stub, args) } return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"") } // Transaction makes payment of X units from A to B func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { var A, B string // Entities var Aval, Bval int // Asset holdings var X int // Transaction value var err error ### 回答2: Hyperledger Fabric 是一个开源的区块链平台,可以用于构建企业级的去中心化应用程序。而 Hyperledger Fabric 2.0 是其最新版本,引入了许多新特性和改进。 编写一个 Hyperledger Fabric 2.0 的 Go 语言链码需要按照一定的流程进行: 1. 准备开发环境:首先,需要安装 Go 语言的开发环境和 Hyperledger Fabric 的相关工具,如 Hyperledger Fabric SDK 和 Hyperledger Fabric CA。 2. 编写链码逻辑:使用 Go 语言编写链码的逻辑,链码是在 Hyperledger Fabric 上运行的智能合约。可以根据项目需求和业务逻辑定义相关的数据结构和函数。 3. 定义链码接口:需要定义链码接口,包括 Init 和 Invoke 两个核心函数。Init 函数用于链码的初始化操作,而 Invoke 函数用于链码的业务逻辑执行。 4. 部署链码:将编写好的链码部署到 Hyperledger Fabric 网络中。可以使用 Hyperledger Fabric SDK 提供的工具和 API 来进行链码的部署操作。 5. 测试链码:编写相应的测试用例,对链码逻辑进行测试。可以使用模拟的 Fabric 网络进行测试,或者与实际的 Fabric 网络交互进行测试。 6. 部署链码应用程序:将编写好的链码应用程序部署到 Hyperledger Fabric 网络上。可以使用 Hyperledger Fabric SDK 提供的工具和 API 来进行链码应用程序的部署操作。 Go 语言是一种高性能的编程语言,适合于开发区块链平台和链码。编写 Hyperledger Fabric 2.0 的 Go 语言链码需要熟悉 Go 语言的基本语法和特性,以及了解 Hyperledger Fabric 的相关知识。通过合理的设计和编码,可以实现各种复杂的业务逻辑和功能。 ### 回答3: 编写一个Hyperledger Fabric 2.0的Go语言链码可以分为以下几个步骤: 1. 准备开发环境:首先,需要在开发机器上安装Go语言和Hyperledger Fabric的相关依赖。可以通过配置Golang环境变量,并使用Golang包管理器安装Fabric的Go SDK。 2. 创建链码项目:使用Go语言的IDE或文本编辑器创建一个新的文件夹,作为链码项目的根目录。 3. 定义链码结构:创建一个新的Go文件,并定义链码结构。链码结构应该实现fabric的Chaincode接口,并实现Init和Invoke两个方法。 4. 实现Init方法:Init方法在链码被实例化时调用,并进行初始化设置。可以在该方法中初始化链码的状态数据和其他必要的准备工作。 5. 实现Invoke方法:Invoke方法在链码接收到调用请求时被调用。在该方法中处理具体的业务逻辑,并根据请求中的操作类型执行相应的操作。 6. 将链码打包:使用Fabric提供的命令行工具将链码打包成压缩文件,以便于后续部署和安装。 7. 部署和安装链码:使用Fabric提供的链码生命周期管理工具,将链码部署到指定的Fabric网络中,并安装到指定的通道上。 8. 实例化链码:在指定的通道上实例化链码,使其可以被其他参与方调用。 9. 调用链码:使用Fabric提供的客户端SDK或命令行工具,向链码发送调用请求,验证链码的功能和逻辑是否正确。 10. 测试链码:编写一些测试用例,用于对链码的功能和性能进行验证。 以上是一个简要的步骤,编写Hyperledger Fabric 2.0的Go语言链码还需要进一步了解链码开发的相关知识和Fabric的API,以有效地实现业务逻辑,并与Fabric网络进行交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萧十一郎君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值