Blockchain App Builder prend l'entrée de votre fichier de spécification et génère un projet de code de chaîne entièrement fonctionnel. Le projet contient des classes et des fonctions générées automatiquement, des méthodes CRUD, des méthodes SDK, la validation automatique des arguments, la conversion de paramètres/déconversion de paramètres et la capacité de persistance transparente (ORM).
Si le projet de code de chaîne est en langue Go, le projet échafaudé contient trois fichiers principaux :
main.go
<chaincodeName>.model.go
<chaincodeName>.controller.go
Toutes les bibliothèques nécessaires sont installées et packagées.
Le fichier <chaincodeName>.model.go
dans le sous-répertoire model
contient plusieurs définitions de ressource et le fichier <chaincodeName>.controller.go
dans le sous-répertoire controller
contient le comportement de la ressource et les méthodes CRUD. Les différents balises et ensembles de structure Go dans model.go
et controller.go
prennent en charge des fonctions telles que la validation automatique des arguments, la conversion des paramètres/déconversion des paramètres des arguments, la capacité de persistance transparente (ORM) et l'appel des interrogations enrichies.
Le projet échafaudé peut être trouvé dans $GOPATH/src/example.com/<chaincodeName>
Informations de référence :
Modèle
Propriété de type d'immobilisation
Par défaut, chaque structure aura une propriété supplémentaire appelée
AssetType
. Cette propriété peut être utile pour extraire uniquement les ressources de ce type. Toute modification de cette propriété est ignorée lors de la création et de la mise à jour de la ressource. La valeur de propriété par défaut est
<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"'
}
Validateurs
-
ID
id:"true"
- Ce valideur identifie la propriété qui définit de manière unique l'immobilisation sous-jacente. L'immobilisation est enregistrée par la valeur de cette clé. Ce valideur s'applique automatiquement lorsqu'un nouveau projet Go est échafaudé.
- Dans la capture d'écran ci-dessous,
"SupplierId"
est la clé de la ressource fournisseur et comporte une propriété de marqueur id:"true"
pour la propriété 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"'
}
-
Dérivé
derived:"strategy,algorithm,format"
- Ce décorateur est utilisé pour définir l'attribut dérivé d'autres propriétés. Ce décorateur a deux paramètres obligatoires :
strategy
: Prend les valeurs concat
ou hash
. Nécessite un paramètre supplémentaire algorithm
si hash
est sélectionné. L'algorithme par défaut est sha256
; md5
est également pris en charge.
format
: Prend un tableau de chaînes de spécification et de valeurs à utiliser par la stratégie.
-
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"'
}
-
Obligatoire
validate:"mandatory"
- Cela marque la propriété suivante comme obligatoire et ne peut pas être ignorée lors de l'enregistrement dans le livre. S'il est ignoré, une erreur est générée. Dans l'exemple ci-dessous,
"SupplierId"
a un marqueur 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"'
}
-
Par défaut
default:"<param>"
- Cela indique que la propriété suivante peut avoir une valeur par défaut. La valeur par défaut du marqueur par défaut est utilisée lorsque la propriété est ignorée lors de l'enregistrement dans le livre. Dans l'exemple de propriété ci-dessous,
Active
a une valeur par défaut de true
, fournie en tant que marqueur default:"true"
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"'
}
-
Valider les types
- Les types Go de base sont validés pour une propriété en définissant un marqueur de validation. Voici les marqueurs de validation basés sur les types :
- chaîne :
validate: "string"
- Date :
validate: "date"
- numéro :
validate: "int"
- booléen :
validate: "bool"
-
Valideur minimal
validate:"min=<param>"
- À l'aide du valideur minimal, vous pouvez définir une valeur minimale pour une propriété de type nombre et chaîne.
- Pour le type int : Dans l'exemple, la propriété
RawMaterialAvailable
a une valeur minimale de 0 et si une valeur inférieure à 0 est appliquée à RawMaterialAvailable
, une erreur est retournée.
- Pour la chaîne de type : Pour le valideur minimal de type de chaîne, vérifiez la longueur de la chaîne avec la valeur fournie. Par conséquent, dans l'exemple ci-dessous, la propriété
License
doit comporter au moins 10 caractères.
- Exemple :
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"'
}
-
Valideur maximal
validate:"max=<param>"
- À l'aide du valideur max, la valeur maximale peut être définie pour une propriété de type nombre et chaîne.
- Pour le type int : Comme le valideur min, pour le type int, si une valeur fournie pour
structfield
est supérieure à la valeur fournie dans le valideur, une erreur est retournée.
- Pour la chaîne de type : Comme pour le valideur min, le valideur max vérifie également la longueur de la chaîne avec la valeur indiquée. Dans l'exemple, la propriété
Domain
a une valeur maximale de 50. Par conséquent, si la propriété Domain
a une longueur de chaîne supérieure à 50 caractères, un message d'erreur sera retourné.
-
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"'
}
-
Valideurs de date
- Avant le valideur :
validate:"before=<param>"
- Le valideur avant valide une propriété de type
date
pour qu'elle ait une valeur inférieure à celle spécifiée dans le paramètre.
- Dans cet exemple, la propriété
ExpiryDate
doit être antérieure à "2020-06-26"
et, dans le cas contraire, elle retournera une erreur.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"'
}
- Après le valideur :
validate:"after=<param>"
- Le valideur avant valide une propriété de type
date
pour qu'elle ait une valeur supérieure à celle spécifiée dans le paramètre.
- Dans cet exemple, la propriété
CompletionDate
doit être postérieure à "2020-06-26"
et, dans le cas contraire, elle retournera une erreur.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"'
}
-
Valideur d'URL
validate:"url"
- Le valideur d'URL validera une propriété pour les chaînes d'URL.
- Dans cet exemple, la propriété
Domain
doit être une URL valide.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"'
}
-
Valideur Regexp
validate:"regexp=<param>"
- Le valideur d'expression rationnelle validera la propriété de l'expression rationnelle d'entrée.
- Dans cet exemple, la propriété
PhoneNumber
sera validée pour un numéro de cellulaire conformément à l'expression rationnelle.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"'
}
-
Valideurs multiples
- Plusieurs valideurs peuvent être appliqués à une propriété.
- Dans cet exemple, la propriété
Domain
a une validation pour une chaîne, une URL et une longueur minimale et maximale de chaîne.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
La capacité de persistance transparente ou ORM simplifiée est saisie dans la classe Model
de l'objet Context (Ctx
). Si votre modèle appelle l'une des méthodes de trousse SDK suivantes, accédez-y à l'aide de t.Ctx.Model
.
Les méthodes de trousse SDK qui mettent en oeuvre ORM sont les suivantes :
Save
- Appel de la méthode Hyperledger Fabric PutState
Get
- Appel de la méthode Hyperledger Fabric GetState
Update
- Appel de la méthode Hyperledger Fabric PutState
Delete
- Appel de la méthode Hyperledger Fabric DeleteState
History
- Appel de la méthode Hyperledger Fabric GetHistoryForKey
GetByRange
- Appel de la méthode Hyperledger Fabric GetStateByRange
GetByRangeWithPagination
- Appel de la méthode Hyperledger Fabric GetStateByRangeWithPagination
Méthodes SDK
De plus, les codes de chaîne mettent en oeuvre la capacité de persistance transparente (ORM) avec l'ensemble de modèles.
Note :
Depuis la version 21.2.3, la façon d'accéder aux méthodes ORM a changé. Exécutez la commande
ochain --version
pour déterminer la version du générateur d'applications Blockchain.
Dans les versions précédentes, les méthodes ORM étaient exposées en tant que méthodes statiques dans le package de modèles. Les méthodes sont maintenant définies sur le destinataire du modèle, qui contient le talon de transaction. Pour appeler ces méthodes, vous utilisez le récepteur de modèle détenu par le contexte de transaction dans le contrôleur. Vous appelez ces méthodes t.Ctx.Model.<method_name>
au lieu de model.<method_name>
.
L'exemple suivant montre les appels de méthode Save
et Get
dans les versions précédentes :
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
}
L'exemple suivant montre les appels de méthode Save
et Get
à partir de la version 21.2.3 et des versions ultérieures :
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
}
Après la mise à niveau vers la version 21.2.3, apportez cette modification à tous les projets de code de chaîne que vous avez créés avec une version antérieure de Blockchain App Builder. Si vous utilisez la commande sync
pour synchroniser les modifications entre le fichier de spécification et votre code source, les modifications sont automatiquement apportées à votre contrôleur pour les méthodes prêtes à l'emploi. Vous devez toujours résoudre manuellement les conflits.
Les méthodes ORM suivantes sont exposées via le package de modèles :
-
Get
- Interroge le grand livre de l'immobilisation stockée en fonction du code indiqué.
-
func Get(Id string, result ...interface{}) (interface{}, error)
- Paramètres :
Id
- ID de l'immobilisation requis dans le livre.
result (interface{})
- Il s'agit d'un objet de ressource vide d'un type particulier, qui est transmis par référence. Cet objet contiendra le résultat de cette méthode. À utiliser uniquement si un résultat spécifique au type est requis.
asset (interface)
- Objet de ressource vide, transmis par référence. Cet objet contiendra le résultat de cette méthode. À utiliser uniquement si un résultat spécifique au type est requis.
- Retourne :
interface {}
- L'interface contient la ressource sous la forme map[string]interface{}
. Avant d'opérer sur cette carte, il est nécessaire d'affirmer l'interface obtenue avec le type map[string]interface{}
. Pour convertir ce mappage en objet de ressource, vous pouvez utiliser l'API de l'utilitaire util.ConvertMaptoStruct
(voir : Ensemble d'utilitaire).
error
- Contient une erreur si elle est retournée ou est nulle.
-
Update
- Met à jour l'immobilisation fournie dans le grand livre avec les nouvelles valeurs.
-
func Update(args ...interface{}) (interface{}, error)
- Paramètres :
obj (interface)
- L'objet qui doit être mis à jour dans le livre est transmis par référence à cette API avec les nouvelles valeurs. L'immobilisation d'entrée est validée et vérifiée en fonction des balises struct mentionnées dans la spécification du modèle, puis stockée dans le grand livre.
- Retourne :
interface{}
- La ressource enregistrée est retournée en tant qu'interface.
error
- Contient une erreur si elle est retournée ou est nulle.
-
Save
- Enregistre l'immobilisation dans le grand livre après validation sur tous les marqueurs de structure.
-
func Save(args ...interface{}) (interface{}, error)
- Paramètres :
obj/args[0] (interface{})
- L'objet qui doit être stocké dans le livre est transmis par référence dans cette méthode d'utilitaire.
metadata/args[1] (interface{})
- Ce paramètre est facultatif. Il a été fourni afin de vous faciliter la tâche si vous devez stocker des métadonnées dans le grand livre avec l'immobilisation au moment de l'exécution. Ce paramètre peut être ignoré s'il n'existe aucune exigence de ce type.
- Retourne :
interface {}
- La ressource est retournée en tant qu'interface.
error
- Contient une erreur si elle est retournée ou est nulle.
-
Delete
- Supprime l'immobilisation du grand livre.
-
func Delete(Id string) (interface{}, error)
- Paramètres :
id (string)
- ID de l'immobilisation qui doit être supprimé du livre.
- Retourne :
interface {}
- Contient la ressource en cours de suppression sous la forme map[string]interface{}
.
-
GetByRange
- Retourne la liste des immobilisations par intervalle d'ID.
-
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
- Paramètres :
startkey (string)
- ID début de l'intervalle d'objets requis.
endkey (string)
- Fin de l'intervalle d'objets requis.
asset interface
- (facultatif) Tableau vide des ressources, qui est transmis par référence. Ce tableau contiendra le résultat de cette méthode. À utiliser si un résultat spécifique au type est requis.
- Retourne :
[]map[string]interface{}
- Ce tableau contient la liste des immobilisations obtenues à partir du livre. Vous pouvez accéder aux objets itérant sur ce tableau et affirmant que les objets sont map[string]interface{}
et à l'aide de l'utilitaire de conversion en objet de ressource.
error
- Contient une erreur si elle est retournée ou est nulle.
-
GetByRangeWithPagination
- La méthode
GetByRangeWithPagination
est une méthode statique de la classe OchainModel
héritée des classes Model
concrètes de {chaincodeName}.model.ts
.
- Cette action retourne une liste des ressources comprises entre
startId
et endId
, filtrées par taille de page et signet. Cette méthode appelle la méthode Hyperledger Fabric GetStateByRangeWithPagination
en interne.
- Si le paramètre
modelName
n'est pas fourni, la méthode retourne Promise<Object [ ] >
. Si le paramètre modelName
est fourni, la méthode traite la conversion dans le type d'appelant Model
. Dans l'exemple suivant, le tableau de résultats est de type Supplier
. Si l'immobilisation retournée à partir du livre n'est pas de type Model
, elle ne sera pas incluse dans la liste. Cette vérification est effectuée par la propriété assetType
en lecture seule dans la classe Model
.
- Pour retourner toutes les ressources comprises entre
startId
et endId
, filtrées par taille de page et signets, utilisez la méthode de contrôleur générique getAssetsByRange
.
-
func (m *Model) GetByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string, asset ...interface{}) ([]map[string]interface{}, error)
- Paramètres :
startkey : string
- Clé de démarrage de l'intervalle. Inclus dans l'intervalle.
endkey : string
- Clé de fin de l'intervalle. Exclu de l'intervalle.
pageSize : number
- Taille de page de l'interrogation.
Bookmark : string
- Signet de l'interrogation. La sortie commence à partir de ce signet.
asset interface
- (Facultatif) Tableau vide de ressources, transmis par référence. Ce tableau contiendra le résultat de cette méthode. Utilisez ce paramètre pour obtenir des résultats propres au type.
- Retourne :
[]map[string]interface{}
- Tableau qui contient la liste des immobilisations extraites du livre. Vous pouvez accéder aux objets en effectuant une itération sur ce tableau et en affirmant que les objets sont map[string]interface{}
et en utilisant un utilitaire pour la conversion en objet de ressource.
error
- Contient une erreur si une erreur est retournée, sinon vide.
-
GetHistoryById
- Retourne l'historique de l'immobilisation avec l'ID indiqué.
-
func GetHistoryByID(Id string) ([]interface{}, error)
- Paramètres :
Id (string)
- ID de la ressource pour laquelle l'historique est nécessaire.
- Retourne :
[]interface{}
- Ce fragment contient l'historique de l'immobilisation obtenue à partir du livre sous la forme d'un fragment de map[string]interface{}
. Vous pouvez accéder à chaque élément d'historique en itérant sur cette tranche et en affirmant que les objets sont map[string]interface{}
et en utilisant l'utilitaire pour les convertir en objet de ressource.
error
- Contient l'erreur si elle est observée.
-
Query
- La méthode d'interrogation exécutera une interrogation SQL/Couch DB sur le livre. Cette méthode n'est prise en charge que pour le déploiement à distance sur Oracle Blockchain Platform. Il s'agit d'une méthode générique pour exécuter des interrogations SQL sur le grand livre.
-
func Query(queryString string) ([]interface{}, error)
- Paramètres :
queryString (string)
- Entrez la chaîne d'interrogation.
- Retourne :
[]interface{}
- Contient la sortie de l'interrogation. Le résultat est sous forme de tranche d'interfaces. Vous devez effectuer une itération sur la tranche et utiliser les éléments en les convertissant en types appropriés.
error
- Contient l'erreur si elle est observée.
-
QueryWithPagination
- La méthode d'interrogation exécutera une interrogation SQL/Couch DB sur le livre, filtrée par taille de page et signet. Cette méthode n'est prise en charge que pour le déploiement à distance sur Oracle Blockchain Platform. Il s'agit d'une méthode générique pour exécuter des interrogations SQL sur le grand livre.
-
func (m *Model) QueryWithPagination(queryString string, pageSize int32, bookmark string) ([]interface{}, error)
- Paramètres :
queryString (string)
- Interrogation SQL/Couch DB enrichie.
pageSize : number
- Taille de page de l'interrogation.
bookmark : string
- Signet de l'interrogation. La sortie commence à partir de ce signet.
- Retourne :
[]interface{}
- Contient la sortie de l'interrogation. Le résultat est sous forme de tranche d'interfaces. Vous devez effectuer une itération sur la tranche et utiliser les éléments en les convertissant en types appropriés.
error
- Contient l'erreur si elle est observée.
-
InvokeCrossChaincode
- Vous pouvez utiliser cette méthode dans un code de chaîne pour appeler une fonction dans un autre code de chaîne. Les deux codes de chaîne doivent être installés sur le même pair.
-
func InvokeCrossChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
- Paramètres :
chaincodeName
- Nom du code de chaîne à appeler.
methodName
- Nom de la méthode à appeler dans le code de chaîne.
arg
- Argument de la méthode appelante.
channelName
- Canal sur lequel se trouve le code de chaîne à appeler.
- Retourne :
interface{}
- Retourne un objet map[string]interface{}
qui contient trois clés :
isValid
- true
si l'appel est valide.
payload
- Sortie retournée par l'appel inter-code, en tant qu'objet JSON.
message
- Message retourné par l'appel inter-code, au format UTF-8.
- Exemple de valeur renvoyée :
{
"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
- Vous pouvez utiliser cette méthode dans un code de chaîne pour appeler une fonction dans un autre code de chaîne. Les deux codes de chaîne doivent être installés sur le même pair.
-
func InvokeChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
- Paramètres :
chaincodeName
- Nom du code de chaîne à appeler.
methodName
- Nom de la méthode à appeler dans le code de chaîne.
arg
- Argument de la méthode appelante.
channelName
- Canal sur lequel se trouve le code de chaîne à appeler.
- Retourne :
interface{}
- Retourne un objet map[string]interface{}
qui contient trois clés :
isValid
- true
si l'appel est valide.
payload
- Sortie retournée par l'appel inter-code de chaîne, au format UTF-8.
message
- Message retourné par l'appel inter-code, au format UTF-8.
- Exemple de valeur renvoyée :
{
"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}"
}
Méthodes clés composites
-
GenerateCompositeKey
- Cette méthode génère et retourne la clé composite en fonction de
indexName
et des attributs indiqués dans les arguments.
func GenerateCompositeKey(indexName string, attributes []string)
(string, error)
- Paramètres :
indexName (string)
- Type d'objet de la clé composite.
attrbutes ([]string)
- Attributs de la ressource en fonction desquels la clé composite doit être formée.
- Retourne :
string
- Contient le résultat de la clé composite.
error
- Contient l'erreur si elle est observée.
-
GetByCompositeKey
- Cette méthode retourne l'immobilisation correspondant à la clé et à la colonne indiquées dans les paramètres. Le paramètre
index
indique l'index de la clé retournée dans le tableau de la méthode stub SplitCompositeKey
.
- En interne, cette méthode appelle
getStateByPartialCompositeKey
, splitCompositeKey
et getState
de Hyperledger Fabric.
func GetByCompositeKey(key string, columns []string, index int)
(interface{}, error)
- Paramètres :
key (string)
- Type d'objet fourni lors de la création de la clé composite.
column ([]string)
- Il s'agit de la tranche d'attributs sur laquelle le livre doit être interrogé à l'aide de la clé composite.
index(int)
- Index de l'attribut.
- Retourne :
Interface{}
- Contient la liste des ressources résultant de cette méthode.
error
- Contient les erreurs éventuelles.
Méthode de talon
-
GetNetworkStub
- Cette méthode retourne la structure Hyperledger Fabric
chaincodeStub
.
- Vous pouvez accéder au talon de cale en appelant la méthode
GetNetworkStub
. Cela vous aidera à écrire votre propre implémentation en travaillant directement avec les ressources.
func GetNetworkStub() shim.ChaincodeStubInterface
- Paramètres :
- Retourne :
shim.ChaincodeStubInterface
- Il s'agit du code de chaîne Hyperledger Fabric.
Autres méthodes
GetTransactionId()
GetTransactionTimestamp()
GetChannelID()
GetCreator()
GetSignedProposal()
GetArgs()
GetStringArgs()
GetCreatorMspId()
GetId
-
GetTransactionId
- Retourne l'ID transaction pour la demande d'appel de code de chaîne courante. L'ID transaction identifie de manière unique la transaction dans la portée du canal.
func GetTransactionId() string
- Paramètres :
- Retourne :
string
- Contient l'ID transaction requis.
-
GetTransactionTimestamp
- Retourne l'horodatage auquel la transaction a été créée. Ceci est tiré de la transaction
ChannelHeader
, donc il indiquera l'horodatage du client, et aura la même valeur pour tous les endossants.
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
- Paramètres :
- Retourne :
timestamp.Timestamp
- Contient l'horodatage requis.
error
- Contient les erreurs éventuelles.
-
GetChannelID
- Retourne l'ID canal à traiter pour la proposition de code de chaîne.
func GetChannelID() string
- Paramètres :
- Retourne :
string
- Contient l'ID canal requis sous forme de chaîne.
-
GetCreator
- Retourne l'objet d'identité de l'émetteur de l'appel de chaîne
func GetCreator() ([]byte, error)
- Paramètres :
- Retourne :
[]byte
- Contient l'objet d'identité requis sérialisé.
error
- Contient les erreurs éventuelles.
-
GetSignedProposal
- Retourne un objet entièrement décodé de la proposition de transaction signée.
func GetSignedProposal() (*peer.SignedProposal, error)
- Paramètres :
- Retourne :
*peer.SignedProposal
- Contient l'objet de proposition signé requis.
error
- Contient les erreurs éventuelles.
-
GetArgs
- Retourne les arguments en tant que tableau de chaînes à partir de la demande d'appel du code de chaîne.
func GetArgs() [][]byte
- Paramètres :
- Retourne :
[][]byte
- Contient les arguments transmis.
-
GetStringArgs
- Renvoie les arguments destinés au code de chaîne Init et Invoke sous forme de tableau de chaînes.
func GetStringArgs() []string
- Paramètres :
- Retourne :
[]string
- Contient les arguments requis sous forme de tableau de chaînes.
-
GetCreatorMspId
- Retourne l'ID MSP de l'identité appelante.
-
func GetCreatorMspId() string
- Paramètres :
- Retourne :
string
- Retourne l'ID MSP de l'identité appelante.
-
GetId
- Lorsque la ressource a une clé dérivée
Id
, vous pouvez utiliser cette méthode pour obtenir un ID dérivé. Cette méthode retournera une erreur si la clé dérivée contient %t
(horodatage).
- Paramètres :
object
- L'objet doit contenir toutes les propriétés dont dépend la clé dérivée.
- Retourne :
- Retourne la clé dérivée sous forme de chaîne.
- Exemple :
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)
}
Ensemble utilitaire
Les méthodes suivantes du package d'utilitaires peuvent être utiles :
-
Util.CreateModel
- Analyse la chaîne JSON fournie et crée un objet de ressource du type fourni.
func CreateModel(obj interface{}, inputString string) error
- Paramètres :
inputString (string)
- Chaîne JSON d'entrée à partir de laquelle l'objet doit être créé.
obj (interface{})
- Référence de l'objet à créer à partir de la chaîne JSON. Cet objet stockera le modèle créé qui est également validé selon les balises du valideur.
- Retourne :
error
- Contient toutes les erreurs détectées lors de la création ou de la validation de la ressource.
-
util.ConvertMapToStruct
- Convertir la carte fournie en objet de type fourni.
func ConvertMapToStruct(inputMap map[string](interface{}), resultStruct
interface{}) error
- Paramètres :
inputMap (map[string](interface{}))
- Mappage qui doit être converti en objet de ressource.
resultStruct (interface{})
- Référence de l'objet de ressource requis qui doit être généré à partir du mappage. Contient l'objet de ressource de résultat requis.
- Retourne :
error
- Contient toutes les erreurs détectées lors de la création ou de la validation de la ressource.
Pour les méthodes de trousse SDK de jeton, voir les rubriques sous Prise en charge de la tokenisation à l'aide du générateur d'applications Blockchain.
Contrôleur
Le fichier Controller.go
met en oeuvre la CRUD et les méthodes personnalisées pour les ressources.
Vous pouvez créer autant de classes, de fonctions ou de fichiers que vous le souhaitez, mais seules les méthodes définies sur la structure de code de chaîne sont invokables de l'extérieur, le reste étant masqué.
Méthodes générées automatiquement
Comme décrit dans Fichier de spécification d'entrée, vous pouvez spécifier les méthodes CRUD à générer dans le fichier de spécification. Par exemple, si vous avez choisi de générer toutes les méthodes, le résultat sera similaire à ce qui suit :
//
//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
}
Méthodes personnalisées
Les méthodes personnalisées suivantes ont été générées à partir de notre exemple de fichier de spécification.
executeQuery
montre comment les interrogations riches en SQL peuvent être appelées. Les validateurs par rapport aux arguments sont ajoutés automatiquement par Blockchain App Builder en fonction du type d'argument spécifié dans le fichier de spécification.
Vous pouvez implémenter la fonctionnalité en fonction de la logique métier. Si vous ajoutez des méthodes personnalisées, ajoutez-les au fichier de contrôleur. Si vous ajoutez des méthodes personnalisées à la bibliothèque au lieu du fichier de contrôleur, vos modifications seront perdues lorsque le contenu du dossier de bibliothèque sera mis à jour lors des processus de synchronisation ou de mise à niveau du code de chaîne.
//
//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
}
Pour les codes de chaîne Go, chaque méthode personnalisée doit retourner deux valeurs :
interface vide,
erreur. Par exemple :
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) {
return nil, nil
}
Méthode d'initialisation
Une méthode Init
personnalisée est fournie dans le contrôleur avec une définition vide. Si vous utilisez le générateur d'applications de chaîne de blocs pour déployer ou mettre à niveau, la méthode Init
est appelée automatiquement. Si vous déployez ou effectuez une mise à niveau à partir de la console Oracle Blockchain Platform sur la plate-forme Hyperledger Fabric v1.4.7, la méthode Init
est également appelée automatiquement. Si vous déployez ou effectuez une mise à niveau à partir de la console Oracle Blockchain Platform sur la plate-forme Hyperledger Fabric v2.x, vous devez appeler la méthode Init
manuellement. Vous pouvez utiliser un outil tiers tel que Postman pour appeler manuellement la méthode Init
.
type Controller struct {
}
func (t *Controller) Init(args string) (interface{}, error)
{ return nil, nil
}
Si vous souhaitez initialiser n'importe quel état d'application à ce stade, vous pouvez utiliser cette méthode pour ce faire.