Projet de code de chaîne de démarrage échafaudé

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/désactivation des paramètres et la capacité de persistance transparente (ORM).

Si le projet de code de chaîne utilise le langage 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 packages Go struct dans model.go et controller.go prennent en charge des fonctionnalités telles que la validation automatique des arguments, la conversion/déconversion des paramètres des arguments, la capacité de persistance transparente (ORM) et l'appel d'interrogations riches.

Le projet échafaudé se trouve dans le répertoire $GOPATH/src/example.com/<chaincodeName>.

Modèle

Propriété de type d'immobilisation

Par défaut, chaque structure a une propriété supplémentaire appelée AssetType. Vous pouvez utiliser cette propriété pour extraire uniquement les ressources de ce type. Toutes les modifications apportées à cette propriété sont ignorées lors de la création ou de la mise à jour des ressources. 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 est automatiquement appliqué lorsqu'un nouveau projet Go est échafaudé.
Dans l'exemple suivant, SupplierId est la clé de la ressource de 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ée
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. Si hash est spécifié, le paramètre supplémentaire algorithm est requis. 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"
Ce décorateur marque la propriété suivante comme obligatoire, de sorte qu'elle ne peut pas être ignorée lors de l'enregistrement dans le livre. Si elle est ignorée, une erreur est générée. Dans l'exemple suivant, la propriété SupplierId comporte 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"'
}
Valeur par défaut
default:"<param>"
Ce décorateur indique que la propriété suivante a une valeur par défaut. La valeur 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 suivant, Active a une valeur par défaut de true, spécifiée 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"'
}
Types de validation
Les types Go de base sont validés pour une propriété en définissant un marqueur de validation. Les marqueurs de validation suivants sont basés sur les types de base :
  • chaîne : validate: "string"
  • date : validate: "date"
  • numéro : validate: "int"
  • booléen : validate: "bool"
Valideur de minute
validate:"min=<param>"
Vous pouvez utiliser le valideur min pour définir la valeur minimale d'une propriété de type nombre ou chaîne.
Pour le type int : Dans l'exemple suivant, la propriété RawMaterialAvailable a une valeur minimale de 0. Si une valeur inférieure à 0 est appliquée à la propriété RawMaterialAvailable, une erreur est retournée.
Pour le type string : Le valideur minimum vérifie la longueur de la chaîne par rapport à la valeur spécifiée. Dans l'exemple suivant, la propriété License doit comporter au moins dix caractères.
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 max.
validate:"max=<param>"
Vous pouvez utiliser le valideur max pour définir la valeur maximale d'une propriété de type nombre et chaîne.
Pour le type int : Semblable au valideur min, si une valeur spécifiée pour un champ struct est supérieure à la valeur fournie dans le valideur, une erreur est retournée.
Pour le type string : Comme pour le min validator, le max validator vérifie la longueur de la chaîne par rapport à la valeur indiquée. Dans l'exemple suivant, 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 before valide une propriété de type date pour qu'elle ait une valeur inférieure au paramètre spécifié.
Dans l'exemple suivant, la propriété ExpiryDate doit être antérieure à "2020-06-26" et, si ce n'est pas le cas, une erreur est retournée.
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 après valide une propriété de type date pour qu'elle ait une valeur supérieure au paramètre spécifié.
Dans l'exemple suivant, 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 valide une propriété pour les chaînes d'URL.
Dans l'exemple suivant, 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 d'expression rationnelle
validate:"regexp=<param>"
Le valideur d'expression rationnelle valide une propriété avec l'expression rationnelle spécifiée.
Dans l'exemple suivant, 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"'
}
Plusieurs valideurs
Plusieurs valideurs peuvent être appliqués à une propriété.
Dans l'exemple suivant, la propriété Domain comporte une validation pour une chaîne, une URL et une longueur de chaîne minimale et maximale.
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é 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 suivantes mettent en oeuvre ORM :
  • Save appelle la méthode PutState Hyperledger Fabric.
  • Get appelle la méthode GetState Hyperledger Fabric.
  • Update appelle la méthode PutState Hyperledger Fabric.
  • Delete appelle la méthode DeleteState Hyperledger Fabric.
  • History appelle la méthode GetHistoryForKey Hyperledger Fabric.
  • GetByRange appelle la méthode GetStateByRange Hyperledger Fabric.
  • GetByRangeWithPagination appelle la méthode GetStateByRangeWithPagination Hyperledger Fabric.

