上个版本的chaincode有很多功能不完备,所以要部署新版本的chaincode。Fabric支持在保留现有状态的前提对chaincode进行升级。

一.新版chaincode

新版本的chaincode增加的功能如下:

1.增加了数据追溯功能,在社区用户发起transaction时,chaincode将自动在用户证书中提取用户信息,将其存储在帖子的字段里。

2.加入了敏感词监管功能,敏感词字典和敏感词过滤功能在外部提供,chaincode通过http api(post 请求)调用服务。

3.加入了模糊查询功能。

chaincode代码:

package main

import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
"net/http"
"io/ioutil"
"crypto/x509"
"encoding/pem" "github.com/hyperledger/fabric/core/chaincode/shim"
sc "github.com/hyperledger/fabric/protos/peer"
) type SmartContract struct {
} type Post struct {
Id string `json:"id"`
OriginalWebsite string `json:"originalwebsite"`
OriginalID string `json:"originalid"`
Title string `json:"title"`
Content string `json:"content"`
AuthorId string `json:"authorid"`
PublishTime string `json:"publishtime"`
UpdateTime string `json:"updatetime"`
Category string `json:"category"`
SourceId string `json:"sourceid"`
Labels string `json:"labels"`
Follower_num int `json:"follower_num"`
Browse_num int `json:"browse_num"`
Star_num int `json:"star_num"`
UserName string `json:"username"`
} type PostLength struct {
Length int `json:"length"`
} func (s *SmartContract) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
return shim.Success(nil)
} func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response { function, args := APIstub.GetFunctionAndParameters() if function == "queryPost" {
return s.queryPost(APIstub, args)
} else if function == "initLedger" {
return s.initLedger(APIstub)
} else if function == "addPost" {
return s.addPost(APIstub, args)
} else if function == "updatePost" {
return s.updatePost(APIstub, args)
} else if function == "richQueryPosts" {
return s.richQueryPosts(APIstub, args)
} else if function == "getPostNum" {
return s.getPostNum(APIstub, args)
}
return shim.Error("Invalid Smart Contract function name.")
} func (s *SmartContract) queryPost(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
postAsBytes, _ := APIstub.GetState(args[0])
return shim.Success(postAsBytes)
} func (s *SmartContract) initLedger(APIstub shim.ChaincodeStubInterface) sc.Response {
creatorByte,_:= APIstub.GetCreator()
certStart := bytes.IndexAny(creatorByte, "-----BEGIN")
if certStart == -1 {
fmt.Errorf("No certificate found")
}
certText := creatorByte[certStart:]
bl, _ := pem.Decode(certText)
if bl == nil {
fmt.Errorf("Could not decode the PEM structure")
} cert, err := x509.ParseCertificate(bl.Bytes)
if err != nil {
fmt.Errorf("ParseCertificate failed")
}
uname:=cert.Subject.CommonName posts := []Post{
Post{Id: "1", OriginalWebsite: "b", OriginalID: "c", Title: "如何学习人工智能呢?",Content:"好好学习",AuthorId:"f",PublishTime:"g",UpdateTime:"h",Category:"i",SourceId:"j",Labels:"k",Follower_num:100,Browse_num:200,Star_num:300,UserName:uname},
Post{Id: "2", OriginalWebsite: "bb", OriginalID: "bb", Title: "目前大数据有什么用呢?",Content:"没用",AuthorId:"ff",PublishTime:"gg",UpdateTime:"hh",Category:"ii",SourceId:"jj",Labels:"kk",Follower_num:400,Browse_num:500,Star_num:600,UserName:uname},
}
length := PostLength{Length:len(posts)}
lengthAsBytes,_ := json.Marshal(length)
APIstub.PutState("POSTLENGTH",lengthAsBytes) i := 0
for i < len(posts) {
fmt.Println("i is ", i)
postAsBytes, _ := json.Marshal(posts[i])
APIstub.PutState("POST"+strconv.Itoa(i), postAsBytes)
fmt.Println("Added", posts[i])
i = i + 1
} return shim.Success(nil)
} func (s *SmartContract) addPost(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 13 {
return shim.Error("Incorrect number of arguments. Expecting 13")
} filteredtitle := sensitiveSupervision(args[2])
filteredcontent := sensitiveSupervision(args[3]) creatorByte,_:= APIstub.GetCreator()
certStart := bytes.IndexAny(creatorByte, "-----BEGIN")
if certStart == -1 {
fmt.Errorf("No certificate found")
}
certText := creatorByte[certStart:]
bl, _ := pem.Decode(certText)
if bl == nil {
fmt.Errorf("Could not decode the PEM structure")
} cert, err := x509.ParseCertificate(bl.Bytes)
if err != nil {
fmt.Errorf("ParseCertificate failed")
}
uname:=cert.Subject.CommonName args10,error := strconv.Atoi(args[10])
args11,error := strconv.Atoi(args[11])
args12,error := strconv.Atoi(args[12]) if error != nil{
fmt.Println("String conversion integer failed!")
}
lengthAsBytes, _ := APIstub.GetState("POSTLENGTH")
length := PostLength{}
json.Unmarshal(lengthAsBytes,&length)
newlength := length.Length+1
var post = Post{Id: strconv.Itoa(newlength), OriginalWebsite: args[0], OriginalID: args[1], Title: filteredtitle,Content:filteredcontent,AuthorId:args[4],PublishTime:args[5],UpdateTime:args[6],Category:args[7],SourceId:args[8],Labels:args[9],Follower_num:args10,Browse_num:args11,Star_num:args12,UserName:uname}
postAsBytes, _ := json.Marshal(post)
APIstub.PutState("POST"+strconv.Itoa(newlength), postAsBytes)
length.Length = newlength
lengthAsBytes,_ = json.Marshal(length)
APIstub.PutState("POSTLENGTH",lengthAsBytes)
return shim.Success(lengthAsBytes)
} func (s *SmartContract) updatePost(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 14 {
return shim.Error("Incorrect number of arguments. Expecting 14")
} filteredtitle := sensitiveSupervision(args[3])
filteredcontent := sensitiveSupervision(args[4]) creatorByte,_:= APIstub.GetCreator()
certStart := bytes.IndexAny(creatorByte, "-----BEGIN")
if certStart == -1 {
fmt.Errorf("No certificate found")
}
certText := creatorByte[certStart:]
bl, _ := pem.Decode(certText)
if bl == nil {
fmt.Errorf("Could not decode the PEM structure")
} cert, err := x509.ParseCertificate(bl.Bytes)
if err != nil {
fmt.Errorf("ParseCertificate failed")
}
uname:=cert.Subject.CommonName args11,error := strconv.Atoi(args[11])
args12,error := strconv.Atoi(args[12])
args13,error := strconv.Atoi(args[13])
if error != nil{
fmt.Println("String conversion integer failed!")
}
var post = Post{Id: args[0], OriginalWebsite: args[1], OriginalID: args[2], Title: filteredtitle,Content:filteredcontent,AuthorId:args[5],PublishTime:args[6],UpdateTime:args[7],Category:args[8],SourceId:args[9],Labels:args[10],Follower_num:args11,Browse_num:args12,Star_num:args13,UserName:uname}
postAsBytes, _ := json.Marshal(post)
APIstub.PutState("POST"+args[0], postAsBytes)
return shim.Success(nil)
} func (s *SmartContract) richQueryPosts(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 3 {
return shim.Error("Incorrect number of arguments. Expecting 3")
} var queryString string if args[1] == "0" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":\"%s\"}}", args[0],args[2])
} else if args[1] == "1" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$gt\":%s}}}", args[0],args[2])
} else if args[1] == "2" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$gte\":%s}}}", args[0],args[2])
} else if args[1] == "3" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$lt\":%s}}}", args[0],args[2])
} else if args[1] == "4" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$lte\":%s}}}", args[0],args[2])
} else if args[1] == "5" {
between := strings.Split(args[2], ",")
queryString = fmt.Sprintf("{\"selector\":{\"$and\":[{\"%s\":{\"$gte\":%s}},{\"%s\":{\"$lte\":%s}}]}}", args[0],between[0],args[0],between[1])
} else if args[1] == "6" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$regex\":\"(?i)%s\"}}}", args[0],args[2])
} else {
return shim.Error("Incorrect number of arguments. Expecting 0~6")
} resultsIterator, err := APIstub.GetQueryResult(queryString)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close() var buffer bytes.Buffer
buffer.WriteString("[") bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
} if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"Key\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.Key)
buffer.WriteString("\"") buffer.WriteString(", \"Record\":") buffer.WriteString(string(queryResponse.Value))
buffer.WriteString("}")
bArrayMemberAlreadyWritten = true
}
buffer.WriteString("]") fmt.Printf("- richQueryPosts:\n%s\n", buffer.String()) return shim.Success(buffer.Bytes())
} func (s *SmartContract) getPostNum(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 3 {
return shim.Error("Incorrect number of arguments. Expecting 3")
}
var queryString string if args[1] == "0" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":\"%s\"}}", args[0],args[2])
} else if args[1] == "1" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$gt\":%s}}}", args[0],args[2])
} else if args[1] == "2" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$gte\":%s}}}", args[0],args[2])
} else if args[1] == "3" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$lt\":%s}}}", args[0],args[2])
} else if args[1] == "4" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$lte\":%s}}}", args[0],args[2])
} else if args[1] == "5" {
between := strings.Split(args[2], ",")
queryString = fmt.Sprintf("{\"selector\":{\"$and\":[{\"%s\":{\"$gte\":%s}},{\"%s\":{\"$lte\":%s}}]}}", args[0],between[0],args[0],between[1])
} else if args[1] == "6" {
queryString = fmt.Sprintf("{\"selector\":{\"%s\":{\"$regex\":\"(?i)%s\"}}}", args[0],args[2])
} else {
return shim.Error("Incorrect number of arguments. Expecting 0~6")
} resultsIterator, err := APIstub.GetQueryResult(queryString)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close() i := 0 for resultsIterator.HasNext() {
resultsIterator.Next() i = i + 1 } fmt.Printf("- getPostNum:\n%s\n", strconv.Itoa(i)) return shim.Success([]byte(strconv.Itoa(i)))
} func sensitiveSupervision(arg string) string {
quertString := fmt.Sprintf("{\"content\":\"%s\"}",arg)
resp, err := http.Post("http://敏感监管url",
"application/x-www-form-urlencoded",
strings.NewReader(quertString))
if err != nil {
fmt.Println(err)
} defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil { } return string(body) } func main() {
err := shim.Start(new(SmartContract))
if err != nil {
fmt.Printf("Error creating new Smart Contract: %s", err)
}
}

 

