Blockchain App Builder übernimmt die Eingabe aus Ihrer Spezifikationsdatei und generiert ein voll funktionsfähiges Gerüstkettencode-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 sich das Chaincode-Projekt in der Go-Sprache befindet, enthält das Gerüstprojekt drei Hauptdateien:
main.go
<chaincodeName>.model.go
<chaincodeName>.controller.go
Alle erforderlichen Bibliotheken werden installiert und in einem Package integriert.
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 Funktionen wie die automatische Validierung von Argumenten, das Marshalling/Unmarshalling von Argumenten, die transparente Persistenzfähigkeit (ORM) und das Aufrufen umfangreicher Abfragen.
Das Gerüstprojekt finden Sie unter $GOPATH/src/example.com/<chaincodeName>
Modell
Anlagentyp - Eigenschaft
Standardmäßig verfügt jede Struktur über eine zusätzliche Eigenschaft namens
AssetType
. Diese Eigenschaft kann nützlich sein, um nur Assets dieses Typs abzurufen. Alle Änderungen an dieser Eigenschaft werden beim Erstellen und Aktualisieren der Anlage ignoriert. Der Eigenschaftswert lautet 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 mit dem Wert in diesem Schlüssel gespeichert. Dieser Validator wird automatisch angewendet, wenn ein neues Go-Projekt gerüstet ist.
- Im folgenden Screenshot ist
"SupplierId"
der Schlüssel für das Lieferantenasset und hat eine 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 zum Definieren des Attributs verwendet, das von anderen Eigenschaften abgeleitet wird. Dieser Dekorator hat zwei obligatorische Parameter:
strategy
: Übernimmt die Werte concat
oder hash
. Erfordert einen zusätzlichen Parameter algorithm
, wenn hash
ausgewählt ist. Der Standardalgorithmus lautet sha256
. md5
wird ebenfalls unterstützt.
format
: Übernimmt ein Array von Spezifikationszeichenfolgen und -werten, 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"
- Die folgende Eigenschaft ist erforderlich und kann beim Speichern im Buch nicht übersprungen werden. Wird er übersprungen, wird ein Fehler ausgegeben. Im folgenden Beispiel hat
"SupplierId"
ein validate:"mandatory"
-Tag.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>"
- Die folgende Eigenschaft kann einen Standardwert aufweisen. Der Standardwert im Standardtag wird verwendet, wenn die Eigenschaft beim Speichern im Buch übersprungen wird. In der folgenden Beispieleigenschaft hat
Active
den Standardwert true
, der als Tag default:"true"
angegeben wirdType 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 validiertes Tag definiert wird. Die folgenden Validierungstags basieren auf Typen:
- Zeichenfolge:
validate: "string"
- Datum:
validate: "date"
- Zahl:
validate: "int"
- Boolescher Wert:
validate: "bool"
-
Minvalidator
validate:"min=<param>"
- Mit dem Min-Validator kann ein Mindestwert für eine Eigenschaft vom Typ Number und String festgelegt werden.
- Für Typ int: Im Beispiel hat die Eigenschaft
RawMaterialAvailable
den Mindestwert 0. Wenn ein Wert kleiner als 0 auf RawMaterialAvailable
angewendet wird, wird ein Fehler zurückgegeben.
- Für Typzeichenfolge: Für den Stringtyp überprüft der Mindestvalidator die Länge der Zeichenfolge mit dem angegebenen Wert. Daher muss im folgenden Beispiel die Eigenschaft
License
mindestens 10 Zeichen lang sein.
- Beispiel:
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>"
- Mit dem maximalen Validator kann der Höchstwert für eine Eigenschaft des Typs "Zahl" und "Zeichenfolge" festgelegt werden.
- Für Typ int: Wie der min-Validator wird für Typ int ein Fehler zurückgegeben, wenn ein für
structfield
angegebener Wert größer als der im Validator angegebene Wert ist.
- Für Typ-String: Wie der min validator überprüft max validator auch die Länge der Zeichenfolge mit dem angegebenen Wert. Im Beispiel hat die Eigenschaft
Domain
einen Höchstwert von 50. Wenn die Eigenschaft Domain
eine Zeichenfolge mit mehr als 50 Zeichen enthält, 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 dem Validator:
validate:"before=<param>"
- Der Before Validator validiert eine Eigenschaft des Typs
date
, sodass ein Wert kleiner als der im Parameter angegebene Wert ist.
- In diesem 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 dem Validator:
validate:"after=<param>"
- Der Before Validator validiert eine Eigenschaft des Typs
date
, sodass ein Wert größer als der im Parameter angegebene Wert ist.
- In diesem 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.
- In diesem 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"'
}
-
Regulärer Ausdrucksvalidator
validate:"regexp=<param>"
- Der Regexp-Validator validiert die Eigenschaft für den eingegebenen regulären Ausdruck.
- In diesem 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
- Mehrere Validatoren können eine Eigenschaft anwenden.
- In diesem Beispiel hat die Eigenschaft
Domain
eine Validierung für eine Zeichenfolge, eine URL sowie eine Mindest- 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
Transparente Persistenzfähigkeit oder vereinfachtes ORM wird in der Klasse Model
des Kontextobjekts (Ctx
) erfasst. Wenn Ihr Modell eine der folgenden SDK-Methoden aufruft, greifen Sie mit t.Ctx.Model
darauf zu.
SDK-Methoden, die ORM implementieren, sind die folgenden Methoden:
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 wurde 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 angegeben. Die Methoden werden nun im Modellempfänger definiert, der das Transaktionsstub enthält. Um diese Methoden aufzurufen, verwenden Sie den Modellempfänger, der im Transaktionskontext im Controller gespeichert ist. Sie nennen diese Methoden als t.Ctx.Model.<method_name>
anstelle von model.<method_name>
.
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 die Methodenaufrufe Save
und Get
von Version 21.2.3 und höher:
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
}
Nach dem Upgrade auf Version 21.2.3 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 übertragen. Konflikte müssen weiterhin manuell gelöst werden.
Die folgenden ORM-Methoden werden über das Modellpaket bereitgestellt:
-
Get
- Fragt das Buch für das gespeicherte Asset basierend auf der angegebenen ID ab.
-
func Get(Id string, result ...interface{}) (interface{}, error)
- Parameter:
Id
: Die ID des Assets, das aus dem Ledger erforderlich ist.
result (interface{})
: Dies ist ein leeres Assetobjekt eines bestimmten Typs, das per Referenz übergeben wird. Dieses Objekt enthält das Ergebnis dieser Methode. Wird nur verwendet, wenn ein typspezifisches Ergebnis erforderlich ist.
asset (interface)
: Leeres Assetobjekt, das durch Referenz übergeben wird. Dieses Objekt enthält das Ergebnis dieser Methode. Wird nur verwendet, wenn ein typspezifisches Ergebnis erforderlich ist.
- Rückgabewert:
interface {}
: Die Schnittstelle enthält das Asset in Form von map[string]interface{}
. Bevor Sie auf dieser Karte arbeiten, müssen Sie die erhaltene 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 ist Null.
-
Update
- Aktualisiert die angegebene Anlage im Buch mit den neuen Werten.
-
func Update(args ...interface{}) (interface{}, error)
- Parameter:
obj (interface)
: Das Objekt, das im Ledger aktualisiert werden muss, wird per Referenz an diese API mit den neuen Werten übergeben. Das Eingabeasset wird gemäß den in der Modellspezifikation genannten Strukturtags validiert und verifiziert und dann im Hauptbuch gespeichert.
- Rückgabewert:
interface{}
: Das gespeicherte Asset wird als Schnittstelle zurückgegeben.
error
: Enthält einen Fehler, wenn er zurückgegeben wird, oder ist Null.
-
Save
- Speichert das Asset nach der Validierung aller Strukturtags im Hauptbuch.
-
func Save(args ...interface{}) (interface{}, error)
- Parameter:
obj/args[0] (interface{})
: Das Objekt, das im Ledger gespeichert werden muss, wird in dieser Utilitymethode per Referenz übergeben.
metadata/args[1] (interface{})
: Dieser Parameter ist optional. Es wurde angegeben, um Ihnen zu helfen, wenn Sie Metadaten zusammen mit dem Asset zur Laufzeit im Ledger speichern müssen. Dieser Parameter kann übersprungen werden, wenn keine derartige Anforderung vorhanden ist.
- Rückgabewert:
interface {}
: Das Asset wird als Schnittstelle zurückgegeben.
error
: Enthält einen Fehler, wenn er zurückgegeben wird, oder ist Null.
-
Delete
- Löscht die Anlage aus dem Buch.
-
func Delete(Id string) (interface{}, error)
- Parameter:
id (string)
: Die ID des Assets, das aus dem Ledger gelöscht werden muss.
- Rückgabewert:
interface {}
: Enthält das zu löschende Asset im Format map[string]interface{}
.
-
GetByRange
- Gibt die Liste der Assets nach ID-Bereich zurück.
-
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
- Parameter:
startkey (string)
: Start-ID für den erforderlichen Objektbereich.
endkey (string)
: Ende des erforderlichen Objektbereichs.
asset interface
- (optional) Leeres Array von Assets, das per Referenz übergeben wird. Dieses Array enthält das Ergebnis dieser Methode. Wird verwendet, wenn typspezifisches Ergebnis erforderlich ist.
- Rückgabewert:
[]map[string]interface{}
: Dieses Array enthält die Liste der Assets, die aus dem Ledger abgerufen werden. Sie können auf die Objekte zugreifen, die über dieses Array iteriert werden, die Objekte als map[string]interface{}
durchsetzen und mit dem Utility in ein Assetobjekt konvertieren.
error
: Enthält einen Fehler, wenn er zurückgegeben wird, oder ist Null.
-
GetByRangeWithPagination
- Die Methode
GetByRangeWithPagination
ist eine statische Methode der Klasse OchainModel
, die von den konkreten Model
-Klassen von {chaincodeName}.model.ts
geerbt wird.
- Dadurch wird eine Liste von Assets zwischen dem Bereich
startId
und endId
zurückgegeben, gefiltert nach Seitengröße und Lesezeichen. Diese Methode ruft die Hyperledger Fabric GetStateByRangeWithPagination
-Methode intern auf.
- Wenn der Parameter
modelName
nicht angegeben wird, 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 das vom Buch zurückgegebene Asset nicht den Typ Model
aufweist, wird es nicht in die Liste aufgenommen. Diese Prüfung wird von der schreibgeschützten Eigenschaft assetType
in der Klasse Model
durchgeführt.
- 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. Im Sortiment enthalten.
endkey : string
: Endschlüssel des Bereichs. Ausgeschlossen aus dem Bereich.
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 von Referenz übergeben wird. Dieses Array enthält das Ergebnis dieser Methode. Verwenden Sie diesen Parameter, um typspezifische Ergebnisse abzurufen.
- Rückgabewert:
[]map[string]interface{}
: Ein Array mit der Liste der Assets, die aus dem Ledger abgerufen werden. Sie können auf die Objekte zugreifen, indem Sie über dieses Array iterieren und die Objekte als map[string]interface{}
durchsetzen und ein Utility für die Konvertierung in ein Assetobjekt verwenden.
error
: Enthält einen Fehler, wenn ein Fehler zurückgegeben wird, andernfalls nil.
-
GetHistoryById
- Gibt die Historie des Vermögensgegenstands mit der angegebenen ID zurück.
-
func GetHistoryByID(Id string) ([]interface{}, error)
- Parameter:
Id (string)
: ID des Assets, für das die Historie erforderlich ist.
- Rückgabewert:
[]interface{}
: Dieser Bereich enthält die Historie des Assets, das aus dem Ledger in Form von Bereich 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 das Utility zur Konvertierung in ein Assetobjekt verwenden.
error
- Enthält den Fehler, falls beobachtet.
-
Query
- Die Abfragemethode führt eine SQL-/Couch-DB-Abfrage über das Ledger aus. Diese Methode wird nur für das Remote-Deployment auf Oracle Blockchain Platform unterstützt. Dies ist eine generische Methode zum Ausführen von SQL-Abfragen für das Ledger.
-
func Query(queryString string) ([]interface{}, error)
- Parameter:
queryString (string)
: Geben Sie die Abfragezeichenfolge ein.
- Rückgabewert:
[]interface{}
: Enthält die Ausgabe der Abfrage. Das Ergebnis ist in Form von Schnittstellenbereichen. Sie müssen den Abschnitt iterieren und die Elemente verwenden, indem Sie sie in die richtigen Typen konvertieren.
error
- Enthält den Fehler, falls beobachtet.
-
QueryWithPagination
- Die Abfragemethode führt eine SQL-/Couch-DB-Abfrage über das Ledger aus, gefiltert nach Seitengröße und Lesezeichen. Diese Methode wird nur für das Remote-Deployment auf Oracle Blockchain Platform unterstützt. Dies ist eine generische Methode zum Ausführen von SQL-Abfragen für das 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{}
: Enthält die Ausgabe der Abfrage. Das Ergebnis ist in Form von Schnittstellenbereichen. Sie müssen den Abschnitt iterieren und die Elemente verwenden, indem Sie sie in die richtigen Typen konvertieren.
error
- Enthält den Fehler, falls beobachtet.
-
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 Chaincodes, der aufgerufen werden soll.
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-Chain-Code-Aufruf als JSON-Objekt zurückgegeben wird.
message
: Die Nachricht, die vom Cross-Chain-Code-Aufruf im UTF-8-Format zurückgegeben wird.
- Beispiel für den 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 Chaincodes, der aufgerufen werden soll.
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-Chain-Code-Aufruf im UTF-8-Format zurückgegeben wird.
message
: Die Nachricht, die vom Cross-Chain-Code-Aufruf im UTF-8-Format zurückgegeben wird.
- Beispiel für den 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}"
}
Composite-Schlüsselmethoden
-
GenerateCompositeKey
- Diese Methode generiert und gibt den zusammengesetzten Schlüssel basierend auf dem
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, basierend auf dem der zusammengesetzte Schlüssel gebildet werden muss.
- Rückgabewert:
string
: Enthält das Ergebnis des zusammengesetzten Schlüssels.
error
- Enthält den Fehler, falls beobachtet.
-
GetByCompositeKey
- Diese Methode gibt das Asset zurück, das mit dem Schlüssel und der in den Parametern 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
von Hyperledger Fabric auf.
func GetByCompositeKey(key string, columns []string, index int)
(interface{}, error)
- Parameter:
key (string)
: Objekttyp beim Erstellen des zusammengesetzten Schlüssels angegeben.
column ([]string)
: Dies ist der Bereich von Attributen, für die das Ledger mit dem zusammengesetzten Schlüssel abgefragt werden muss.
index(int)
: Index des Attributs.
- Rückgabewert:
Interface{}
: Enthält die Liste der Assets, die das Ergebnis dieser Methode sind.
error
: Enthält eventuelle Fehler.
Stub-Methode
-
GetNetworkStub
- Diese Methode gibt die Hyperledger Fabric
chaincodeStub
zurück.
- Sie können den Shim-Stub aufrufen, indem Sie die Methode
GetNetworkStub
aufrufen. Dies wird Ihnen helfen, Ihre eigene Implementierung zu schreiben, die direkt mit den Assets zusammenarbeitet.
func GetNetworkStub() shim.ChaincodeStubInterface
- Parameter:
- Rückgabewert:
shim.ChaincodeStubInterface
- Dies ist der Hyperledger Fabric Chaincode-Stub.
Andere Methoden
GetTransactionId()
GetTransactionTimestamp()
GetChannelID()
GetCreator()
GetSignedProposal()
GetArgs()
GetStringArgs()
GetCreatorMspId()
GetId
-
GetTransactionId
- 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:
- Rückgabewert:
string
- Enthält die erforderliche Transaktions-ID.
-
GetTransactionTimestamp
- Gibt den Zeitstempel zurück, zu dem die Transaktion erstellt wurde. Dies wird aus der Transaktion
ChannelHeader
übernommen. Sie gibt daher den Zeitstempel des Clients an und hat denselben Wert für alle Bestätiger.
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
- Parameter:
- Rückgabewert:
timestamp.Timestamp
: Enthält den erforderlichen Zeitstempel.
error
: Enthält eventuelle Fehler.
-
GetChannelID
- Gibt die Kanal-ID für den Vorschlag für den zu verarbeitenden Chaincode zurück.
func GetChannelID() string
- Parameter:
- Rückgabewert:
string
: Enthält die erforderliche Kanal-ID als Zeichenfolge.
-
GetCreator
- Gibt das Identity-Objekt des Weiterleitenden des Chaincode-Aufrufs zurück
func GetCreator() ([]byte, error)
- Parameter:
- Rückgabewert:
[]byte
: Enthält das erforderliche Identitätsobjekt, das serialisiert wurde.
error
: Enthält eventuelle Fehler.
-
GetSignedProposal
- Gibt ein vollständig dekodiertes Objekt des unterzeichneten Transaktionsvorschlags zurück.
func GetSignedProposal() (*peer.SignedProposal, error)
- Parameter:
- Rückgabewert:
*peer.SignedProposal
: Enthält das erforderliche signierte Vorschlagsobjekt.
error
: Enthält eventuelle Fehler.
-
GetArgs
- Gibt die Argumente als Array von Zeichenfolgen aus der Chaincode-Aufrufanforderung zurück.
func GetArgs() [][]byte
- Parameter:
- Rückgabewert:
[][]byte
: Enthält die übergebenen Argumente.
-
GetStringArgs
- Gibt die Argumente zurück, die für den Chaincode Init and Invoke als Zeichenfolgenarray bestimmt sind.
func GetStringArgs() []string
- Parameter:
- Rückgabewert:
[]string
: Enthält die erforderlichen Argumente als Zeichenfolgenarray.
-
GetCreatorMspId
- Gibt die MSP-ID der aufrufenden Identity zurück.
-
func GetCreatorMspId() string
- Parameter:
- Rückgabewert:
string
: Gibt die MSP-ID der aufrufenden Identität zurück.
-
GetId
- Wenn das Asset einen abgeleiteten Schlüssel als
Id
aufweist, können Sie diese Methode verwenden, um eine abgeleitete ID abzurufen. Diese Methode gibt einen Fehler zurück, wenn der abgeleitete Schlüssel %t
(timestamp) enthält.
- Parameter:
object
: Das Objekt muss alle Eigenschaften enthalten, von denen der abgeleitete Schlüssel abhängig ist.
- 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 im Utilitypackage können nützlich sein:
-
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, aus der das Objekt erstellt werden soll.
obj (interface{})
: Die Referenz des Objekts, das aus der JSON-Zeichenfolge erstellt werden soll. Dieses Objekt speichert das erstellte Modell, das auch gemäß Validator-Tags validiert wird.
- Rückgabewert:
error
: Enthält alle Fehler, die beim Erstellen oder Validieren des Assets gefunden wurden.
-
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{}))
: Zuordnung, die in das Assetobjekt konvertiert werden muss.
resultStruct (interface{})
: Die Referenz des erforderlichen Assetobjekts, das aus der Map generiert werden muss. Enthält das erforderliche Ergebnisassetobjekt.
- Rückgabewert:
error
: Enthält alle Fehler, die beim Erstellen oder Validieren des Assets gefunden wurden.
Token-SDK-Methoden finden Sie in den Themen unter Tokenisierungsunterstützung mit Blockchain App Builder.
Controller
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 auf Chaincode-Struktur definiert sind, können von außen aufgerufen werden. Die übrigen Methoden sind ausgeblendet.
Automatisch generierte Methoden
Wie unter Eingabespezifikationsdatei beschrieben, können Sie angeben, welche CRUD-Methoden in der Spezifikationsdatei generiert werden sollen. Wenn Sie z.B. alle Methoden generieren möchten, sieht das Ergebnis wie folgt aus:
//
//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 unserer Beispielspezifikationsdatei generiert.
Die executeQuery
zeigt, wie SQL Rich-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 Geschäftslogik implementieren. Wenn Sie benutzerdefinierte Methoden hinzufügen, fügen Sie sie der Controllerdatei hinzu. Wenn Sie der Bibliothek benutzerdefinierte Methoden anstelle der Controllerdatei hinzufügen, gehen Ihre Änderungen verloren, wenn der Inhalt des Bibliotheksordners während der Synchronisierungs- oder Chaincode-Aktualisierung 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-Kettencodes muss jede benutzerdefinierte Methode zwei Werte zurückgeben:
leere Schnittstelle,
Fehler. Beispiel:
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 auf der Hyperledger Fabric v1.4.7-Plattform bereitstellen oder ein Upgrade durchführen, wird die Methode Init
auch automatisch aufgerufen. Wenn Sie die Oracle Blockchain Platform-Konsole auf der Hyperledger Fabric v2.x-Plattform bereitstellen oder ein Upgrade durchfü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
}
Wenn Sie jetzt einen Anwendungsstatus initialisieren möchten, können Sie diese Methode verwenden.