Gerüstete Go Chaincode Projekt

Blockchain App Builder übernimmt die Eingabe aus Ihrer Spezifikationsdatei und generiert ein voll funktionsfähiges gerüstetes Chaincode-Projekt. Das Projekt enthält automatisch generierte Klassen und Funktionen, CRUD-Methoden, SDK-Methoden, automatische Validierung von Argumenten, Marshalling/Un-Marshalling und transparente Persistenzfähigkeit (ORM).

Wenn das Chaincode-Projekt die Sprache Go verwendet, enthält das gerüstete Projekt drei Hauptdateien:
  • main.go
  • <chaincodeName>.model.go
  • <chaincodeName>.controller.go
Alle erforderlichen Bibliotheken sind installiert und in einem Package verpackt.

Die Datei <chaincodeName>.model.go im Unterverzeichnis model enthält mehrere Assetdefinitionen, und die Datei <chaincodeName>.controller.go im Unterverzeichnis controller enthält das Verhalten des Assets und die CRUD-Methoden. Die verschiedenen Go-Struktur-Tags und -Packages in model.go und controller.go unterstützen Features wie die automatische Validierung von Argumenten, das Marshalling/Unmarshalling von Argumenten, die transparente Persistenzfunktion (ORM) und das Aufrufen von umfangreichen Abfragen.

Das Gerüstprojekt befindet sich im Verzeichnis $GOPATH/src/example.com/<chaincodeName>.

Modell

Eigenschaft für Vermögensgegenstandstyp

Standardmäßig verfügt jede Struktur über eine zusätzliche Eigenschaft namens AssetType. Mit dieser Eigenschaft können Sie nur Assets dieses Typs abrufen. Alle Änderungen an dieser Eigenschaft werden ignoriert, wenn Assets erstellt oder aktualisiert werden. Der Eigenschaftswert ist standardmäßig <modelName>.
type Supplier struct {
AssetType string 'json:"AssetType" default:"TestGoProject.Supplier"'

SupplierId            string      'json:"SupplierId" validate:"string,mandatory" id:"true'
RawMaterialAvailable  int         'json:"RawMaterialAvailable" validate:"int,min=0"'
License               string      'json:"License" validate:"string,min=10"'
ExpiryDate            date.Date   'json:"ExpiryDate" validate:"date,before=2020-06-26"'
Active                bool	  'json:"Active" validate:"bool" default:"true"'
Metadata              interface{} 'json:"Metadata,omitempty"'
}

Validatoren

ID
id:"true"
Dieser Validator identifiziert die Eigenschaft, die den zugrunde liegenden Vermögensgegenstand eindeutig definiert. Das Asset wird durch den Wert in diesem Schlüssel gespeichert. Dieser Validator wird automatisch angewendet, wenn ein neues Go-Projekt eingerichtet wird.
Im folgenden Beispiel ist SupplierId der Schlüssel für das Lieferantenasset und hat die Tag-Eigenschaft id:"true" für die Eigenschaft SupplierId.
type Supplier struct {
    Supplierld              string        'json:"Supplierld" validate:"string,mandatory" id:"true"' 
    RawMaterialAvailable    int           'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                 string        'json:"License" validate:"string,min=10"'
    ExpiryDate              date.Date     'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                  bool          'json:"Active" validate:"bool" default :"true"'
    Metadata                interface{}   'json:"Metadata,omitempty"'   
}
Abgeleitet
derived:"strategy,algorithm,format"
Dieser Dekorator wird zur Definition des Attributs verwendet, das von anderen Eigenschaften abgeleitet wird. Dieser Dekorateur hat zwei obligatorische Parameter:
  • strategy: Nimmt die Werte concat oder hash an. Wenn hash angegeben wird, ist der zusätzliche Parameter algorithm erforderlich. Der Standardalgorithmus ist sha256. md5 wird ebenfalls unterstützt.
  • format: Nimmt ein Array von Spezifikationszeichenfolgen und -werten an, die von der Strategie verwendet werden sollen.
