// 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 := createDeployTransaction(chaincodeDeploymentSpec, tid) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() if err != nil { return nil, fmt.Errorf("Failed to get handle to ledger: %s ", err) } 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 }
// Invoke or query a chaincode. func invoke(ctx context.Context, spec *pb.ChaincodeSpec, typ pb.Transaction_Type) (*pb.ChaincodeEvent, string, []byte, error) { chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} // Now create the Transactions message and send to Peer. uuid := util.GenerateUUID() var transaction *pb.Transaction var err error transaction, err = pb.NewChaincodeExecute(chaincodeInvocationSpec, uuid, typ) if err != nil { return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s ", err) } var retval []byte var execErr error var ccevt *pb.ChaincodeEvent if typ == pb.Transaction_CHAINCODE_QUERY { retval, ccevt, execErr = chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) } else { ledger, _ := ledger.GetLedger() ledger.BeginTxBatch("1") retval, ccevt, execErr = chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s ", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) } return ccevt, uuid, retval, execErr }
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{Args: util.ToChaincodeArgs("init")}, 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 }
func whoIsTheOwner(asset string) ([]byte, error) { chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs("query", 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 }
// 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, h.curBatchErrs, metadata); err != nil { return nil, fmt.Errorf("Failed to commit transaction to the ledger: %v", err) } size := ledger.GetBlockchainSize() defer func() { h.curBatch = nil // TODO, remove after issue 579 h.curBatchErrs = 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) } logger.Debugf("Committed block with %d transactions, intended to include %d", len(block.Transactions), len(h.curBatch)) return block, nil }
func transferOwnership(owner crypto.Client, ownerCert crypto.CertificateHandler, fromAttributes string, newOwnerCert crypto.CertificateHandler, toAttributes string, amount string) 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("role") if err != nil { return err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return err } chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs( "transferOwnership", base64.StdEncoding.EncodeToString(ownerCert.GetCertificate()), fromAttributes, base64.StdEncoding.EncodeToString(newOwnerCert.GetCertificate()), toAttributes, amount)} // 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 := 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 }
// MakeGenesis creates the genesis block 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 { genesisLogger.Info("Creating genesis block.") if makeGenesisError = ledger.BeginTxBatch(0); makeGenesisError == nil { makeGenesisError = ledger.CommitTxBatch(0, nil, nil, nil) } } }) return makeGenesisError }
func deploy2(ctx context.Context, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec) ([]byte, error) { tid := chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := createDeployTransaction(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 }
// 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 }
func read(invoker crypto.Client, invokerCert crypto.CertificateHandler) ([]byte, error) { // Get a transaction handler to be used to submit the query transaction // and bind the chaincode access control logic using the binding submittingCertHandler, err := invoker.GetTCertificateHandlerNext() if err != nil { return nil, err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return nil, err } binding, err := txHandler.GetBinding() if err != nil { return nil, err } chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs("read")} chaincodeInputRaw, err := proto.Marshal(chaincodeInput) if err != nil { return nil, err } // Access control: // invokerCert signs invokerCert.GetCertificate() || chaincodeInputRaw || binding to confirm his identity sigma, err := invokerCert.Sign(append(invokerCert.GetCertificate(), append(chaincodeInputRaw, binding...)...)) if err != nil { return nil, err } rbacMetadata := RBACMetadata{invokerCert.GetCertificate(), sigma} rbacMetadataRaw, err := asn1.Marshal(rbacMetadata) if err != nil { return nil, err } // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, Metadata: rbacMetadataRaw, 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.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 }
// MakeGenesis creates the genesis block based on configuration in core.yaml // and adds it to the blockchain. func MakeGenesis() error { once.Do(func() { ledger, err := ledger.GetLedger() if err != nil { makeGenesisError = err return } var genesisBlockExists bool if ledger.GetBlockchainSize() == 0 { genesisLogger.Info("Creating genesis block.") ledger.BeginTxBatch(0) } else { genesisBlockExists = true } var genesisTransactions []*protos.Transaction defer func() { if !genesisBlockExists && makeGenesisError == nil { genesisLogger.Info("Adding %d system chaincodes to the genesis block.", len(genesisTransactions)) ledger.CommitTxBatch(0, genesisTransactions, nil, nil) } }() //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 isDeploySystemChaincodeEnabled() && allowDeployValidityPeriod { vpTransaction, deployErr := deployUpdateValidityPeriodChaincode(genesisBlockExists) if deployErr != nil { genesisLogger.Error("Error deploying validity period system chaincode for genesis block.", deployErr) makeGenesisError = deployErr return } genesisTransactions = append(genesisTransactions, vpTransaction) } if getGenesis() == nil { genesisLogger.Info("No genesis block chaincodes defined.") } else { chaincodes, chaincodesOK := genesis["chaincodes"].(map[interface{}]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 := range chaincodes { name := i.(string) genesisLogger.Debug("Chaincode %s", name) chaincode := chaincodes[name] chaincodeMap, chaincodeMapOK := chaincode.(map[interface{}]interface{}) if !chaincodeMapOK { genesisLogger.Error("Invalid chaincode defined in genesis configuration:", chaincode) makeGenesisError = fmt.Errorf("Invalid chaincode defined in genesis configuration: %s", chaincode) 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 } if chaincodeType == "" { chaincodeType = "GOLANG" } chaincodeID := &protos.ChaincodeID{Path: path, Name: name} genesisLogger.Debug("Genesis chaincodeID %s", chaincodeID) 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 { _, ctorArgsOK := constructorMap["args"] 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 } ctorArgs, ctorArgsOK := constructorMap["args"].([]interface{}) var ctorArgsStringArray []string if ctorArgsOK { genesisLogger.Debug("Genesis chaincode constructor args %s", ctorArgs) 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{Args: ctorArgsStringArray}} } transaction, _, deployErr := DeployLocal(context.Background(), &spec, genesisBlockExists) if deployErr != nil { genesisLogger.Error("Error deploying chaincode for genesis block.", deployErr) makeGenesisError = deployErr return } genesisTransactions = append(genesisTransactions, transaction) } //for } //else }) return makeGenesisError }
func addRole(admCert crypto.CertificateHandler, idCert crypto.CertificateHandler, role string) 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 := administrator.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: "addRole", Args: []string{string(idCert.GetCertificate()), role}} chaincodeInputRaw, err := proto.Marshal(chaincodeInput) if err != nil { return err } // Access control: // admCert signs admCert.GetCertificate() || chaincodeInputRaw || binding to confirm his identity sigma, err := admCert.Sign(append(admCert.GetCertificate(), append(chaincodeInputRaw, binding...)...)) if err != nil { return err } rbacMetadata := RBACMetadata{admCert.GetCertificate(), sigma} rbacMetadataRaw, err := asn1.Marshal(rbacMetadata) if err != nil { return err } // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, Metadata: rbacMetadataRaw, // 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 }