O Blockchain App Builder pega a entrada do seu arquivo de especificação e gera um projeto de chaincode andaime totalmente funcional. O projeto contém classes e funções geradas automaticamente, métodos CRUD, métodos SDK, validação automática de argumentos, marshalling/un-marshalling e capacidade de persistência transparente (ORM).
Se o projeto chaincode estiver no idioma Go, o projeto scaffolded contém três arquivos principais:
main.go
<chaincodeName>.model.go
<chaincodeName>.controller.go
Todas as bibliotecas necessárias são instaladas e empacotadas.
O arquivo <chaincodeName>.model.go no subdiretório model contém várias definições de ativos e o arquivo <chaincodeName>.controller.go no subdiretório controller contém o comportamento do ativo e os métodos CRUD. As várias tags e pacotes de estruturas Go em model.go e controller.go fornecem suporte para recursos como validação automática de argumentos, marshalling/unmarshalling de argumentos, recurso de persistência transparente (ORM) e chamada de consultas avançadas.
O projeto scaffolded pode ser encontrado em $GOPATH/src/example.com/<chaincodeName>
Modelo
Propriedade do Tipo de Ativo
Por padrão, cada estrutura terá uma propriedade adicional chamada
AssetType. Essa propriedade pode ser útil para extrair somente ativos desse tipo. Todas as alterações nesta propriedade são ignoradas durante a criação e atualização do ativo. O valor da propriedade por padrão é
<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"'
}
Validadores
-
ID
id:"true"
- Este validador identifica a propriedade que define exclusivamente o ativo subjacente. O ativo é salvo pelo valor nesta chave. Esse validador se aplica automaticamente quando um novo projeto Go é submetido a andaimes.
- Na captura de tela abaixo,
"SupplierId" é a chave do ativo do fornecedor e tem uma propriedade de tag id:"true" para a propriedade 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"'
}
-
Derivado
derived:"strategy,algorithm,format"
- Este decorador é usado para definir o atributo derivado de outras propriedades. Este decorador tem dois parâmetros obrigatórios:
strategy: obtém valores de concat ou hash. Requer um parâmetro adicional algorithm se hash estiver selecionado. O algoritmo padrão é sha256; md5 também é suportado.
format: usa um array de strings e valores de especificação para serem usados pela estratégia.
-
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"'
}
-
Obrigatória
validate:"mandatory"
- Isso marca a propriedade a seguir como obrigatória e não pode ser ignorada ao salvar no razão. Se ignorado, ele gerará um erro. No exemplo abaixo,
"SupplierId" tem uma tag validate:"mandatory".Type Supplier struct {
Supplierld string 'json:"Supplierld" validate:"string,mandatory" id:"true"'
RawMaterialAvailable int 'json:"RawMaterialAvailable" validate:"int,min=0"'
License string 'json:"License" validate:"string,min=10"'
ExpiryDate date.Date 'json:"ExpiryDate" validate:"date,before=2020-06-26"'
Active bool 'json:"Active" validate:"bool" default :"true"'
Metadata interface{} 'json:"Metadata,omitempty"'
}
-
Padrão
default:"<param>"
- Isso indica que a propriedade a seguir pode ter um valor padrão. O valor padrão na etiqueta padrão é usado quando a propriedade é ignorada ao salvar no razão. Na propriedade de exemplo abaixo,
Active tem um valor padrão de true, fornecido como tag 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"'
}
-
Validar tipos
- Os tipos básicos de Go são validados para uma propriedade definindo uma tag de validação. Estas são as tags de validação baseadas em tipos:
- string:
validate: "string"
- data:
validate: "date"
- número:
validate: "int"
- booliano:
validate: "bool"
-
Validador mínimo
validate:"min=<param>"
- Usando o validador min, o valor mínimo pode ser definido para uma propriedade do tipo número e string.
- Para o tipo int: No exemplo, a propriedade
RawMaterialAvailable tem um valor mínimo de 0 e, se um valor menor que 0 for aplicado a RawMaterialAvailable, um erro será retornado.
- Para tipo de string: Para o tipo de string, o validador mínimo verificará o tamanho da string com o valor fornecido. Portanto, no exemplo abaixo, a propriedade
License deve ter no mínimo 10 caracteres.
- Exemplo:
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"'
}
-
Validador máximo
validate:"max=<param>"
- Usando o validador máximo, o valor máximo pode ser definido para uma propriedade do tipo número e string.
- Para o tipo int: Como o validador min, para o tipo int, se um valor fornecido para o
structfield for maior que o valor fornecido no validador, um erro será retornado.
- Para a string de tipo: Como o validador mínimo, o validador máximo também verificará o tamanho da string com determinado valor. No exemplo, a propriedade
Domain tem um valor máximo de 50, portanto, se a propriedade Domain tiver uma string com mais de 50 caracteres, uma mensagem de erro será retornada.
-
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"'
}
-
Validadores de data
- Antes do validador:
validate:"before=<param>"
- O validador anterior valida uma propriedade do tipo
date para ter um valor menor que o especificado no parâmetro.
- Neste exemplo, a propriedade
ExpiryDate deve ser anterior a "2020-06-26" e, se não for, retornará um erro.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"'
}
- Após o validador:
validate:"after=<param>"
- O validador anterior valida uma propriedade do tipo
date para ter um valor maior que o especificado no parâmetro.
- Neste exemplo, a propriedade
CompletionDate deve ser posterior a "2020-06-26" e, se não for, retornará um erro.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"'
}
-
Validador de URL
validate:"url"
- O validador de URL validará uma propriedade para strings de URL.
- Neste exemplo, a propriedade
Domain deve ser um URL válido.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"'
}
-
Validador Regexp
validate:"regexp=<param>"
- O validador Regexp validará a propriedade para a expressão regular de entrada.
- Neste exemplo, a propriedade
PhoneNumber será validada para um número de celular de acordo com a expressão regular.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"'
}
-
Vários validadores
- Vários validadores podem ser aplicados a uma propriedade.
- Neste exemplo, a propriedade
Domain tem validação para uma string, URL e tamanho mínimo e máximo da string.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
O Recurso de Persistência Transparente ou ORM simplificado é capturado na classe Model do objeto de Contexto (Ctx). Se seu modelo chamar qualquer um dos métodos SDK a seguir, acesse-os usando t.Ctx.Model.
Os métodos SDK que implementam o ORM são os seguintes:
Save – isso chama o método Hyperledger Fabric PutState
Get – isso chama o método Hyperledger Fabric GetState
Update – isso chama o método Hyperledger Fabric PutState
Delete – isso chama o método Hyperledger Fabric DeleteState
History – isso chama o método Hyperledger Fabric GetHistoryForKey
GetByRange – isso chama o método Hyperledger Fabric GetStateByRange
GetByRangeWithPagination – isso chama o método Hyperledger Fabric GetStateByRangeWithPagination
Métodos SDK
Go chaincodes implementar Transparent Persistence Capability (ORM) com o pacote de modelos.
Observação:
A partir da versão 21.2.3, a maneira de acessar os métodos ORM mudou. Execute o comando
ochain --version para determinar a versão do Blockchain App Builder.
Em releases anteriores, os métodos ORM foram expostos como métodos estáticos no pacote de modelos. Os métodos agora são definidos no receptor de modelo, que contém o canhoto da transação. Para chamar esses métodos, você usa o modelo receptor mantido pelo contexto da transação no controlador. Você chama esses métodos como t.Ctx.Model.<method_name> em vez de model.<method_name>.
O exemplo a seguir mostra as chamadas de método Save e Get nas versões anteriores:
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
}
O exemplo a seguir mostra as chamadas de método Save e Get da versão 21.2.3 e posterior:
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
}
Depois de fazer upgrade para a versão 21.2.3, faça essa alteração em todos os projetos de chaincode que você criou com uma versão anterior do Blockchain App Builder. Se você usar o comando sync para sincronizar alterações entre o arquivo de especificação e o código-fonte, as alterações serão trazidas automaticamente ao controlador para os métodos prontos para uso. Você ainda precisa resolver manualmente quaisquer conflitos.
Os seguintes métodos ORM são expostos por meio do pacote de modelos:
-
Get
- Consulta o razão para o ativo armazenado com base no ID fornecido.
-
func Get(Id string, result ...interface{}) (interface{}, error)
- Parâmetros:
Id - O ID do ativo que é obrigatório no razão.
result (interface{}) - Este é um objeto de ativo vazio de um tipo específico, que é passado por referência. Este objeto conterá o resultado deste método. Para ser usado somente se o resultado específico do tipo for obrigatório.
asset (interface) - Objeto de ativo vazio, que é passado por referência. Este objeto conterá o resultado deste método. Para ser usado somente se o resultado específico do tipo for obrigatório.
- Retorna:
interface {} - A interface contém o ativo na forma de map[string]interface{}. Antes de operar neste mapa, é necessário afirmar a interface obtida com o tipo map[string]interface{}. Para converter esse mapa em um objeto de ativo, você pode usar a API do utilitário util.ConvertMaptoStruct (consulte: Pacote do Utilitário).
error - Contém um erro se for retornado ou for nulo.
-
Update
- Atualiza o ativo fornecido no razão com os novos valores.
-
func Update(args ...interface{}) (interface{}, error)
- Parâmetros:
obj (interface) - O objeto que deve ser atualizado no razão é informado por referência nesta API com os novos valores. O ativo de entrada é validado e verificado de acordo com as tags de estrutura mencionadas na especificação do modelo e, em seguida, armazenado no razão.
- Retorna:
interface{} - O ativo salvo é retornado como uma interface.
error - Contém um erro se for retornado ou for nulo.
-
Save
- Salva o ativo no razão após a validação em todas as tags de estrutura.
-
func Save(args ...interface{}) (interface{}, error)
- Parâmetros:
obj/args[0] (interface{}) - O objeto que precisa ser armazenado no razão é passado por referência neste método de utilitário.
metadata/args[1] (interface{}) - Este parâmetro é opcional. Ele foi fornecido para facilitar se você precisar armazenar quaisquer metadados no razão junto com o ativo no runtime. Este parâmetro poderá ser ignorado se não existir tal requisito.
- Retorna:
interface {} - O ativo é retornado como uma interface.
error - Contém um erro se for retornado ou for nulo.
-
Delete
- Exclui o ativo do razão.
-
func Delete(Id string) (interface{}, error)
- Parâmetros:
id (string) - O ID do ativo que deve ser excluído do razão.
- Retorna:
interface {} - Contém o ativo que está sendo excluído no formato map[string]interface{}.
-
GetByRange
- Retorna a lista de ativos por intervalo de IDs.
-
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
- Parâmetros:
startkey (string) - ID Inicial para o intervalo de objetos que são obrigatórios.
endkey (string) - Fim do intervalo de objetos que são obrigatórios.
asset interface - (opcional) Array vazio de ativos, que é passado por referência. Essa matriz conterá o resultado desse método. A ser usado se o resultado específico do tipo for obrigatório.
- Retorna:
[]map[string]interface{} - Esse array contém a lista de ativos obtidos do razão. Você pode acessar os objetos iterando por esse array e afirmando os objetos como map[string]interface{} e usando o utilitário para converter em objeto de ativo.
error - Contém um erro se for retornado ou for nulo.
-
GetByRangeWithPagination
- O método
GetByRangeWithPagination é um método estático da classe OchainModel que é herdado pelas classes Model concretas de {chaincodeName}.model.ts.
- Isso retorna uma lista de ativos entre o intervalo
startId e endId, filtrados por tamanho de página e marcador. Esse método chama o método GetStateByRangeWithPagination do Hyperledger Fabric internamente.
- Se o parâmetro
modelName não for fornecido, o método retornará Promise<Object [ ] >. Se o parâmetro modelName for fornecido, o método tratará a conversão no tipo Model do chamador. No exemplo a seguir, o array de resultados é do tipo Supplier. Se o ativo retornado do razão não for do tipo Model, ele não será incluído na lista. Essa verificação é feita pela propriedade assetType somente para leitura na classe Model.
- Para retornar todos os ativos entre a faixa
startId e endId, filtrados por tamanho de página e marcadores, use o método do controlador genérico getAssetsByRange.
-
func (m *Model) GetByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string, asset ...interface{}) ([]map[string]interface{}, error)
- Parâmetros:
startkey : string – Chave inicial do intervalo. Incluído no intervalo.
endkey : string – Chave final da faixa. Excluído do intervalo.
pageSize : number – O tamanho da página da consulta.
Bookmark : string – O marcador da consulta. Esta saída começa neste marcador.
asset interface – (Opcional) Um array vazio de ativos, transmitido por referência. Essa matriz conterá o resultado desse método. Use esse parâmetro para obter resultados específicos do tipo.
- Retorna:
[]map[string]interface{} – Um array que contém a lista de ativos recuperados do razão. Você pode acessar os objetos iterando sobre esse array e afirmando os objetos como map[string]interface{} e usando um utilitário para conversão em um objeto de ativo.
error – Contém um erro se um erro for retornado, caso contrário, nulo.
-
GetHistoryById
- Retorna o histórico do ativo com o ID fornecido.
-
func GetHistoryByID(Id string) ([]interface{}, error)
- Parâmetros:
Id (string) - ID do ativo para o qual o histórico é necessário.
- Retorna:
[]interface{} - Esta fatia contém o histórico do ativo obtido do razão na forma de fatia de map[string]interface{}. Você pode acessar cada elemento de histórico iterando sobre esse segmento e afirmando os objetos como map[string]interface{} e usando o utilitário para converter em objeto de ativo.
error - Contém o erro se observado.
-
Query
- O método de consulta executará uma consulta SQL/Couch DB no razão. Esse método só é suportado para implantação remota no Oracle Blockchain Platform. Este é um método genérico para executar consultas SQL no razão.
-
func Query(queryString string) ([]interface{}, error)
- Parâmetros:
queryString (string) - Informe a string de consulta.
- Retorna:
[]interface{} - Isso conterá a saída da consulta. O resultado é na forma de um segmento de interfaces. É necessário iterar no intervalo e utilizar os elementos, convertendo-os em tipos apropriados.
error - Contém o erro se observado.
-
QueryWithPagination
- O método de consulta executará uma consulta SQL/Couch DB no razão, filtrada por tamanho de página e marcador. Esse método só é suportado para implantação remota no Oracle Blockchain Platform. Este é um método genérico para executar consultas SQL no razão.
-
func (m *Model) QueryWithPagination(queryString string, pageSize int32, bookmark string) ([]interface{}, error)
- Parâmetros:
queryString (string) - Consulta Rich SQL/Couch DB.
pageSize : number - O tamanho da página da consulta.
bookmark : string - O marcador da consulta. Esta saída começa neste marcador.
- Retorna:
[]interface{} - Isso conterá a saída da consulta. O resultado é na forma de um segmento de interfaces. É necessário iterar no intervalo e utilizar os elementos, convertendo-os em tipos apropriados.
error - Contém o erro se observado.
-
InvokeCrossChaincode
- Você pode usar esse método em um chaincode para chamar uma função em outro chaincode. Ambos os chaincodes devem ser instalados no mesmo par.
-
func InvokeCrossChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
- Parâmetros:
chaincodeName – O nome do chaincode a ser chamado.
methodName - O nome do método a ser chamado no chaincode.
arg - O argumento do método de chamada.
channelName - O canal onde o chaincode a ser chamado está localizado.
- Retorna:
interface{} - Retorna um objeto map[string]interface{} que contém três chaves:
isValid - true se a chamada for válida.
payload - A saída retornada pela chamada cross-chaincode, como um objeto JSON.
message - A mensagem retornada pela chamada de código de cadeia cruzada, no formato UTF-8.
- Exemplo de Valor de Retorno:
{
"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
- Você pode usar esse método em um chaincode para chamar uma função em outro chaincode. Ambos os chaincodes devem ser instalados no mesmo par.
-
func InvokeChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
- Parâmetros:
chaincodeName – O nome do chaincode a ser chamado.
methodName - O nome do método a ser chamado no chaincode.
arg - O argumento do método de chamada.
channelName - O canal onde o chaincode a ser chamado está localizado.
- Retorna:
interface{} - Retorna um objeto map[string]interface{} que contém três chaves:
isValid - true se a chamada for válida.
payload - A saída retornada pela chamada de código de cadeia cruzada, no formato UTF-8.
message - A mensagem retornada pela chamada de código de cadeia cruzada, no formato UTF-8.
- Exemplo de Valor de Retorno:
{
"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étodos de Chave Composta
-
GenerateCompositeKey
- Esse método gera e retorna a chave composta com base no
indexName e nos atributos fornecidos nos argumentos.
func GenerateCompositeKey(indexName string, attributes []string)
(string, error)
- Parâmetros:
indexName (string) - Tipo de objeto da chave composta.
attrbutes ([]string) - Atributos do ativo com base no qual a chave composta deve ser formada.
- Retorna:
string - Contém o resultado da chave composta.
error - Contém o erro se observado.
-
GetByCompositeKey
- Este método retorna o ativo que corresponde à chave e à coluna fornecidas nos parâmetros. O parâmetro
index indica o índice da chave retornada no array do método stub SplitCompositeKey.
- Internamente, esse método chama os
getStateByPartialCompositeKey, splitCompositeKey e getState do Hyperledger Fabric.
func GetByCompositeKey(key string, columns []string, index int)
(interface{}, error)
- Parâmetros:
key (string) - Tipo de objeto fornecido ao criar a chave composta.
column ([]string) - Esta é a fatia de atributos na qual o razão deve ser consultado usando a chave composta.
index(int) - Índice do atributo.
- Retorna:
Interface{} - Contém a lista de ativos que são resultado desse método.
error - Contém erros, se houver.
Método Stub
-
GetNetworkStub
- Esse método retornará o Hyperledger Fabric
chaincodeStub.
- Você pode obter acesso ao stub do shim chamando o método
GetNetworkStub. Isso ajudará você a criar sua própria implementação trabalhando diretamente com os ativos.
func GetNetworkStub() shim.ChaincodeStubInterface
- Parâmetros:
- Retorna:
shim.ChaincodeStubInterface - Este é o stub de chaincode do Hyperledger Fabric.
Outros métodos
GetTransactionId()
GetTransactionTimestamp()
GetChannelID()
GetCreator()
GetSignedProposal()
GetArgs()
GetStringArgs()
GetCreatorMspId()
GetId
-
GetTransactionId
- Retorna o ID da transação para a solicitação de chamada de chaincode atual. O ID da transação identifica exclusivamente a transação dentro do escopo do canal.
func GetTransactionId() string
- Parâmetros:
- Retorna:
string - Contém o ID da transação obrigatório.
-
GetTransactionTimestamp
- Retorna o timestamp quando a transação foi criada. Isso é retirado da transação
ChannelHeader, portanto, indicará o timestamp do cliente e terá o mesmo valor em todos os endossadores.
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
- Parâmetros:
- Retorna:
timestamp.Timestamp - Contém o timestamp obrigatório.
error - Contém erros, se houver.
-
GetChannelID
- Retorna o ID do canal da proposta para o chaincode a ser processado.
func GetChannelID() string
- Parâmetros:
- Retorna:
string - Contém o ID do canal obrigatório como uma string.
-
GetCreator
- Retorna o objeto de identidade do remetente da chamada de chaincode
func GetCreator() ([]byte, error)
- Parâmetros:
- Retorna:
[]byte - Contém o objeto de identidade necessário serializado.
error - Contém erros, se houver.
-
GetSignedProposal
- Retorna um objeto totalmente decodificado da proposta de transação assinada.
func GetSignedProposal() (*peer.SignedProposal, error)
- Parâmetros:
- Retorna:
*peer.SignedProposal - Contém o objeto de proposta assinado obrigatório.
error - Contém erros, se houver.
-
GetArgs
- Retorna os argumentos como array de strings da solicitação de chamada de chaincode.
func GetArgs() [][]byte
- Parâmetros:
- Retorna:
[][]byte - Contém os argumentos passados.
-
GetStringArgs
- Retorna os argumentos destinados ao chaincode Init e Invoke como um array de string.
func GetStringArgs() []string
- Parâmetros:
- Retorna:
[]string - Contém os argumentos obrigatórios como um array de string.
-
GetCreatorMspId
- Retorna o ID do MSP da identidade de chamada.
-
func GetCreatorMspId() string
- Parâmetros:
- Retorna:
string - Retorna o ID do MSP da identidade de chamada.
-
GetId
- Quando o ativo tiver uma chave derivada como
Id, você poderá usar esse método para obter um ID derivado. Este método retornará um erro se a chave derivada contiver %t (timestamp).
- Parâmetros:
object - O objeto deve conter todas as propriedades das quais a chave derivada é dependente.
- Retorna:
- Retorna a chave derivada como uma string.
- Exemplo:
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)
}
Pacote de Utilitários
Os seguintes métodos no pacote de utilitários podem ser úteis:
-
Util.CreateModel
- Analisa a string JSON fornecida e cria um objeto de ativo do tipo fornecido.
func CreateModel(obj interface{}, inputString string) error
- Parâmetros:
inputString (string) - A string JSON de entrada da qual o objeto deve ser criado.
obj (interface{}) - A referência do objeto a ser criado com base na string JSON. Este objeto armazenará o modelo criado que também é validado de acordo com as tags do validador.
- Retorna:
error - Contém quaisquer erros encontrados durante a criação ou validação do ativo.
-
util.ConvertMapToStruct
- Converta o mapa fornecido em objeto do tipo fornecido.
func ConvertMapToStruct(inputMap map[string](interface{}), resultStruct
interface{}) error
- Parâmetros:
inputMap (map[string](interface{})) - Mapa que precisa ser convertido no objeto do ativo.
resultStruct (interface{}) - A referência do objeto de ativo necessário que precisa ser gerado no mapa. Contém o objeto de ativo de resultado necessário.
- Retorna:
error - Contém quaisquer erros encontrados durante a criação ou validação do ativo.
Para métodos de token SDK, consulte os tópicos em Suporte à Tokenização Usando o Blockchain App Builder.
Controladora
O arquivo Controller.go implementa o CRUD e os métodos personalizados para os ativos.
Você pode criar qualquer número de classes, funções ou arquivos, mas apenas os métodos que são definidos na estrutura de chaincode são invocáveis de fora, o resto deles estão ocultos.
Métodos Gerados Automaticamente
Conforme descrito em Arquivo de Especificação de Entrada, você pode especificar quais métodos CRUD deseja gerar no arquivo de especificação. Por exemplo, se você optou por gerar todos os métodos, o resultado seria semelhante a:
//
//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étodos personalizados
Os métodos personalizados a seguir foram gerados do nosso arquivo de especificação de exemplo.
O executeQuery mostra como as consultas rich SQL podem ser chamadas. Os validadores contra os argumentos são adicionados automaticamente pelo Blockchain App Builder com base no tipo do argumento especificado no arquivo de especificação.
É possível implementar a funcionalidade de acordo com a lógica de negócio. Se você adicionar métodos personalizados, adicione-os ao arquivo do controlador. Se você adicionar métodos personalizados à biblioteca em vez do arquivo controlador, suas alterações serão perdidas quando o conteúdo da pasta da biblioteca for atualizado durante os processos de sincronização ou atualização de chaincode.
//
//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
}
Para chaincodes Go, cada método personalizado deve retornar dois valores:
interface vazia,
erro. Por exemplo:
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) {
return nil, nil
}
Método Init
Um método Init personalizado é fornecido no controlador com uma definição vazia. Se você usar o Blockchain App Builder para implantar ou fazer upgrade, o método Init será chamado automaticamente. Se você implantar ou fazer upgrade da console do Oracle Blockchain Platform, deverá chamar o método Init manualmente. Você pode usar uma ferramenta de terceiros, como Postman, para chamar o método Init manualmente.
type Controller struct {
}
func (t *Controller) Init(args string) (interface{}, error)
{ return nil, nil
}
Você pode usar esse método para inicializar qualquer estado do aplicativo neste momento.