type Supplier struct{
   AssetType string 'json:"AssetType" final:"chaincode1.Supplier"'
   SupplierId   string  'json:"SupplierId" validate:"string" id:"true" mandatory:"true" derived:"strategy=hash,algorith=sha256,format=IND%1%2,License,Name"'
   Name         string  'json:"Name" validate:"string,min=2,max=4"'
   License      string  'json:"License" validate:"string,min=2,max=4"'
}
Obligatorisch
validate:"mandatory"
Dieser Dekorator kennzeichnet die folgende Eigenschaft als obligatorisch, sodass sie beim Speichern im Buch nicht übersprungen werden kann. Wenn sie übersprungen werden, wird ein Fehler ausgelöst. Im folgenden Beispiel hat die Eigenschaft SupplierId ein Tag validate:"mandatory".
Type Supplier struct {
    Supplierld              string      'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable    int         'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                 string      'json:"License" validate:"string,min=10"'
    ExpiryDate              date.Date   'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                  bool        'json:"Active" validate:"bool" default :"true"'
    Metadata                interface{} 'json:"Metadata,omitempty"'
}
Standard
default:"<param>"
Dieser Dekorator gibt an, dass die folgende Eigenschaft einen Standardwert hat. Der Wert im Standardtag wird verwendet, wenn die Eigenschaft beim Speichern im Buch übersprungen wird. Im folgenden Beispiel hat Active den Standardwert true, der als Tag default:"true" angegeben ist.
Type Supplier struct {
    Supplierld            string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License               string       'json:"License" validate:"string,min=10"'
    ExpiryDate            date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                bool         'json:"Active" validate:"bool" default :"true"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
Validierungstypen
Grundlegende Go-Typen werden für eine Eigenschaft validiert, indem ein Validierungstag definiert wird. Die folgenden Validierungstags basieren auf den Basistypen:
  • Zeichenfolge: validate: "string"
  • Datum: validate: "date"
  • Zahl: validate: "int"
  • boolesch: validate: "bool"
Min. Validator
validate:"min=<param>"
Mit dem Validator min können Sie den Mindestwert für eine Eigenschaft des Typs "Zahl" oder "Zeichenfolge" festlegen.
Für Typ int: Im folgenden Beispiel hat die Eigenschaft RawMaterialAvailable einen Mindestwert von 0. Wenn ein Wert kleiner als 0 auf die Eigenschaft RawMaterialAvailable angewendet wird, wird ein Fehler zurückgegeben.
Für Typzeichenfolge: Der Mindestvalidator prüft die Länge der Zeichenfolge mit dem angegebenen Wert. Im folgenden Beispiel muss die Eigenschaft License mindestens zehn Zeichen lang sein.
Type Supplier struct {
    Supplierld             string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable   int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                string       'json:"License" validate:"string,min=10"'
    ExpiryDate             date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                 bool         'json:"Active" validate:"bool" default :"true"'
    Metadata               interface{}  'json:"Metadata,omitempty"'
}
Max. Validator
validate:"max=<param>"
Sie können den maximalen Validator verwenden, um den Höchstwert für eine Eigenschaft des Typs "Zahl" und "Zeichenfolge" festzulegen.
Für Typ int: Ähnlich wie beim Min-Validator wird ein Fehler zurückgegeben, wenn ein für ein Strukturfeld angegebener Wert größer als der im Validator angegebene Wert ist.
Für Typzeichenfolge: Ähnlich wie beim Min-Validator prüft der Max-Validator die Länge der Zeichenfolge mit dem angegebenen Wert. Im folgenden Beispiel hat die Eigenschaft Domain einen Höchstwert von 50. Wenn die Eigenschaft Domain also eine Zeichenfolgenlänge von mehr als 50 Zeichen hat, wird eine Fehlermeldung zurückgegeben.
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}
Datumsvalidatoren
Vor Validator:
validate:"before=<param>"
Der Before Validator validiert eine Eigenschaft des Typs date mit einem Wert, der kleiner als der angegebene Parameter ist.
Im folgenden Beispiel muss die Eigenschaft ExpiryDate vor "2020-06-26" liegen. Andernfalls wird ein Fehler zurückgegeben.
Type Supplier struct {
    Supplierld            string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License               string       'json:"License" validate:"string,min=10"'
    ExpiryDate            date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                bool         'json:"Active" validate:"bool" default :"true"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
Nach Validator:
validate:"after=<param>"
Der After Validator validiert eine Eigenschaft des Typs date, um einen Wert zu haben, der größer als der angegebene Parameter ist.
Im folgenden Beispiel muss die Eigenschaft CompletionDate nach "2020-06-26" liegen. Andernfalls wird ein Fehler zurückgegeben.
Type Supplier struct {
    Manufacturerld        string       'json:"Manufacturerld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,max=8"'
    ProductsAvailable     int          'json:"ProductsAvailable" validate:"int"'
    CompletionDate        date.Date    'json:"CompletionDate" validate:"date,after=2020-06-26"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
URL-Validator
validate:"url"
Der URL-Validator validiert eine Eigenschaft für URL-Zeichenfolgen.
Im folgenden Beispiel muss die Eigenschaft Domain eine gültige URL sein.
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"string,url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}
Regexp-Validator
validate:"regexp=<param>"
Der regexp-Validator validiert eine Eigenschaft mit dem angegebenen regulären Ausdruck.
Im folgenden Beispiel wird die Eigenschaft PhoneNumber gemäß dem regulären Ausdruck für eine Mobiltelefonnummer validiert.
type Customer struct {
Customerld      string       'json:"Customerld" validate:"string,mandatory" id:"true"'
Name            string       'json:"Name" validate:"string,mandatory"'
ProductsBought  int          'json:"ProductsBought" validate:"int"'
OfferApplied    int          'json:"OfferApplied" validate :"int,nax=0"'
PhoneNumber     string       'json:"PhoneNumber" validate:"string,regexp=A\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"'
Received        bool         'json:"Received" validate:"bool"'
Metadata        interface{}  'json:"Metadata,omitempty"'
}
Mehrere Validatoren
Eine Eigenschaft kann auf mehrere Validatoren angewendet werden.
Im folgenden Beispiel hat die Eigenschaft Domain die Validierung für eine Zeichenfolge, eine URL sowie die minimale und maximale Zeichenfolgenlänge.
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"string,url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}

ORM

Transparent Persistence Capability oder vereinfachtes ORM wird in der Klasse Model des Context-(Ctx-)Objekts erfasst. Wenn Ihr Modell eine der folgenden SDK-Methoden aufruft, greifen Sie mit t.Ctx.Model darauf zu.

Die folgenden SDK-Methoden implementieren ORM:
  • Save ruft die Hyperledger Fabric PutState-Methode auf.
  • Get ruft die Hyperledger Fabric GetState-Methode auf.
  • Update ruft die Hyperledger Fabric PutState-Methode auf.
  • Delete ruft die Hyperledger Fabric DeleteState-Methode auf.
  • History ruft die Hyperledger Fabric GetHistoryForKey-Methode auf.
  • GetByRange ruft die Hyperledger Fabric GetStateByRange-Methode auf.
  • GetByRangeWithPagination ruft die Hyperledger Fabric GetStateByRangeWithPagination-Methode auf.

SDK-Methoden

Go chaincodes implementieren Transparent Persistence Capability (ORM) mit dem Modellpaket.

Hinweis:

Ab Version 21.2.3 hat sich der Zugriff auf die ORM-Methoden geändert. Führen Sie den Befehl ochain --version aus, um die Version von Blockchain App Builder zu bestimmen.

In früheren Releases wurden die ORM-Methoden als statische Methoden im Modellpackage bereitgestellt. Die Methoden werden nun auf dem Modellempfänger definiert, der den Transaktions-Stub enthält. Um diese Methoden aufzurufen, verwenden Sie den Modellempfänger, der vom Transaktionskontext im Controller gehalten wird. Diese Methoden werden als t.Ctx.Model.<method_name> anstelle von model.<method_name> aufgerufen.

Das folgende Beispiel zeigt die Methodenaufrufe Save und Get in früheren Releases:

func (t *Controller) CreateSupplier(asset Supplier) (interface{}, error) {
  return model.Save(&asset)
}

func (t *Controller) GetSupplierById(id string) (Supplier, error) {
  var asset Supplier
  _, err := model.Get(id, &asset)
  return asset, err
}

Das folgende Beispiel zeigt Methodenaufrufe Save und Get ab Version 21.2.3:

func (t *Controller) CreateSupplier(asset Supplier) (interface{}, error) {
  return t.Ctx.Model.Save(&asset)
}

func (t *Controller) GetSupplierById(id string) (Supplier, error) {
  var asset Supplier
  _, err := t.Ctx.Model.Get(id, &asset)
  return asset, err
}

Nachdem Sie ein Upgrade auf Version 21.2.3 durchgeführt haben, nehmen Sie diese Änderung in allen Chaincode-Projekten vor, die Sie mit einer früheren Version von Blockchain App Builder erstellt haben. Wenn Sie den Befehl sync verwenden, um Änderungen zwischen der Spezifikationsdatei und dem Quellcode zu synchronisieren, werden die Änderungen automatisch an den Controller für die einsatzbereiten Methoden weitergeleitet. Konflikte müssen weiterhin manuell gelöst werden.

Die folgenden ORM-Methoden werden vom Modellpackage bereitgestellt:

Get
Fragt das Buch für die gespeicherte Anlage basierend auf der angegebenen ID ab.
func Get(Id string, result ...interface{}) (interface{}, error)
Parameter:
  • Id: Die ID des Vermögensgegenstands, der aus dem Buch abgerufen werden soll.
  • result (interface{}): Ein leeres Assetobjekt eines bestimmten Typs, das per Referenz übergeben wird. Dieses Objekt enthält das Ergebnis dieser Methode. Verwenden Sie diesen Parameter nur, wenn ein typspezifisches Ergebnis erforderlich ist.
  • asset (interface): Ein leeres Assetobjekt, das per Referenz übergeben wird. Dieses Objekt enthält das Ergebnis dieser Methode. Verwenden Sie diesen Parameter nur, wenn ein typspezifisches Ergebnis erforderlich ist.
Rückgabewert:
  • interface {}: Die Schnittstelle enthält das Asset im Formular map[string]interface{}. Bevor Sie mit dieser Zuordnung arbeiten, müssen Sie die zurückgegebene Schnittstelle mit dem Typ map[string]interface{} durchsetzen. Um diese Zuordnung in ein Assetobjekt zu konvertieren, können Sie die Utility-API util.ConvertMaptoStruct verwenden (siehe: Utilitypackage).
  • error: Enthält einen Fehler, wenn er zurückgegeben wird oder null ist.
Update
Aktualisiert die angegebene Anlage im Buch mit neuen Werten.
func Update(args ...interface{}) (interface{}, error)
Parameter:
  • obj (interface): Das Objekt, das im Buch aktualisiert werden soll, wird zusammen mit den neuen Werten per Referenz an diese API übergeben. Das eingegebene Asset wird gemäß den Strukturtags in der Modellspezifikation validiert und verifiziert und anschließend im Ledger gespeichert.
Rückgabewert:
  • interface{}: Das gespeicherte Asset wird als Schnittstelle zurückgegeben.
  • error: Enthält einen Fehler, wenn er zurückgegeben wird oder null ist.
Save
Speichert die Anlage im Buch, nachdem sie für alle Strukturtags validiert wurde.
func Save(args ...interface{}) (interface{}, error)
Parameter:
  • obj/args[0] (interface{}): Das Objekt, das im Buch gespeichert werden soll, wird in dieser Utilitymethode per Referenz übergeben.
  • metadata/args[1] (interface{}) (Optional) Mit diesem Parameter können Sie Metadaten zusammen mit dem Asset zur Laufzeit im Buch speichern.
Rückgabewert:
  • interface {}: Das Asset wird als Schnittstelle zurückgegeben.
  • error: Enthält einen Fehler, wenn er zurückgegeben wird oder null ist.
Delete
Löscht die Anlage aus dem Buch.
func Delete(Id string) (interface{}, error)
Parameter:
  • id (string): Die ID des Vermögensgegenstands, der aus dem Buch gelöscht werden soll.
Rückgabewert:
  • interface {}: Enthält das Asset, das im Formular map[string]interface{} gelöscht wird.
GetByRange
Gibt eine Liste der Assets zurück, die durch einen Bereich von IDs angegeben sind.
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
Parameter:
  • startkey (string): Start-ID für den abzurufenden Objektbereich.
  • endkey (string): End-ID für den abzurufenden Objektbereich.
  • asset interface (Optional) Ein leeres Array von Assets, das per Referenz übergeben wird. Dieses Array enthält das Methodenergebnis. Verwenden Sie diesen Parameter, wenn ein typspezifisches Ergebnis erforderlich ist.
Rückgabewert:
  • []map[string]interface{}: Dieses Array enthält die Liste der Assets, die aus dem Buch abgerufen wurden. Sie können auf die Objekte zugreifen, indem Sie über dieses Array iterieren und die Objekte als map[string]interface{} durchsetzen und ein Utility zum Konvertieren in ein Assetobjekt verwenden.
  • error: Enthält einen Fehler, wenn er zurückgegeben wird oder null ist.
GetByRangeWithPagination
Die Methode GetByRangeWithPagination ist eine statische Methode der Klasse OchainModel, die von den konkreten Model-Klassen von {chaincodeName}.model.ts geerbt wird.
Diese Methode gibt eine Liste von Assets zwischen startId und endId zurück, gefiltert nach Seitengröße und Lesezeichen. Diese Methode ruft die Hyperledger Fabric GetStateByRangeWithPagination-Methode intern auf.
Wenn der Parameter modelName nicht angegeben ist, gibt die Methode Promise<Object [ ] > zurück. Wenn der Parameter modelName angegeben ist, verarbeitet die Methode das Casting in den Aufrufertyp Model. Im folgenden Beispiel hat das Ergebnisarray den Typ Supplier. Wenn der aus dem Buch zurückgegebene Vermögensgegenstand nicht den Typ Model aufweist, wird er nicht in die Liste aufgenommen. Diese Prüfung erfolgt durch die schreibgeschützte Eigenschaft assetType in der Klasse Model.
Um alle Assets zwischen dem Bereich startId und endId zurückzugeben, gefiltert nach Seitengröße und Lesezeichen, verwenden Sie die generische Controllermethode getAssetsByRange.
func (m *Model) GetByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string, asset ...interface{}) ([]map[string]interface{}, error) 
Parameter:
  • startkey : string: Startschlüssel des Bereichs, der im Bereich enthalten ist.
  • endkey : string: Endschlüssel des Bereichs, der aus dem Bereich ausgeschlossen ist.
  • pageSize : number: Die Seitengröße der Abfrage.
  • Bookmark : string: Das Lesezeichen der Abfrage. Die Ausgabe beginnt mit diesem Lesezeichen.
  • asset interface (Optional) Ein leeres Array von Assets, das per Referenz übergeben wird. Dieses Array enthält das Ergebnis dieser Methode. Mit diesem Parameter können Sie typspezifische Ergebnisse abrufen.
Rückgabewert:
  • []map[string]interface{}: Ein Array mit der Liste der aus dem Buch abgerufenen Assets. Sie können auf die Objekte zugreifen, indem Sie über dieses Array iterieren und die Objekte als map[string]interface{} durchsetzen und ein Utility zur Konvertierung in ein Assetobjekt verwenden.
  • error: Enthält einen Fehler, wenn ein Fehler zurückgegeben wird, andernfalls null.
GetHistoryById
Gibt die Historie des Assets mit der angegebenen ID zurück.
func GetHistoryByID(Id string) ([]interface{}, error)
Parameter:
  • Id (string): ID des Assets.
Rückgabewert:
  • []interface{}: Dieser Abschnitt enthält die Historie des Vermögensgegenstands, der aus dem Buch in Form von Abschnitt map[string]interface{} abgerufen wurde. Sie können auf jedes Historienelement zugreifen, indem Sie über diesen Bereich iterieren und die Objekte als map[string]interface{} durchsetzen und ein Utility zum Konvertieren in ein Assetobjekt verwenden.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
Query
Diese Methode führt eine SQL/Couch DB-Abfrage über das Buch aus. Diese Methode wird nur für Remote-Deployments auf Oracle Blockchain Platform unterstützt. Dies ist eine generische Methode zum Ausführen von SQL-Abfragen im Ledger.
func Query(queryString string) ([]interface{}, error)
Parameter:
  • queryString (string) - Die Abfragezeichenfolge.
Rückgabewert:
  • []interface{}: Die Abfrageausgabe in Form eines Bereichs von Schnittstellen. Wiederholen Sie den Vorgang über den Bereich, und verwenden Sie die Elemente, indem Sie sie in die entsprechenden Typen umwandeln.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
QueryWithPagination
Diese Methode führt eine SQL/Couch DB-Abfrage über das Ledger aus, gefiltert nach Seitengröße und Lesezeichen. Diese Methode wird nur für Remote-Deployments auf Oracle Blockchain Platform unterstützt. Dies ist eine generische Methode zum Ausführen von SQL-Abfragen im Ledger.
func (m *Model) QueryWithPagination(queryString string, pageSize int32, bookmark string) ([]interface{}, error)
Parameter:
  • queryString (string): Rich SQL/Couch DB-Abfrage.
  • pageSize : number: Die Seitengröße der Abfrage.
  • bookmark : string - Das Lesezeichen der Abfrage. Die Ausgabe beginnt mit diesem Lesezeichen.
Rückgabewert:
  • []interface{}: Die Abfrageausgabe in Form eines Bereichs von Schnittstellen. Wiederholen Sie den Vorgang über den Bereich, und verwenden Sie die Elemente, indem Sie sie in die entsprechenden Typen umwandeln.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
InvokeCrossChaincode
Sie können diese Methode in einem Chaincode verwenden, um eine Funktion in einem anderen Chaincode aufzurufen. Beide Chaincodes müssen auf demselben Peer installiert sein.
func InvokeCrossChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
Parameter:
  • chaincodeName: Der Name des aufzurufenden Chaincodes.
  • methodName: Der Name der Methode, die im Chaincode aufgerufen werden soll.
  • arg - Das Argument der aufrufenden Methode.
  • channelName: Der Kanal, in dem sich der aufzurufende Chaincode befindet.
Rückgabewert:
  • interface{} - Gibt ein map[string]interface{}-Objekt zurück, das drei Schlüssel enthält:
    • isValid - true, wenn der Aufruf gültig ist.
    • payload: Die Ausgabe, die vom Cross-Chaincode-Aufruf als JSON-Objekt zurückgegeben wird.
    • message: Die vom Cross-Chaincode-Aufruf zurückgegebene Nachricht im UTF-8-Format.
Beispiel für Rückgabewert:
{
      "isValid": true,
      "message": "Successfully invoked method [CreateAccount] on sub-chaincode [erc721_go_453]",
      "payload": {
                  "AccountId": "oaccount~6b83b8ab931f99442897dd04cd7a2a55f808686f49052a40334afe3753fda4c4",
                  "AssetType": "oaccount",
                  "BapAccountVersion": 0,
                  "NoOfNfts": 0,
                  "OrgId": "appdev",
                  "TokenType": "nonfungible",
                  "UserId": "user2"
      }
}
InvokeChaincode
Sie können diese Methode in einem Chaincode verwenden, um eine Funktion in einem anderen Chaincode aufzurufen. Beide Chaincodes müssen auf demselben Peer installiert sein.
func InvokeChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
Parameter:
  • chaincodeName: Der Name des aufzurufenden Chaincodes.
  • methodName: Der Name der Methode, die im Chaincode aufgerufen werden soll.
  • arg - Das Argument der aufrufenden Methode.
  • channelName: Der Kanal, in dem sich der aufzurufende Chaincode befindet.
Rückgabewert:
  • interface{} - Gibt ein map[string]interface{}-Objekt zurück, das drei Schlüssel enthält:
    • isValid - true, wenn der Aufruf gültig ist.
    • payload: Die Ausgabe, die vom Cross-Chaincode-Aufruf im UTF-8-Format zurückgegeben wird.
    • message: Die vom Cross-Chaincode-Aufruf zurückgegebene Nachricht im UTF-8-Format.
Beispiel für Rückgabewert:
{
    "isValid": true,
    "message": "Successfully invoked method [CreateAccount] on sub-chaincode [erc721_go_453]",
    "payload": "{\"AssetType\":\"oaccount\",\"AccountId\":\"oaccount~c6bd7f8dcc339bf7144ea2e1cf953f8c1df2f28482b87ad7895ac29e7613a58f\",\"UserId\":\"user1\",\"OrgId\":\"appdev\",\"TokenType\":\"nonfungible\",\"NoOfNfts\":0,\"BapAccountVersion\":0}"
} 

Zusammengesetzte Schlüsselmethoden

GenerateCompositeKey
Diese Methode generiert und gibt den zusammengesetzten Schlüssel basierend auf der indexName und den in den Argumenten angegebenen Attributen zurück.
func GenerateCompositeKey(indexName string, attributes []string)
            (string, error)
Parameter:
  • indexName (string): Objekttyp des zusammengesetzten Schlüssels.
  • attrbutes ([]string): Attribute des Assets, auf denen der zusammengesetzte Schlüssel gebildet wird.
Rückgabewert:
  • string: Das zusammengesetzte Schlüsselergebnis.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
GetByCompositeKey
Diese Methode gibt das Asset zurück, das mit dem angegebenen Schlüssel und der angegebenen Spalte übereinstimmt. Der Parameter index gibt den Index des Schlüssels an, der im Array der Stub-Methode SplitCompositeKey zurückgegeben wird.
Intern ruft diese Methode die getStateByPartialCompositeKey-, splitCompositeKey- und getState-Methoden von Hyperledger Fabric auf.
func GetByCompositeKey(key string, columns []string, index int)
                (interface{}, error)
Parameter:
  • key (string): Der Objekttyp wurde beim Erstellen des zusammengesetzten Schlüssels angegeben.
  • column ([]string): Das Segment der Attribute, in dem das Buch mit dem zusammengesetzten Schlüssel abgefragt wird.
  • index(int): Index des Attributs.
Rückgabewert:
  • Interface{}: Die Liste der übereinstimmenden Assets.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.

Stub-Methode

GetNetworkStub
Diese Methode gibt den Hyperledger Fabric-Wert chaincodeStub zurück.
Sie können auf das Shim-Stub zugreifen, indem Sie die Methode GetNetworkStub aufrufen. Dies kann Sie beim Schreiben Ihrer eigenen Implementierung unterstützen, die direkt mit Assets arbeitet.
func GetNetworkStub() shim.ChaincodeStubInterface
Parameter:
  • Kein
Rückgabewert:
  • shim.ChaincodeStubInterface - Der Hyperledger Fabric Chaincode-Stub.

Sonstige Methoden

  • GetTransactionId()
  • GetTransactionTimestamp()
  • GetChannelID()
  • GetCreator()
  • GetSignedProposal()
  • GetArgs()
  • GetStringArgs()
  • GetCreatorMspId()
  • GetId
GetTransactionId
Diese Methode gibt die Transaktions-ID für die aktuelle Chaincode-Aufrufanforderung zurück. Die Transaktions-ID identifiziert die Transaktion im Geltungsbereich des Kanals eindeutig.
func GetTransactionId() string
Parameter:
  • Kein
Rückgabewert:
  • string: Die Transaktions-ID.
GetTransactionTimestamp
Gibt den Zeitstempel zurück, als die Transaktion erstellt wurde. Da der Wert aus der Transaktion ChannelHeader stammt, gibt er den Zeitstempel des Clients an und hat denselben Wert für alle Endorser.
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
Parameter:
  • Kein
Rückgabewert:
  • timestamp.Timestamp - Der Zeitstempel.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
GetChannelID
Gibt die Kanal-ID für den Vorschlag zurück, den der Chaincode verarbeiten soll.
func GetChannelID() string
Parameter:
  • Kein
Rückgabewert:
  • string - Die angeforderte Kanal-ID im Zeichenfolgenformat.
GetCreator
Gibt das Identitätsobjekt des Weiterleitenden des Chaincode-Aufrufs zurück.
func GetCreator() ([]byte, error)
Parameter:
  • Kein
Rückgabewert:
  • []byte: Das erforderliche Identitätsobjekt in serialisierter Form.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
GetSignedProposal
Gibt ein vollständig decodiertes Objekt des signierten Transaktionsvorschlags zurück.
func GetSignedProposal() (*peer.SignedProposal, error)
Parameter:
  • Kein
Rückgabewert:
  • *peer.SignedProposal: Das unterschriebene Vorschlagsobjekt.
  • error: Enthält den Fehler, wenn ein Fehler zurückgegeben wird.
GetArgs
Gibt die Argumente als Array von Zeichenfolgen aus der Chaincode-Aufrufanforderung zurück.
func GetArgs() [][]byte
Parameter:
  • Kein
Rückgabewert:
  • [][]byte - Die übergebenen Argumente.
GetStringArgs
Gibt die Argumente für die Chaincode-Methoden Init und Invoke als Zeichenfolgenarray zurück.
func GetStringArgs() []string
Parameter:
  • Kein
Rückgabewert:
  • []string - Die Argumente als Zeichenfolgenarray.
GetCreatorMspId
Gibt die MSP-ID der aufrufenden Identität zurück.
func GetCreatorMspId() string
Parameter:
  • Kein
Rückgabewert:
  • string: Die MSP-ID der aufrufenden Identität.
GetId
Wenn das Asset einen abgeleiteten Schlüssel als Id aufweist, können Sie mit dieser Methode eine abgeleitete ID abrufen. Diese Methode gibt einen Fehler zurück, wenn der abgeleitete Schlüssel %t (Zeitstempel) enthält.
Parameter:
  • object: Das Objekt muss alle Eigenschaften enthalten, von denen der abgeleitete Schlüssel abhängt.
Rückgabewert:
  • Gibt den abgeleiteten Schlüssel als Zeichenfolge zurück.
Beispiel:
func (t *Controller) CustomGetterForSupplier(License string, Name string)(interface{}, error){
   var asset Supplier
   asset.License = License
   asset.Name = Name
   id,err := t.Ctx.Model.GetId(&asset)

   if err !=nil {
      return nil, fmt.Errorf("error in getting ID %v", err.Error())
   }
   return t.GetSupplierById(id)
}

Utilitypaket

Die folgenden Methoden werden im Utilitypackage bereitgestellt.

Util.CreateModel
Parst die angegebene JSON-Zeichenfolge und erstellt ein Assetobjekt des angegebenen Typs.
func CreateModel(obj interface{}, inputString string) error
Parameter:
  • inputString (string): Die JSON-Eingabezeichenfolge, die zum Erstellen des Objekts verwendet werden soll.
  • obj (interface{}): Die Referenz des Objekts, das aus der JSON-Zeichenfolge erstellt werden soll. Dieses Objekt speichert das erstellte Modell, das ebenfalls gemäß den Validator-Tags validiert wird.
Rückgabewert:
  • error: Enthält den Fehler, wenn beim Erstellen oder Validieren des Assets ein Fehler zurückgegeben wird.
util.ConvertMapToStruct
Konvertieren Sie die angegebene Zuordnung in ein Objekt des angegebenen Typs.
func ConvertMapToStruct(inputMap map[string](interface{}), resultStruct
interface{}) error
Parameter:
  • inputMap (map[string](interface{})): Die Zuordnung, die in ein Assetobjekt konvertiert werden soll.
  • resultStruct (interface{}): Die Referenz des Assetobjekts, das aus der Zuordnung erstellt werden soll.
Rückgabewert:
  • error: Enthält den Fehler, wenn beim Erstellen oder Validieren des Assets ein Fehler zurückgegeben wird.

Token-SDK-Methoden finden Sie in den Themen unter Tokenisierungsunterstützung mit Blockchain App Builder.

Verantwortlicher

Die Datei Controller.go implementiert das CRUD und benutzerdefinierte Methoden für die Assets.

Sie können eine beliebige Anzahl von Klassen, Funktionen oder Dateien erstellen, aber nur die Methoden, die in Chaincode-Strukturen definiert sind, können von außen aufgerufen werden. Die restlichen Methoden sind ausgeblendet.

Automatisch generierte Methoden

Wie unter Eingabespezifikationsdatei beschrieben, können Sie angeben, welche CRUD-Methoden in der Spezifikationsdatei generiert werden sollen. Beispiel: Wenn Sie alle Methoden generieren, sieht das Ergebnis ähnlich aus wie der folgende Code:

//	
//Supplier
//	
func (t *ChainCode) CreateSupplier(inputString string) (interface{}, error) {
    var obj Supplier
    err := util.CreateModel(&obj, inputString)
    if err != nil {
        return nil, err   
    }
    return model.Save(&obj)
}

func (t *ChainCode) GetSupplierById(id string) (interface{}, error) {
    asset, err := model.Get(id) 
    return asset, err
}

func (t *ChainCode) UpdateSupplier(inputString string) (interface{}, error) {
    var obj Supplier
    err := util.CreateModel(&obj, inputstring)
    if err != nil {   
        return nil, err
    }
return model.Update(&obj)
}

func (t *ChainCode) DeleteSupplier(id string) (interface{}, error) { 
    return model.Delete(id)
}

func (t *ChainCode) GetSupplierHistoryById(id string) (interface{}, error) { 
    historyArray, err := model.GetHistoryByld(id) 
    return historyArray, err
}

func (t *ChainCode) GetSupplierByRange(startkey string, endKey string) (interface{}, error) { 
    assetArray, err := model.GetByRange(startkey, endKey) 
    return assetArray, err
}

Benutzerdefinierte Methoden

Die folgenden benutzerdefinierten Methoden wurden aus der Beispielspezifikationsdatei generiert.

Die Funktion executeQuery zeigt, wie SQL-reiche Abfragen aufgerufen werden können. Die Validatoren für die Argumente werden automatisch von Blockchain App Builder basierend auf dem in der Spezifikationsdatei angegebenen Argumenttyp hinzugefügt.

Sie können die Funktionalität entsprechend der erforderlichen Geschäftslogik implementieren. Wenn Sie benutzerdefinierte Methoden hinzufügen, fügen Sie sie der Controllerdatei hinzu. Wenn Sie der Bibliothek anstelle der Controllerdatei benutzerdefinierte Methoden hinzufügen, gehen Ihre Änderungen verloren, wenn der Inhalt des Bibliotheksordners während der Synchronisierung oder des Chaincodeupgrades aktualisiert wird.

//	
//Custom Methods
//			
/*
*	BDB sql rich queries can be executed in OBP CS/EE.
*	This method can be invoked only when connected to remote OBP CS/EE network.
*/
func (t *ChainCode) ExecuteQuery(inputQuery string) (interface{}, error) { 
    resultArray, err := model.Query(inputQuery) 
    return resultArray, err
}

func (t *ChainCode) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) {
    return nil, nil
}

