Chaincode 结构 shim.ChaincodeStubInterface 接口有三个方法,分别是:Init、Query 和 Invoke 16.7.1. 导入库 import ( "fmt" "strconv" "github.com/hyperledger/fabric/core/chaincode/shim" pb "github.com/ 当对peer节点部署chaincode并实例化时,就会执行 main 函数。 = nil { fmt.Printf("Error starting Simple chaincode: %s", err) } } shim.Start(new(SampleChaincode package main import ( "bytes" "encoding/json" "fmt" "strconv" "github.com/hyperledger/fabric/core/chaincode
开发环境 6.2. chaincode 代码 6.3. 启动容器部署chaincode 6.4. 测试 6.1. /chaincode|. 代码 [root@localhost chaincode-docker-devmode]# cat chaincode/chaincode_example02.go /* Copyright IBM ID is hard-coded in chaincode_example04 to illustrate one way of //calling chaincode from a chaincode build chaincode_example02.go root@78d23b3b2b37:/opt/gopath/src/chaincode# 进入 chaincode 容器启动 chaincode
fabric智能合约-chaincode接口: package shim import ( "github.com/hyperledger/fabric/protos/peer" ) // ChaincodeStubInterface provides the shim interface of a chaincode invocation type ChaincodeStubInterface interface { // State The totalQueryLimit is intended to be // set by a chaincode's MSP policies at install or instantiation Setting totalQueryLimit to zero will allow a chaincode to read any number of keys. value of the specified `key` from the transient store GetTransient(key string) ([]byte, error) // Chaincode
Fabric的开发主要分成2部分,ChainCode链上代码开发和基于SDK的Application开发。我们这里先讲ChainCode的开发。 Fabric的链上代码支持Java或者Go语言进行开发,因为Fabric本身是Go开发的,所以深蓝建议还是用Go进行ChainCode的开发。 ChainCode的Go代码需要定义一个SimpleChaincode这样一个struct,然后在该struct上定义Init和Invoke两个函数,然后还要定义一个main函数,作为ChainCode 以下是ChainCode的模板: package main import ( "github.com/hyperledger/fabric/core/chaincode/shim" pb 增删改查State DB 对于ChainCode来说,核心的操作就是对State Database的增删改查,对此Fabric接口提供了3个对State DB的操作方法。
分析github.com/hyperledger/fabric/internal/peer/chaincode包 一,探索思路 这个目录的tree是这样的 . ├── chaincode.go ├── connectionprofile.yaml │ └── src │ └── chaincodes │ └── noop │ └── chaincode.go ├── upgrade.go └── upgrade_test.go 显而易见,我们要探索的命令: peer chaincode query -C winechannel -n mycontract SPDX-License-Identifier: Apache-2.0 */ package chaincode import ( "errors" "fmt" github.com/spf13/cobra" ) var chaincodeQueryCmd *cobra.Command // queryCmd returns the cobra command for Chaincode
分析github.com/hyperledger/fabric/internal/peer/chaincode包 一,探索思路 这个目录的tree是这样的 . ├── chaincode.go ├── -c '{"Args":["GetAllWines"]}' chaincode.go和query.go 是关键! 2,上源码 (1)chaincode.go /* Copyright IBM Corp. All Rights Reserved. , "The name of the verification system chaincode to be used for this chaincode") 常量和全局变量: const ( chainFuncName = "chaincode" chainCmdDes = "Operate a chaincode: install
2.Chaincode类——拥有Chaincode 我们的Chaincode应该提供以下功能: 1.创建一个钱包。 Init函数必须在Chaincode中实现,并且每当我们实例化或升级Chaincode时都会自动调用。通常,它用于初始化区块链中的一些数据。 第4步——Chaincode类 package org.hyperledger.fabric.chaincode; import java.util.List; import org.hyperledger.fabric.chaincode.Models.Wallet fabric-samples/chaincode/chaincode_example02/java/: ? /byfn.sh down 然后,删除目录fabric-samples/chaincode/chaincode_example02/java并将目录java_01重命名为java。 谢谢!
在fabric开发中,chaincode的测试是一个令人比较头疼的问题,一是由于实际情况中chaincode中的存储和查询是依赖于peer节点上的状态数据库的,所以无法在本地直接测试;二是由于chaincode /chaincode:/opt/gopath/src/chaincode 说明fabric-samples/chaincode目录会映射到容器内部,这也是我们待测试链码需要放置的地方。 终端二:编译链码 进入chaincode容器 docker exec -it chaincode bash 编译想要测试的chaincode: cd sacc go build 成功执行后单当前目录下会出现生成的可执行文件 : error sending chaincode REGISTER。 /chaincode/sacc -n mycc -v 0 peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a","10"]}' -C myc
标准输出, attachStdout: false 逆向从链码调用到docker操作源码表 core/container/util/dockerutil.go NewDockerClient core/chaincode /platforms/util/utils.go DockerBuild core/chaincode/platforms/golang/platform.go GenerateDockerBuild core/chaincode/platforms/platforms.go StreamDockerBuild GenerateDockerBuild core/container/controller.go /container_runtime.go Start LaunchConfig core/chaincode/runtime_launcher.go Launch core/chaincode/chaincode_support.go /support.go Execute core/endorser/endorser.go callChaincode SimulateProposal ProcessProposal peer/chaincode
examples/chaincode/go/chaincode_example02 这时候 chaincode 代码已经安装到了 peer0 节点上,但并未实例化运行。 examples/chaincode/go/chaincode_example02 4. 实例化chaincode chaincode 的实例化可在任意 peer 上进行,并且 chaincode 只能被实例化一次,下面以在 peer0.org2.example.com 上实例化 chaincode 2.6 更新chaincode 通过 channel upgrade 命令可以使得 chaincode 更新到最新的版本,而低版本 chaincode 将不能再使用。 /hyperledger/fabric/examples/chaincode/go/chaincode_example02 在 VM1 的 cli 容器升级 chaincode ,添加两个变量 ‘c’和
/my-fabric-chaincode-java 四、代码解析 在 Fabric 2.x 版本后的合约编写方式与旧版本略有不同,需要实现 ContractInterface 接口,下面是官方的一段说明 : All chaincode implementations must extend the abstract class ChaincodeBase. It is possible to implement chaincode by extending ChaincodeBase directly however new projects should </groupId> <artifactId>fabric-chaincode-shim</artifactId> <version>${fabric-chaincode-java.version 查询数据使用 peer chaincode query [flags],该命令不会生成交易。 由于 invoke 命令所需要的参数较多,所以我们先创建一个脚本命令。
BYFN 链码例子 路径/fabric-samples/chaincode/chaincode_example02/go/chaincode_example02.go /* Copyright IBM ID is hard-coded in chaincode_example04 to illustrate one way of //calling chaincode from a chaincode //chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of //hard-coding to the chaincode. docker exec -it cli bash peer chaincode install -p chaincodedev/chaincode/sacc -n mycc -v 0 peer chaincode
%{chaincode}.%{success} histogram The time to launch a chaincode. chaincode.launch_failures. %{chaincode} counter The number of chaincode launches that have failed. chaincode.launch_timeouts. %{chaincode}. %{chaincode}. %{chaincode}.
mainCmd.AddCommand(chaincode.Cmd(nil, cryptoProvider)) 添加了一个命令 chaincode.Cmd(nil, cryptoProvider) 到 mainCmd 关键在这一句mainCmd.AddCommand(chaincode.Cmd(nil, cryptoProvider)) 添加了一个命令 chaincode.Cmd(nil, cryptoProvider 有这句,导致我们在命令行使用peer命令,后面可以加chaincode 四,深入分析mainCmd.AddCommand(chaincode.Cmd(nil, cryptoProvider))这一句 首先 ,根据代码导入的包路径可以确定,chaincode.Cmd 函数来自于 "github.com/hyperledger/fabric/internal/peer/chaincode" 包。 通过添加这个命令,可以在运行程序时使用 peer chaincode 命令执行与链码相关的操作,例如安装、实例化、升级、查询等。
,编译链码,并启动 docker exec -it chaincode bash cd hello/ go build ? CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./hello ? 五、新开一个终端,进入docker容器,操作链码 docker exec -it cli bash 安装链码 peer chaincode install -p chaincodedev/chaincode 实例化链码 peer chaincode instantiate -n mycc -v 0 -c '{"Args":["str","HelloWorld"]}' -C myc ? 查询链码 peer chaincode query -n mycc -c '{"Args":["get","str"]}' -C myc ?
比如,一个特定的用户ID可以执行chaincode应用,但是无法部署新的chaincode。 用户之间相互知道身份,但是并不知道相互之间做了什么。 Chaincode定义资产所有权变更的参数,例如,确保转让所有权的所有交易都遵守相同的规则和要求。System chaincode 是定义了整个channel操作参数的chaincode。 生命周期和配置system chaincode定义channle的规则;背书和验证system chaincode定义了背书和验证交易的需求。 Chaincode Chaincode 是定义资产和修改资产的交易指令的软件。也就是说,它就是业务逻辑。chaincode执行读取和修改键值对和其它状态数据库信息的规则。 Chaincode仅安装在需要获取资产状态来执行读写操作的peers(换句话说,如果一个chaincode没有安装一个peer,它将不能与账本交互)。
/fabcar/go peer lifecycle chaincode package fabcar.tar.gz --path /opt/fabric-samples-master/chaincode install fabcar.tar.gz 输出: 2020-11-16 13:34:09.269 CST [cli.lifecycle.chaincode] submitInstallProposal /fabcar/go peer lifecycle chaincode install fabcar.tar.gz 输出: 2020-11-16 13:47:37.740 CST [cli.lifecycle.chaincode invoke successful. result: status:200 至此智能合约部署完成 调用智能合约 查询所有汽车 peer chaincode query -C mychannel -n invoke successful. result: status:200 查询刚刚新增的车辆 peer chaincode query -C mychannel -n fabcar -c '{"Args
:java:Example:classes :examples:chaincode:java:Example:jar :examples:chaincode:java:Example:startScripts :examples:chaincode:java:Example:distTar :examples:chaincode:java:Example:distZip :examples:chaincode :java:Example:assemble :examples:chaincode:java:Example:compileTestJava UP-TO-DATE :examples:chaincode :examples:chaincode:java:Example:test UP-TO-DATE :examples:chaincode:java:Example:check UP-TO-DATE : examples:chaincode:java:Example:build :examples:chaincode:java:Example:copyToLib BUILD SUCCESSFUL
collections FAB-13581: memberOnlyWrite collection configuration option FAB-13527: GetPrivateDataHash chaincode API FAB-12043: Option to include private data in block events 外部链码启动器 FAB-13584: External chaincode FAB-15366: Logger removed from chaincode shim, 链码日志记录认为开发者自己的职责, 考虑下分布式日志ELK这些方案。 FAB-16213: The go chaincode entities extension has been removed, 以前有扩展包? FAB-12075: Client Identity (CID) library has moved, 移动到fabric-chaincode-go仓库下的/pkg/cid.
/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init 3.1.3调用ChainCode 接下来,我们让a给b转账10元,运行命令: peer chaincode invoke -n ${CC_ID} -c '{"Function": "invoke", " 3.2.1通过REST API部署GO语言的ChainCode POST 192.168.100.129:7050/chaincode Body是: { "jsonrpc": "2.0", 3.2.3通过REST API调用ChainCode 我们试着从a向b转账100元: POST 192.168.100.129:7050/chaincode Body内容是: { "jsonrpc