// chaincodeInvokeOrQuery invokes or queries the chaincode. If successful, the // INVOKE form prints the transaction ID on STDOUT, and the QUERY form prints // the query result on STDOUT. A command-line flag (-r, --raw) determines // whether the query result is output as raw bytes, or as a printable string. // The printable form is optionally (-x, --hex) a hexadecimal representation // of the query response. If the query response is NIL, nothing is output. func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool) (err error) { if err = checkChaincodeCmdParams(cmd); err != nil { return } if chaincodeName == "" { err = errors.New("Name not given for invoke/query") return } devopsClient, err := getDevopsClient(cmd) if err != nil { err = fmt.Errorf("Error building %s: %s", chainFuncName, err) return } // Build the spec input := &pb.ChaincodeInput{} if err = json.Unmarshal([]byte(chaincodeCtorJSON), &input); err != nil { err = fmt.Errorf("Chaincode argument error: %s", err) return } chaincodeLang = strings.ToUpper(chaincodeLang) spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]), ChaincodeID: &pb.ChaincodeID{Name: chaincodeName}, CtorMsg: input} // If security is enabled, add client login token if viper.GetBool("security.enabled") { if chaincodeUsr == undefinedParamValue { err = errors.New("Must supply username for chaincode when security is enabled") return } // Retrieve the CLI data storage path // Returns /var/openchain/production/client/ localStore := getCliFilePath() // Check if the user is logged in before sending transaction if _, err = os.Stat(localStore + "loginToken_" + chaincodeUsr); err == nil { logger.Info("Local user '%s' is already logged in. Retrieving login token.\n", chaincodeUsr) // Read in the login token token, err := ioutil.ReadFile(localStore + "loginToken_" + chaincodeUsr) if err != nil { panic(fmt.Errorf("Fatal error when reading client login token: %s\n", err)) } // Add the login token to the chaincodeSpec spec.SecureContext = string(token) // If privacy is enabled, mark chaincode as confidential if viper.GetBool("security.privacy") { logger.Info("Set confidentiality level to CONFIDENTIAL.\n") spec.ConfidentialityLevel = pb.ConfidentialityLevel_CONFIDENTIAL } } else { // Check if the token is not there and fail if os.IsNotExist(err) { err = fmt.Errorf("User '%s' not logged in. Use the 'login' command to obtain a security token.", chaincodeUsr) return } // Unexpected error panic(fmt.Errorf("Fatal error when checking for client login token: %s\n", err)) } } // Build the ChaincodeInvocationSpec message invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} var resp *pb.Response if invoke { resp, err = devopsClient.Invoke(context.Background(), invocation) } else { resp, err = devopsClient.Query(context.Background(), invocation) } if err != nil { if invoke { err = fmt.Errorf("Error invoking %s: %s\n", chainFuncName, err) } else { err = fmt.Errorf("Error querying %s: %s\n", chainFuncName, err) } return } if invoke { transactionID := string(resp.Msg) logger.Info("Successfully invoked transaction: %s(%s)", invocation, transactionID) fmt.Println(transactionID) } else { logger.Info("Successfully queried transaction: %s", invocation) if resp != nil { if chaincodeQueryRaw { if chaincodeQueryHex { err = errors.New("Options --raw (-r) and --hex (-x) are not compatible\n") return } os.Stdout.Write(resp.Msg) } else { if chaincodeQueryHex { fmt.Printf("%x\n", resp.Msg) } else { fmt.Println(string(resp.Msg)) } } } } return nil }
// MakeGenesis creates the genesis block based on configuration in openchain.yaml // and adds it to the blockchain. func MakeGenesis() error { once.Do(func() { ledger, err := ledger.GetLedger() if err != nil { makeGenesisError = err return } if ledger.GetBlockchainSize() > 0 { // genesis block already exists return } genesisLogger.Info("Creating genesis block.") ledger.BeginTxBatch(0) var genesisTransactions []*protos.Transaction //We are disabling the validity period deployment for now, we shouldn't even allow it if it's enabled in the configuration allowDeployValidityPeriod := false if deploySystemChaincodeEnabled() && allowDeployValidityPeriod { vpTransaction, deployErr := deployUpdateValidityPeriodChaincode() if deployErr != nil { genesisLogger.Error("Error deploying validity period system chaincode for genesis block.", deployErr) makeGenesisError = deployErr return } genesisTransactions = append(genesisTransactions, vpTransaction) } genesis := viper.GetStringMap("ledger.blockchain.genesisBlock") if genesis == nil { genesisLogger.Info("No genesis block chaincodes defined.") } else { chaincodes, chaincodesOK := genesis["chaincode"].([]interface{}) if !chaincodesOK { genesisLogger.Info("No genesis block chaincodes defined.") ledger.CommitTxBatch(0, genesisTransactions, nil, nil) return } genesisLogger.Debug("Genesis chaincodes are %s", chaincodes) for i := 0; i < len(chaincodes); i++ { genesisLogger.Debug("Chaincode %d is %s", i, chaincodes[i]) chaincodeMap, chaincodeMapOK := chaincodes[i].(map[interface{}]interface{}) if !chaincodeMapOK { genesisLogger.Error("Invalid chaincode defined in genesis configuration:", chaincodes[i]) makeGenesisError = fmt.Errorf("Invalid chaincode defined in genesis configuration: %s", chaincodes[i]) return } path, pathOK := chaincodeMap["path"].(string) if !pathOK { genesisLogger.Error("Invalid chaincode URL defined in genesis configuration:", chaincodeMap["path"]) makeGenesisError = fmt.Errorf("Invalid chaincode URL defined in genesis configuration: %s", chaincodeMap["path"]) return } chaincodeType, chaincodeTypeOK := chaincodeMap["type"].(string) if !chaincodeTypeOK { genesisLogger.Error("Invalid chaincode type defined in genesis configuration:", chaincodeMap["type"]) makeGenesisError = fmt.Errorf("Invalid chaincode type defined in genesis configuration: %s", chaincodeMap["type"]) return } chaincodeID := &protos.ChaincodeID{Path: path, Name: ""} genesisLogger.Debug("Genesis chaincodeID %s", chaincodeID) genesisLogger.Debug("Genesis chaincode type %s", chaincodeType) constructorMap, constructorMapOK := chaincodeMap["constructor"].(map[interface{}]interface{}) if !constructorMapOK { genesisLogger.Error("Invalid chaincode constructor defined in genesis configuration:", chaincodeMap["constructor"]) makeGenesisError = fmt.Errorf("Invalid chaincode constructor defined in genesis configuration: %s", chaincodeMap["constructor"]) return } var spec protos.ChaincodeSpec if constructorMap == nil { genesisLogger.Debug("Genesis chaincode has no constructor.") spec = protos.ChaincodeSpec{Type: protos.ChaincodeSpec_Type(protos.ChaincodeSpec_Type_value[chaincodeType]), ChaincodeID: chaincodeID} } else { ctorFunc, ctorFuncOK := constructorMap["func"].(string) if !ctorFuncOK { genesisLogger.Error("Invalid chaincode constructor function defined in genesis configuration:", constructorMap["func"]) makeGenesisError = fmt.Errorf("Invalid chaincode constructor function args defined in genesis configuration: %s", constructorMap["func"]) return } ctorArgs, ctorArgsOK := constructorMap["args"].([]interface{}) if !ctorArgsOK { genesisLogger.Error("Invalid chaincode constructor args defined in genesis configuration:", constructorMap["args"]) makeGenesisError = fmt.Errorf("Invalid chaincode constructor args defined in genesis configuration: %s", constructorMap["args"]) return } genesisLogger.Debug("Genesis chaincode constructor func %s", ctorFunc) genesisLogger.Debug("Genesis chaincode constructor args %s", ctorArgs) var ctorArgsStringArray []string for j := 0; j < len(ctorArgs); j++ { ctorArgsStringArray = append(ctorArgsStringArray, ctorArgs[j].(string)) } spec = protos.ChaincodeSpec{Type: protos.ChaincodeSpec_Type(protos.ChaincodeSpec_Type_value[chaincodeType]), ChaincodeID: chaincodeID, CtorMsg: &protos.ChaincodeInput{Function: ctorFunc, Args: ctorArgsStringArray}} } transaction, _, deployErr := DeployLocal(context.Background(), &spec) if deployErr != nil { genesisLogger.Error("Error deploying chaincode for genesis block.", deployErr) makeGenesisError = deployErr return } genesisTransactions = append(genesisTransactions, transaction) } //for } //else genesisLogger.Info("Adding %d system chaincodes to the genesis block.", len(genesisTransactions)) ledger.CommitTxBatch(0, genesisTransactions, nil, nil) }) return makeGenesisError }
// chaincodeDeploy deploys the chaincode. On success, the chaincode name // (hash) is printed to STDOUT for use by subsequent chaincode-related CLI // commands. func chaincodeDeploy(cmd *cobra.Command, args []string) (err error) { if err = checkChaincodeCmdParams(cmd); err != nil { return } devopsClient, err := getDevopsClient(cmd) if err != nil { err = fmt.Errorf("Error building %s: %s", chainFuncName, err) return } // Build the spec input := &pb.ChaincodeInput{} if err = json.Unmarshal([]byte(chaincodeCtorJSON), &input); err != nil { err = fmt.Errorf("Chaincode argument error: %s", err) return } chaincodeLang = strings.ToUpper(chaincodeLang) spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]), ChaincodeID: &pb.ChaincodeID{Path: chaincodePath, Name: chaincodeName}, CtorMsg: input} // If security is enabled, add client login token if viper.GetBool("security.enabled") { logger.Debug("Security is enabled. Include security context in deploy spec") if chaincodeUsr == undefinedParamValue { err = errors.New("Must supply username for chaincode when security is enabled") return } // Retrieve the CLI data storage path // Returns /var/openchain/production/client/ localStore := getCliFilePath() // Check if the user is logged in before sending transaction if _, err = os.Stat(localStore + "loginToken_" + chaincodeUsr); err == nil { logger.Info("Local user '%s' is already logged in. Retrieving login token.\n", chaincodeUsr) // Read in the login token token, err := ioutil.ReadFile(localStore + "loginToken_" + chaincodeUsr) if err != nil { panic(fmt.Errorf("Fatal error when reading client login token: %s\n", err)) } // Add the login token to the chaincodeSpec spec.SecureContext = string(token) // If privacy is enabled, mark chaincode as confidential if viper.GetBool("security.privacy") { logger.Info("Set confidentiality level to CONFIDENTIAL.\n") spec.ConfidentialityLevel = pb.ConfidentialityLevel_CONFIDENTIAL } } else { // Check if the token is not there and fail if os.IsNotExist(err) { err = fmt.Errorf("User '%s' not logged in. Use the 'login' command to obtain a security token.", chaincodeUsr) return } // Unexpected error panic(fmt.Errorf("Fatal error when checking for client login token: %s\n", err)) } } chaincodeDeploymentSpec, err := devopsClient.Deploy(context.Background(), spec) if err != nil { err = fmt.Errorf("Error building %s: %s\n", chainFuncName, err) return } logger.Info("Deploy result: %s", chaincodeDeploymentSpec.ChaincodeSpec) fmt.Println(chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name) return nil }