二.升级链码步骤

2.1 从宿主机将chaincode拷贝进容器

docker cp community2. cli:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go

2.2 安装新版本chaincode,打包到peer节点

docker exec -it cli bash
peer chaincode install -n mycc -v 2.0 -p github.com/hyperledger/fabric/examples/chaincode/go/community2.

2.3 升级chaincode

peer chaincode upgrade -o orderer.example.com: --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 -v 2.0 -c '{"Args":["init"]}' -P "OR      ('Org1MSP.member','Org2MSP.member')"

这样chaincode就升级完毕了。

搭建基于hyperledger fabric的联盟社区(七) --升级chaincode的更多相关文章

  1. 搭建基于hyperledger fabric的联盟社区(六) --搭建node.js服务器

    接下来我要做的是用fabric sdk来做出应用程序,代替CLI与整个区块链网络交互.并且实现一个http API,向社区提供一个简单的接口,使社区轻松的与区块链交互. 官方虽然提供了Node.JS, ...

  2. 搭建基于hyperledger fabric的联盟社区(一) --前言

    三个月前上面发了一个关于智群汇聚和问题求解研究的项目,我们公司做其中的一个子项目,就是基于区块链的科技信息联盟构建.利用区块链的去中心化特性,构建一个基于区块链的科技社区,以提供科技群智汇聚采集的基础 ...

  3. 搭建基于hyperledger fabric的联盟社区(五) --启动Fabric网络

    现在所有的文件都已经准备完毕,我们可以启动fabric网络了. 一.启动orderer节点 在orderer服务器上运行: cd ~/go/src/github.com/hyperledger/fab ...

  4. 搭建基于hyperledger fabric的联盟社区(四) --chaincode开发

    前几章已经分别把三台虚拟机环境和配置文件准备好了,在启动fabric网络之前我们要准备好写好的chaincode.chaincode的开发一般是使用GO或者JAVA,而我选择的是GO语言.先分析一下官 ...

  5. 搭建基于hyperledger fabric的联盟社区(三) --生成公私钥证书及配置文件

    一.生成公私钥和证书 Fabric中有两种类型的公私钥和证书,一种是给节点之前通讯安全而准备的TLS证书,另一种是用户登录和权限控制的用户证书.这些证书本来应该是由CA来颁发,但是目前只有两个社区,所 ...

  6. 搭建基于hyperledger fabric的联盟社区(二) --环境配置

    接下来讲一下在本地测试区块链网络的过程.我要部署的是2peer+1orderer架构,所以需要准备三台虚拟机,为了方便起见可以先把一台配置好,然后复制出剩余两台即可.搭建虚拟机我用的是virtualb ...

  7. 搭建基于hyperledger fabric的联盟社区(八) --Fabric证书解析

    一.证书目录解析   通过cryptogen生成所有证书文件后,以peerOrgannizations的第一个组织树org1为例,每个目录和对应文件的功能如下:   ca: 存放组织的根证书和对应的私 ...

  8. 搭建基于hyperledger fabric的联盟社区(九) --检索状态数据库

    一.启动elasticsearch服务 官网下载压缩包解压,进入bin目录启动: ./elasticsearch 通过ip访问 localhost:9200,可以看到如下信息 { name: &quo ...

  9. Hyperledger Fabric定制联盟链网络工程实践

    总体来看,网络上成体系的可用的 Fabric 教程极少--不是直接在 Fabric 官网复制内容大谈基础理论就是在描述一个几乎无法复现的项目实践,以至于学习 Fabric 的效率极低,印象最深刻的就是 ...

随机推荐

  1. poj 1724 ROADS 很水的dfs

    题意:给你N个城市和M条路和K块钱,每条路有话费,问你从1走到N的在K块钱内所能走的最短距离是多少 链接:http://poj.org/problem?id=1724 直接dfs搜一遍就是 代码: # ...

  2. Putty实现Linux与Windows互传文件

    putty远程连接VPS,先开一贴,有空来整理. 从putty官网下载putty,选择[A Windows installer for everything except PuTTYtel]安装包,下 ...

  3. python __new__和__init__

    转载:http://www.cnblogs.com/tuzkee/p/3540293.html 1 2 3 4 5 6 7 8 class A(object):     def __init__(se ...

  4. TLS就是SSL的升级版+网络安全——一图看懂HTTPS建立过程——本质上就是引入第三方监管,web服务器需要先生成公钥和私钥,去CA申请,https通信时候浏览器会去CA校验CA证书的有效性

    起初是因为HTTP在传输数据时使用的是明文(虽然说POST提交的数据时放在报体里看不到的,但是还是可以通过抓包工具窃取到)是不安全的,为了解决这一隐患网景公司推出了SSL安全套接字协议层,SSL是基于 ...

  5. python3与python2中的string.join()函数

    在python2中,string 模块中有一个join()函数,用于以特定的分隔符分隔源变量中的字符串,将其作为新的元素加入到一个列表中,例如: body=string.join(( "Fr ...

  6. APUE学习笔记——4.2结构体 struct stat 及其相关函数介绍

    以下不少内容来自man手册 结构体struct stat         结构体struct stat用于保存文件相关的所有信息.         struct stat的基本成员如下所示 struc ...

  7. kmeans实现文本聚类

    需求 拿到的需求是输入n个文本,对文本进行聚类,由于这些输入不能通过历史数据进行训练,所以这个主要就是用无监督学习来解决. kmeans 谈到聚类就会想到kmeans,它的核心思想是给定的K值和K个初 ...

  8. 深度学习(六十四)Faster R-CNN物体检测

  9. Vue学习笔记 ——computed VS methods

    对于最终的结果,两种方式确实是相同的.然而,不同的是计算属性是基于它们的依赖进行缓存的.计算属性只有在它的相关依赖发生改变时才会重新求值.这就意味着只要 message 还没有发生改变,多次访问 re ...

  10. 使用gmock白盒测试

    提起白盒测试,很多程序员可能觉得就是个书上的概念,很多人写完代码根本没有具体的测试方案,自己觉得可行就提交了,其实这是个很危险的事情,毕竟出了bug,最后要加班的人还是你 ,因此做好白盒测试,100% ...