func (t *ChainCode) GetRawMaterialFromSupplier(manufacturerId string, supplierId string, rawMaterialSupply int) (interface{} error) { 
    return nil, nil
}

Func (t *ChainCode) CreateProducts(manufacturerId string, rawMaterialConsumed int, productsCreated int) (interface{}, error) { 
    return nil, nil
}

func (t *ChainCode) SendProductsToDistribution() (interface{}, error) { 
    return nil, nil
    }
Bei Go-Chaincodes muss jede benutzerdefinierte Methode zwei Werte zurückgeben: eine empty interface und eine error, wie im folgenden Beispiel dargestellt:
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) { 
    return nil, nil
}

Initialisierungsmethode

Eine benutzerdefinierte Init-Methode wird im Controller mit einer leeren Definition bereitgestellt. Wenn Sie Blockchain App Builder zum Deployment oder Upgrade verwenden, wird die Methode Init automatisch aufgerufen. Wenn Sie die Oracle Blockchain Platform-Konsole bereitstellen oder ein Upgrade ausführen, müssen Sie die Methode Init manuell aufrufen. Sie können ein Drittanbietertool wie Postman verwenden, um die Methode Init manuell aufzurufen.

type Controller struct {
}
func (t *Controller) Init(args string) (interface{}, error) 
    { return nil, nil
}

Mit dieser Methode können Sie dann jeden Anwendungsstatus initialisieren.