// Invoke or query a chaincode. func invoke(ctx context.Context, spec *pb.ChaincodeSpec, typ pb.Transaction_Type) (string, []byte, error) { chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} // Now create the Transactions message and send to Peer. uuid := util.GenerateUUID() transaction, err := pb.NewChaincodeExecute(chaincodeInvocationSpec, uuid, typ) if err != nil { return uuid, nil, fmt.Errorf("Error invoking chaincode: %s ", err) } var retval []byte var execErr error if typ == pb.Transaction_CHAINCODE_QUERY { retval, execErr = Execute(ctx, GetChain(DefaultChain), transaction) } else { ledger, _ := ledger.GetLedger() ledger.BeginTxBatch("1") retval, execErr = Execute(ctx, GetChain(DefaultChain), transaction) if err != nil { return uuid, nil, fmt.Errorf("Error invoking chaincode: %s ", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) } return uuid, retval, execErr }
// Deploy a chaincode - i.e., build and initialize. func deploy(ctx context.Context, spec *pb.ChaincodeSpec) ([]byte, error) { // First build and get the deployment spec chaincodeDeploymentSpec, err := getDeploymentSpec(ctx, spec) if err != nil { return nil, err } tid := chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := pb.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, tid) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") b, err := Execute(ctx, GetChain(DefaultChain), transaction) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return b, err }
func whoIsTheOwner(asset string) ([]byte, error) { chaincodeInput := &pb.ChaincodeInput{Function: "query", Args: []string{asset}} // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, ConfidentialityLevel: pb.ConfidentialityLevel_PUBLIC, } var ctx = context.Background() chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} tid := chaincodeInvocationSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := administrator.NewChaincodeQuery(chaincodeInvocationSpec, tid) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") result, err := chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return result, err }
func transferOwnership(owner crypto.Client, ownerCert crypto.CertificateHandler, asset string, newOwnerCert crypto.CertificateHandler) error { // Get a transaction handler to be used to submit the execute transaction // and bind the chaincode access control logic using the binding submittingCertHandler, err := owner.GetTCertificateHandlerNext() if err != nil { return err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return err } binding, err := txHandler.GetBinding() if err != nil { return err } chaincodeInput := &pb.ChaincodeInput{Function: "transfer", Args: []string{asset, string(newOwnerCert.GetCertificate())}} chaincodeInputRaw, err := proto.Marshal(chaincodeInput) if err != nil { return err } // Access control. Owner signs chaincodeInputRaw || binding to confirm his identity sigma, err := ownerCert.Sign(append(chaincodeInputRaw, binding...)) if err != nil { return err } // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, Metadata: sigma, // Proof of identity ConfidentialityLevel: pb.ConfidentialityLevel_PUBLIC, } var ctx = context.Background() chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} tid := chaincodeInvocationSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, tid) if err != nil { return fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") _, err = chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return err }
func deploy(admCert crypto.CertificateHandler) error { // Prepare the spec. The metadata includes the identity of the administrator spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: &pb.ChaincodeInput{Function: "init", Args: []string{}}, Metadata: admCert.GetCertificate(), ConfidentialityLevel: pb.ConfidentialityLevel_PUBLIC, } // First build and get the deployment spec var ctx = context.Background() chaincodeDeploymentSpec, err := getDeploymentSpec(ctx, spec) if err != nil { return err } tid := chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := administrator.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, tid) if err != nil { return fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") _, err = chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return err }
// CommitTxBatch gets invoked when the current transaction-batch needs // to be committed. This function returns successfully iff the // transactions details and state changes (that may have happened // during execution of this transaction-batch) have been committed to // permanent storage. func (h *Helper) CommitTxBatch(id interface{}, transactions []*pb.Transaction, transactionsResults []*pb.TransactionResult, metadata []byte) error { ledger, err := ledger.GetLedger() if err != nil { return fmt.Errorf("Failed to get the ledger: %v", err) } if err := ledger.CommitTxBatch(id, transactions, nil, metadata); err != nil { return fmt.Errorf("Failed to commit transaction to the ledger: %v", err) } return nil }
// CommitTxBatch gets invoked when the current transaction-batch needs // to be committed. This function returns successfully iff the // transactions details and state changes (that may have happened // during execution of this transaction-batch) have been committed to // permanent storage. func (h *Helper) CommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) { ledger, err := ledger.GetLedger() if err != nil { return nil, fmt.Errorf("Failed to get the ledger: %v", err) } // TODO fix this one the ledger has been fixed to implement if err := ledger.CommitTxBatch(id, h.curBatch, nil, metadata); err != nil { return nil, fmt.Errorf("Failed to commit transaction to the ledger: %v", err) } size := ledger.GetBlockchainSize() h.curBatch = nil // TODO, remove after issue 579 block, err := ledger.GetBlockByNumber(size - 1) if err != nil { return nil, fmt.Errorf("Failed to get the block at the head of the chain: %v", err) } return block, 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 }