//generateHashcode gets hashcode of the code under path. If path is a HTTP(s) url //it downloads the code first to compute the hash. //NOTE: for dev mode, user builds and runs chaincode manually. The name provided //by the user is equivalent to the path. This method will treat the name //as codebytes and compute the hash from it. ie, user cannot run the chaincode //with the same (name, ctor, args) func generateHashcode(spec *pb.ChaincodeSpec, path string) (string, error) { ctor := spec.CtorMsg if ctor == nil || ctor.Function == "" { return "", fmt.Errorf("Cannot generate hashcode from empty ctor") } hash := util.GenerateHashFromSignature(spec.ChaincodeID.Path, ctor.Function, ctor.Args) buf, err := ioutil.ReadFile(path) if err != nil { return "", fmt.Errorf("Error reading file: %s", err) } newSlice := make([]byte, len(hash)+len(buf)) copy(newSlice[len(buf):], hash[:]) //hash = md5.Sum(newSlice) hash = util.ComputeCryptoHash(newSlice) return hex.EncodeToString(hash[:]), nil }
//generateHashcode gets hashcode of the code under path. If path is a HTTP(s) url //it downloads the code first to compute the hash. //NOTE: for dev mode, user builds and runs chaincode manually. The name provided //by the user is equivalent to the path. This method will treat the name //as codebytes and compute the hash from it. ie, user cannot run the chaincode //with the same (name, ctor, args) func generateHashcode(spec *pb.ChaincodeSpec, tw *tar.Writer) (string, error) { if spec == nil { return "", fmt.Errorf("Cannot generate hashcode from nil spec") } chaincodeID := spec.ChaincodeID if chaincodeID == nil || chaincodeID.Path == "" { return "", fmt.Errorf("Cannot generate hashcode from empty chaincode path") } ctor := spec.CtorMsg if ctor == nil || ctor.Function == "" { return "", fmt.Errorf("Cannot generate hashcode from empty ctor") } //code root will point to the directory where the code exists //in the case of http it will be a temporary dir that //will have to be deleted var codegopath string var ishttp bool defer func() { if ishttp && codegopath != "" { os.RemoveAll(codegopath) } }() path := chaincodeID.Path var err error var actualcodepath string if strings.HasPrefix(path, "http://") { ishttp = true actualcodepath = path[7:] codegopath, err = getCodeFromHTTP(actualcodepath) } else if strings.HasPrefix(path, "https://") { ishttp = true actualcodepath = path[8:] codegopath, err = getCodeFromHTTP(actualcodepath) } else { actualcodepath = path codegopath, err = getCodeFromFS(path) } if err != nil { return "", fmt.Errorf("Error getting code %s", err) } tmppath := codegopath + "/src/" + actualcodepath if err = isCodeExist(tmppath); err != nil { return "", fmt.Errorf("code does not exist %s", err) } hash := util.GenerateHashFromSignature(actualcodepath, ctor.Function, ctor.Args) hash, err = hashFilesInDir(codegopath+"/src/", actualcodepath, hash, tw) if err != nil { return "", fmt.Errorf("Could not get hashcode for %s - %s\n", path, err) } return hex.EncodeToString(hash[:]), nil }
//generateHashcode gets hashcode of the code under path. If path is a HTTP(s) url //it downloads the code first to compute the hash. //NOTE: for dev mode, user builds and runs chaincode manually. The name provided //by the user is equivalent to the path. This method will treat the name //as codebytes and compute the hash from it. ie, user cannot run the chaincode //with the same (name, ctor, args) func generateHashcode(spec *pb.ChaincodeSpec, tw *tar.Writer) (string, error) { if spec == nil { return "", fmt.Errorf("Cannot generate hashcode from nil spec") } chaincodeID := spec.ChaincodeID if chaincodeID == nil || chaincodeID.Path == "" { return "", fmt.Errorf("Cannot generate hashcode from empty chaincode path") } ctor := spec.CtorMsg if ctor == nil || len(ctor.Args) == 0 { return "", fmt.Errorf("Cannot generate hashcode from empty ctor") } codepath := chaincodeID.Path var ishttp bool defer func() { if ishttp { os.RemoveAll(codepath) } }() var err error if strings.HasPrefix(codepath, "http://") || strings.HasPrefix(codepath, "https://") { ishttp = true codepath, err = getCodeFromHTTP(codepath) } else if !strings.HasPrefix(codepath, "/") { wd := "" wd, err = os.Getwd() codepath = wd + "/" + codepath } if err != nil { return "", fmt.Errorf("Error getting code %s", err) } if err = isCodeExist(codepath); err != nil { return "", fmt.Errorf("code does not exist %s", err) } root := codepath if strings.LastIndex(root, "/") == len(root)-1 { root = root[:len(root)-1] } root = root[:strings.LastIndex(root, "/")+1] ctorbytes, err := proto.Marshal(ctor) if err != nil { return "", fmt.Errorf("Error marshalling constructor: %s", err) } hash := util.GenerateHashFromSignature(codepath, ctorbytes) hash, err = hashFilesInDir(root, codepath, hash, tw) if err != nil { return "", fmt.Errorf("Could not get hashcode for %s - %s\n", codepath, err) } return hex.EncodeToString(hash[:]), nil }