zoukankan      html  css  js  c++  java
  • 搭建基于hyperledger fabric的联盟社区(七) --升级chaincode

    上个版本的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:
    %s
    ", 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:
    %s
    ", 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.0 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.0

    2.3 升级chaincode

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

    这样chaincode就升级完毕了。

  • 相关阅读:
    Node.js之使用Buffer类处理二进制数据
    node.js之require
    node.js之模块
    node.js之setTimeout()、clearTimeout()与 setInterval()与clearInterval()
    Node.js之包与npm包管理工具
    node.js基础知识
    运维之linux基础知识(一)
    node.js之调试器
    Ubuntu 18.04安装搜狗输入法
    微信小程序项目总结记账小程序(包括后端)
  • 原文地址:https://www.cnblogs.com/preminem/p/7874697.html
Copyright © 2011-2022 走看看