Méthodes SDK

Les codes de chaîne de Go mettent en oeuvre la fonctionnalité Transparent Persistence Capability (ORM) avec l'ensemble de modèle.

Note :

À partir de 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 l'ensemble de modèles. Les méthodes sont maintenant définies dans 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 en tant que t.Ctx.Model.<method_name> au lieu de model.<method_name>.

L'exemple suivant présente 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 des versions 21.2.3 et 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 du générateur d'applications Blockchain. 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 tout conflit.

Les méthodes ORM suivantes sont exposées par l'ensemble de modèles :

Get
Interroge le grand livre pour l'immobilisation stockée en fonction du code indiqué.
func Get(Id string, result ...interface{}) (interface{}, error)
Paramètres :
  • Id - ID de la ressource à extraire du livre.
  • result (interface{}) - Objet de ressource vide d'un type particulier, transmis par référence. Cet objet contiendra le résultat de cette méthode. Utilisez ce paramètre 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. Utilisez ce paramètre uniquement si un résultat spécifique au type est requis.
Retourne :
  • interface {} - L'interface contient la ressource dans le formulaire map[string]interface{}. Avant de travailler sur cette carte, vous devez affirmer l'interface retournée avec le type map[string]interface{}. Pour convertir ce mappage en objet de ressource, vous pouvez utiliser l'API d'utilitaire util.ConvertMaptoStruct (voir : Ensemble d'utilitaire).
  • error - Contient une erreur si elle est retournée ou nulle.
Update
Met à jour l'immobilisation précisée dans le grand livre avec de nouvelles valeurs.
func Update(args ...interface{}) (interface{}, error)
Paramètres :
  • obj (interface) - L'objet à mettre à 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 étiquettes de structure dans la spécification du modèle, puis stockée dans le livre.
Retourne :
  • interface{} - La ressource enregistrée est retournée en tant qu'interface.
  • error - Contient une erreur si elle est retournée ou nulle.
Save
Enregistre l'immobilisation dans le livre après validation sur toutes les balises de structure.
func Save(args ...interface{}) (interface{}, error)
Paramètres :
  • obj/args[0] (interface{}) - L'objet à stocker dans le livre est transmis par référence dans cette méthode d'utilitaire.
  • metadata/args[1] (interface{}) - (Facultatif) Vous pouvez utiliser ce paramètre pour stocker les métadonnées dans le livre avec la ressource au moment de l'exécution.
Retourne :
  • interface {} - La ressource est retournée en tant qu'interface.
  • error - Contient une erreur si elle est retournée ou nulle.
Delete
Supprime l'immobilisation du grand livre.
func Delete(Id string) (interface{}, error)
Paramètres :
  • id (string) - ID de la ressource à supprimer du livre.
Retourne :
  • interface {} - Contient la ressource en cours de suppression dans le formulaire map[string]interface{}.
GetByRange
Retourne la liste des immobilisations spécifiées par un intervalle d'ID.
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
Paramètres :
  • startkey (string) - ID de début de l'intervalle d'objets à extraire.
  • endkey (string) - ID fin de l'intervalle d'objets à extraire.
  • asset interface - (Facultatif) Tableau vide des ressources, transmis par référence. Ce tableau contiendra le résultat de la méthode. Utilisez ce paramètre si un résultat spécifique au type est requis.
Retourne :
  • []map[string]interface{} - Ce tableau contient la liste des ressources obtenues à partir du livre. Vous pouvez accéder aux objets en itérant sur ce tableau et en les définissant comme map[string]interface{} et en utilisant un utilitaire pour les convertir en objet de ressource.
  • error - Contient une erreur si elle est retournée ou nulle.
GetByRangeWithPagination
La méthode GetByRangeWithPagination est une méthode statique de la classe OchainModel qui est héritée des classes Model concrètes de {chaincodeName}.model.ts.
Cette méthode retourne une liste de ressources entre l'intervalle startId et endId, filtrée par taille de page et signet. Cette méthode appelle la méthode Hyperledger Fabric GetStateByRangeWithPagination à l'interne.
Si le paramètre modelName n'est pas indiqué, la méthode retourne Promise<Object [ ] >. Si le paramètre modelName est fourni, la méthode traite la distribution dans le type Model de l'appelant. Dans l'exemple suivant, le tableau de résultats est de type Supplier. Si la ressource 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 l'intervalle 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ébut de l'intervalle, qui est incluse dans l'intervalle.
  • endkey : string – Clé de fin de l'intervalle, qui est exclue 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 des 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 ressources extraites du livre. Vous pouvez accéder aux objets en itérant sur ce tableau et en indiquant les objets comme map[string]interface{} et en utilisant un utilitaire de conversion en objet de ressource.
  • error – Contient une erreur si une erreur est retournée, sinon aucune.
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.
Retourne :
  • []interface{} - Cette tranche contient l'historique de la ressource obtenue à partir du livre sous forme de tranche de map[string]interface{}. Vous pouvez accéder à chaque élément d'historique en itérant sur cette tranche et en définissant les objets comme map[string]interface{} et en utilisant un utilitaire pour la conversion en objet de ressource.
  • error - Contient l'erreur si une erreur est retournée.
Query
Cette méthode exécute une interrogation SQL/Couch DB sur le grand livre. Cette méthode n'est prise en charge que pour les déploiements à 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) - Chaîne d'interrogation.
Retourne :
  • []interface{} - Sortie de l'interrogation sous la forme d'une tranche d'interfaces. Effectuez une itération sur la tranche et utilisez les éléments en les convertissant en types appropriés.
  • error - Contient l'erreur si une erreur est retournée.
QueryWithPagination
Cette méthode exécute 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 les déploiements à 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/base de données Couch enrichie.
  • pageSize : number - Taille de page de l'interrogation.
  • bookmark : string - Signet de l'interrogation. La sortie commence à partir de ce signet.
Retourne :
  • []interface{} - Sortie de l'interrogation sous la forme d'une tranche d'interfaces. Effectuez une itération sur la tranche et utilisez les éléments en les convertissant en types appropriés.
  • error - Contient l'erreur si une erreur est retourné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 où 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, en tant qu'objet JSON.
    • message - Message retourné par l'appel inter-code de chaîne, 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 où 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 de chaîne, 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 sera formée.
Retourne :
  • string - Résultat de la clé composite.
  • error - Contient l'erreur si une erreur est retournée.
GetByCompositeKey
Cette méthode retourne l'immobilisation correspondant à la clé et à la colonne spécifiées. 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 les méthodes 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) - Tranche d'attributs sur laquelle le livre sera interrogé à l'aide de la clé composite.
  • index(int) - Index de l'attribut.
Retourne :
  • Interface{} - Liste des ressources correspondantes.
  • error - Contient l'erreur si une erreur est retournée.

Méthode de talon

GetNetworkStub
Cette méthode retourne la valeur chaincodeStub Hyperledger Fabric.
Vous pouvez accéder au talon de cale en appelant la méthode GetNetworkStub. Cela peut vous aider à rédiger votre propre implémentation qui fonctionne directement avec les ressources.
func GetNetworkStub() shim.ChaincodeStubInterface
Paramètres :
  • aucune
Retourne :
  • shim.ChaincodeStubInterface - Le talon de code de chaîne Hyperledger Fabric.

Autres méthodes

  • GetTransactionId()
  • GetTransactionTimestamp()
  • GetChannelID()
  • GetCreator()
  • GetSignedProposal()
  • GetArgs()
  • GetStringArgs()
  • GetCreatorMspId()
  • GetId
GetTransactionId
Cette méthode 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 :
  • aucune
Retourne :
  • string - ID transaction.
GetTransactionTimestamp
Retourne l'horodatage de la création de la transaction. Comme la valeur provient de la transaction ChannelHeader, elle indique l'horodatage du client et a la même valeur pour tous les endossateurs.
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
Paramètres :
  • aucune
Retourne :
  • timestamp.Timestamp - Horodatage.
  • error - Contient l'erreur si une erreur est retournée.
GetChannelID
Retourne l'ID canal de la proposition pour le code de chaîne à traiter.
func GetChannelID() string
Paramètres :
  • aucune
Retourne :
  • string - ID canal demandé dans le format de chaîne.
GetCreator
Retourne l'objet d'identité de l'émetteur de l'appel de code de chaîne.
func GetCreator() ([]byte, error)
Paramètres :
  • aucune
Retourne :
  • []byte - Objet d'identité requis dans un format sérialisé.
  • error - Contient l'erreur si une erreur est retournée.
GetSignedProposal
Retourne un objet entièrement décodé de la proposition de transaction signée.
func GetSignedProposal() (*peer.SignedProposal, error)
Paramètres :
  • aucune
Retourne :
  • *peer.SignedProposal - Objet de proposition signé.
  • error - Contient l'erreur si une erreur est retournée.
GetArgs
Retourne les arguments en tant que tableau de chaînes de la demande d'appel de code de chaîne.
func GetArgs() [][]byte
Paramètres :
  • aucune
Retourne :
  • [][]byte - Arguments transmis.
GetStringArgs
Retourne les arguments destinés aux méthodes Init et Invoke du code de chaîne sous forme de tableau de chaînes.
func GetStringArgs() []string
Paramètres :
  • aucune
Retourne :
  • []string - Arguments sous forme de tableau de chaînes.
GetCreatorMspId
Retourne l'ID MSP de l'identité appelante.
func GetCreatorMspId() string
Paramètres :
  • aucune
Retourne :
  • string - 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 retourne 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 d'utilitaires

Les méthodes suivantes sont fournies dans le package de l'utilitaire.

Util.CreateModel
Analyse la chaîne JSON spécifiée et crée un objet de ressource du type spécifié.
func CreateModel(obj interface{}, inputString string) error
Paramètres :
  • inputString (string) - Chaîne JSON d'entrée à utiliser pour créer l'objet.
  • 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é conformément aux balises de validation.
Retourne :
  • error - Contient l'erreur si une erreur est retournée lors de la création ou de la validation de la ressource.
util.ConvertMapToStruct
Convertissez le mappage spécifié en un objet du type spécifié.
func ConvertMapToStruct(inputMap map[string](interface{}), resultStruct
interface{}) error
Paramètres :
  • inputMap (map[string](interface{})) - Mappage à convertir en objet de ressource.
  • resultStruct (interface{}) - Référence de l'objet de ressource à créer à partir du mappage.
Retourne :
  • error - Contient l'erreur si une erreur est retournée 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 des jetons à l'aide du générateur d'applications Blockchain.

Controller

Le fichier Controller.go met en oeuvre la CRUD et les méthodes personnalisées pour les ressources.

Vous pouvez créer n'importe quel nombre de classes, de fonctions ou de fichiers, mais seules les méthodes définies dans la structure de code de chaîne peuvent être appelées de l'extérieur; les autres sont masquées.

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 choisissez de générer toutes les méthodes, le résultat ressemblera au code suivant :

//	
//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 du fichier de spécification de l'exemple.

La fonction executeQuery montre comment appeler des interrogations enrichies SQL. Les valideurs 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 les fonctionnalités en fonction de la logique métier nécessaire. 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 la 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 : empty interface et error, comme indiqué dans l'exemple suivant :
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 Blockchain App Builder pour déployer ou mettre à niveau, la méthode Init est appelée automatiquement. Si vous déployez ou mettez à niveau à partir de la console Oracle Blockchain Platform, 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
}

Vous pouvez ensuite utiliser cette méthode pour initialiser n'importe quel état d'application.