github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/chaincode/platforms/java/hash.go (about) 1 /* 2 Copyright DTCC 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package java 18 19 import ( 20 "archive/tar" 21 "bytes" 22 "encoding/hex" 23 "fmt" 24 "io/ioutil" 25 "os" 26 "os/exec" 27 "strings" 28 29 "errors" 30 31 "github.com/golang/protobuf/proto" 32 "github.com/hyperledger/fabric/common/flogging" 33 "github.com/hyperledger/fabric/common/util" 34 ccutil "github.com/hyperledger/fabric/core/chaincode/platforms/util" 35 pb "github.com/hyperledger/fabric/protos/peer" 36 ) 37 38 var logger = flogging.MustGetLogger("java/hash") 39 40 func getCodeFromHTTP(path string) (codegopath string, err error) { 41 42 codegopath, err = ioutil.TempDir("", "javachaincode") 43 44 if err != nil { 45 return "", fmt.Errorf("Error creating temporary file: %s", err) 46 } 47 var out bytes.Buffer 48 49 cmd := exec.Command("git", "clone", path, codegopath) 50 cmd.Stderr = &out 51 cmderr := cmd.Run() 52 if cmderr != nil { 53 return "", fmt.Errorf("Error cloning git repository %s", cmderr) 54 } 55 56 return codegopath, nil 57 58 } 59 60 //collectChaincodeFiles collects chaincode files and generates hashcode for the 61 //package. If path is a HTTP(s) url it downloads the code first. 62 //NOTE: for dev mode, user builds and runs chaincode manually. The name provided 63 //by the user is equivalent to the path. This method will treat the name 64 //as codebytes and compute the hash from it. ie, user cannot run the chaincode 65 //with the same (name, input, args) 66 func collectChaincodeFiles(spec *pb.ChaincodeSpec, tw *tar.Writer) (string, error) { 67 if spec == nil { 68 return "", errors.New("Cannot collect chaincode files from nil spec") 69 } 70 71 chaincodeID := spec.ChaincodeId 72 if chaincodeID == nil || chaincodeID.Path == "" { 73 return "", errors.New("Cannot collect chaincode files from empty chaincode path") 74 } 75 76 codepath := chaincodeID.Path 77 78 var ishttp bool 79 defer func() { 80 if ishttp { 81 os.RemoveAll(codepath) 82 } 83 }() 84 85 var err error 86 if strings.HasPrefix(codepath, "http://") || 87 strings.HasPrefix(codepath, "https://") { 88 ishttp = true 89 codepath, err = getCodeFromHTTP(codepath) 90 } else if !strings.HasPrefix(codepath, "/") { 91 wd := "" 92 wd, err = os.Getwd() 93 codepath = wd + "/" + codepath 94 } 95 96 if err != nil { 97 return "", fmt.Errorf("Error getting code %s", err) 98 } 99 100 if err = ccutil.IsCodeExist(codepath); err != nil { 101 return "", fmt.Errorf("code does not exist %s", err) 102 } 103 104 var hash []byte 105 106 //install will not have inputs and we don't have to collect hash for it 107 if spec.Input == nil || len(spec.Input.Args) == 0 { 108 logger.Debugf("not using input for hash computation for %v ", chaincodeID) 109 } else { 110 inputbytes, err2 := proto.Marshal(spec.Input) 111 if err2 != nil { 112 return "", fmt.Errorf("Error marshalling constructor: %s", err) 113 } 114 hash = util.GenerateHashFromSignature(codepath, inputbytes) 115 } 116 117 hash, err = ccutil.HashFilesInDir("", codepath, hash, tw) 118 if err != nil { 119 return "", fmt.Errorf("Could not get hashcode for %s - %s\n", codepath, err) 120 } 121 122 return hex.EncodeToString(hash[:]), nil 123 }