Criar e Implantar o Contrato Inteligente
Para criar o contrato inteligente, precisamos definir as entidades a serem armazenadas e gerenciadas no Blockchain, conforme mostrado no modelo de entidade da imagem a seguir.
Descrição da ilustração oracle-blockchain-cms-entity.png
Todas essas entidades e suas relações, toda a lógica necessária para gerenciar e interagir com as entidades e também para persisti-las no razão blockchain é definida no contrato inteligente.
A pasta é representada como um token NFT, por isso será desenvolvida e inicializada como um NFT. As outras entidades dependentes (Documentos e Propriedades), são entidades padrão e são entidades filho da pasta, portanto, serão desenvolvidas como entidades padrão sem a necessidade de inicialização.
Uma vez que o contrato inteligente é criado, vamos instalá-lo e implantá-lo na Rede Blockchain que criamos.
Criar o Contrato Inteligente
Depois de configurar o Oracle Blockchain App Builder, você poderá criar o arquivo de especificação. O arquivo de especificação pode ser criado como um arquivo YAML simples mostrado no código a seguir.
Observação:
Você também pode fazer download desse arquivo em GitHub: Fazer download do arquivo YAML.#
# Token asset to manage the complete lifecycle of a non-fungible token representing a folder to hold docuements.
# This specification file will generate an Smartcontract project with a non-fungible token for the folders to be maintained by the users.
#
assets:
- name: folderNFT
type: token
symbol: eDocs
standard: erc721+
anatomy:
type: nonfungible
unit: whole
behavior:
- indivisible
- singleton
- mintable:
- transferable
- burnable
- roles:
minter_role_name: minter
properties:
- name: folderHASH
type: string
- name: documents
type: document[]
metadata:
- name: folderID
type: string
mandatory: true
id: true
- name: folderType
type: string
mandatory: true
methods:
crud: [create, getById, update, delete]
others: [getHistoryById, getByRange]
- name: document
properties:
- name: docName
type: string
mandatory: true
id: true
- name: docURL
type: string
mandatory: true
- name: docHASH
type: string
mandatory: true
- name: docType
type: string
mandatory: true
- name: docProperties
type: docProperty[]
methods:
crud: [create, getById, update, delete]
others: [getHistoryById, getByRange]
- name: docProperty
type: embedded
properties:
- name: propName
type: string
mandatory: true
- name: propValue
type: string
mandatory: true
methods:
crud: [create, getById, update, delete]
others: [getHistoryById, getByRange]
customMethods:
- executeQuery
- "attachDocument(tokenId: string, docName: string, docURL: string, docHASH: string, docType: string, docProps: string[], docVals: string[])" # Attach a document to an existing folder.
- "retrieveDocuments(tokenId: string)" # Retrieve Documents of an folder.
- "transferFolder(tokenId: string, fromOrgId: string, fromUserId: string, toOrgId: string, toUserId: string)" # Transfer the folder among participants.
- "updateFolderHASH(tokenId: string, newHash: string)" # Update HASH folder
- "getFolderHASH(tokenId: string)" # Check HASH folder
Neste arquivo de especificação, na primeira entidade definida (folderNFT), você pode ver todas as seções e atributos para a representação de um token NFT. Visão geral das seções definidas no arquivo:
- Ativos: Coloque onde os diferentes ativos (entidades padrão, transações financeiras, NFTs) são definidos. Dentro de cada um dos ativos, podemos distinguir diferentes seções que podem variar dependendo do tipo de ativo representado. Para NFTs e FTs, estas são as diferentes subseções:
- Tipo/Símbolo/Padrão: Especifique se esse token se baseia no Padrão ERC-721 e dê a ele um indentificador de símbolo exclusivo.
- Anatomia: Especifique se é um NFT e se está subdividido em frações menores (hoje, "todo" é a única opção para tokens NFT).
- Comportamento: Define se o token pode ser cunhado e, nesse caso, qual é o número máximo de tokens minimizáveis. Aqui você também deve declarar que é um token indivisível, se é singleton para cada classe, transferível e queimável que é semelhante à sua exclusão (mas não desaparecendo, então ainda está lá, mas não utilizável). Também nesta seção, você pode restringir o comportamento do token a funções específicas.
- Metadados: Define uma espécie de propriedades que devem ser definidas durante a criação do token e não podem ser alteradas no futuro. Assim, seu valor permanecerá imutável por toda a vida do token.
- Propriedades: Define atributos padrão do token que podem variar durante a vida útil do token, como o array de documentos que compõem a pasta.
- customMethods: Local no qual a lista de nossos métodos personalizados deve ser definida. Para esses métodos, o Oracle Blockchain App Builder só gerará a assinatura do método, sem qualquer implementação neles. A implementação desses métodos é o único código que pode ser implementado pelo desenvolvedor.
Os links a seguir descrevem como configurar qualquer tipo de entidade (NFT, FT ou entidades padrão) com base em suas necessidades de negócios:
- Entidade padrão, consulte Como criar um Arquivo de Especificação de Entrada.
- Entidade representada como um NFT. Consulte Arquivo de Especificação de Entrada para Tokens Não Fungíveis.
- Entidade representada como uma transação financeira. Consulte Arquivo de Especificação de Entrada para Tokens Fungíveis.
Depois que o arquivo de especificação tiver sido criado, poderemos exigir que o Oracle Blockchain App Builder crie o andaime do projeto seguindo estas próximas etapas.
oracle-blockchain-nft-token-oracle.zip
Neste ponto, o chaincode está pronto para ser usado, para que possamos implantar e testar o chaincode localmente seguindo as instruções de Testar Seu Chaincode em uma Rede Local do Hyperledger Fabric.
Implantar o Contrato Inteligente
Depois de testarmos localmente o chaincode, prossiga para implantá-lo na rede real criada anteriormente usando a Console do Oracle Blockchain Service:
- Empacotando o projeto do chaincode.
- Instalando e Implantando o pacote chaincode na instância única (fundador).
- Crie o pacote implantável a partir do projeto chaincode. No Visual Studio, clique no botão direito na parte superior do nome do projeto do chaincode. No menu pop-up, selecione a opção Pacote e selecione o diretório para salvar o arquivo do pacote chaincode.
- Acesse a Console do Oracle Blockchain Service para instalar e implantar o pacote de chaincode na instância do fundador.
- Navegue até a guia Código de Cadeia e clique em Implantar um Novo Código de Cadeia.
- Selecione a opção Implantação Avançada.
- Defina todos os valores para instalar o pacote de chaincode na instância do fundador e clique em Próximo.
- Rótulo do Pacote: Forneça um nome que possa ajudá-lo a identificar qual pacote está instalado nos diferentes canais existentes. Como você pode ter mais de uma versão do mesmo contrato inteligente implantada em diferentes canais, é uma boa prática definir um nome de rótulo de pacote como:
<smartContractName>_<channel>_<version>
- Idioma do Código de Cadeia: selecione entre os diferentes idiomas, com base no idioma em que você desenvolveu o código de cadeia.
- Pares de Destino: Selecione os pares nos quais você deseja instalar o pacote de chaincode.
- Chaincode Empacotado: Deixe esta caixa de seleção desmarcada se você estiver fazendo upload de um arquivo zip. Marque a caixa de seleção para arquivos
tar.gz
. - Origem do Código de Cadeia: Clique em Fazer Upload do Arquivo de Código de Cadeia e selecione o arquivo zip do código de cadeia.
- Rótulo do Pacote: Forneça um nome que possa ajudá-lo a identificar qual pacote está instalado nos diferentes canais existentes. Como você pode ter mais de uma versão do mesmo contrato inteligente implantada em diferentes canais, é uma boa prática definir um nome de rótulo de pacote como:
- Se a instalação for bem-sucedida, veremos a mensagem de sucesso. A próxima etapa é a implantação do chaincode no canal selecionado; portanto, você deve definir todos os valores relacionados à fase de implantação e clicar em Próximo.
- Canal: Selecione o canal no qual você deseja implantar o contrato inteligente.
- Nome do Código de Cadeia: Defina o nome com o qual o contrato inteligente será implantado no canal.
- Versão: Atribua um número a esta implantação, que está alinhada com o pacote instalado anteriormente. Dessa forma, você poderá correlacionar pacotes instalados com chaincodes implantados em diferentes canais.
- Init-required: Marque essa caixa de seleção se o método
init
do chaincode precisar ser chamado antes de permitir transações do usuário. - Política de Endosso: Especifique políticas de endosso durante a implantação. Neste exemplo do manual de soluções, não estamos usando políticas de endosso.
- Coleta de Dados Privados: Defina Coletas de Dados Privados, se necessário. Neste exemplo de manual de soluções, não definiremos a coleta de dados privada.
Inicializar o Contrato Inteligente
Quando você está lidando com FTs e tokens NFT, há um conjunto de ações administrativas a serem executadas antes de poder executar seus métodos de negócios. Com o Oracle Blockchain, todas as tarefas administrativas podem ser executadas como chamadas REST simples e reduz consideravelmente o esforço necessário para inicializar o contrato inteligente.
Observação:
Antes de executar qualquer uma das etapas a seguir, devemos criar o enrollmentIDs nos Proxies REST para os usuários que receberam acesso aos métodos de contrato inteligente. A inscrição é um mapeamento entre o nome de usuário que chama a API REST e as contas gerenciadas internamente pelo blockchain às quais os tokens serão atribuídos, conforme descrito no tópico Criar inscrições nos nós Proxy REST.Use a seguinte coleção Postman para inicializar facilmente o contrato inteligente: Fazer Download da coleção Postman
Na pasta AdminSteps desta coleção Postman, há três chamadas de solicitação a serem executadas para a inicialização do contrato inteligente.
A coleção Postman está pronta para ser usada, mas há um conjunto de variáveis que precisam ser configuradas adequadamente para seu próprio ambiente (senhas, URLs e assim por diante). Essas variáveis são definidas na guia Variáveis da coleção Postman. A tabela a seguir mostra todas as variáveis que definimos e que precisam ser adaptadas ao seu ambiente.
Nome da Variável | Valor da variável |
---|---|
bc_founder_provider_url | https://org1-w.... |
bc_timeout | 60,000 |
bc_nft_founder_userid1 | cmsleg001 |
bc_nft_founder_userid1_pwd | senha |
bc_nft_founder_userid2 | cmsfin001 |
bc_nft_founder_userid2_pwd | senha |
bc_nft_founder_userid3 | cmsrsk001 |
bc_nft_founder_userid4_pwd | senha |
bc_channel_name | wedocms |
bc_chaincode_name | CUNHA |
Localize o ponto final no qual a API REST está acessível na Console do Serviço Blockchain.
- Inicialização de contrato inteligente (Contas de Usuário do Administrador de Entrada).
- Criação de carteiras para usuários que podem possuir os tokens NFT.
- Designe a atribuição de minter aos usuários que devem ter esse privilégio.
AdminSteps
da coleção Postman fornecida.
- Inicialize o chaincode (Etapa-0: Iniciar Conta de Usuário Admin) indicando quais contas de usuário terão permissão para executar tarefas administrativas. É importante definir os argumentos do método
init
corretamente:args: Scaped array of user_ids with their org_ids
.{ "chaincode": "{{bc_nft_chaincode_name}}", "args": [ "init", "[{\"orgId\":\"org1\",\"userId\":\"cmsleg001\"},{\"orgId\":\"org1\",\"userId\":\"cmsfin001\"},{\"orgId\":\"org1\",\"userId\":\"cmsrsk001\"}]" ], "timeout": {{bc_timeout}}, "isInit": true, "sync": true }
- Crie contas de usuário para todos os usuários que podem ser depositários dos ativos NFT que representam os ativos físicos. Isso pode ser feito executando a solicitação Postman da Etapa 1: Criar conta. Para as especificidades do nosso caso de uso, existem apenas três usuários relacionados com a mesma organização única pertencente à rede. Essa chamada deve ser executada tantas vezes quanto os usuários para os quais queremos criar uma conta. No nosso caso três vezes, cada um com os seguintes parâmetros:
"createAccount", "org1", "cmsleg001", "nonfungible"
"createAccount", "org1", "cmsfin001", "nonfungible"
"createAccount", "org1", "cmsrsk001", "nonfungible"
{ "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name "args": [ "createAccount", "org1","cmsleg001","nonfungible" //Method, OrgID, UserID, fungible for FT / nonfungible for NFT ], "timeout": 60000, "sync": true }
- Defina qual usuário tem permissão para cunhar tokens. Nesse caso, cunhar um token significa criar uma nova pasta para conter um novo conjunto de documentos, para que você possa decidir qual dos três usuários existentes (cmsleg001, cmsfin001 ou cmsrsk001) pode executar essas ações e, para esses usuários, execute a solicitação Etapa 2: AddRole da coleção Postman.
{ "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name "args": [ "addRole", //Method name "minter","org1","cmsleg001" //Role, OrgId, UserID ], "timeout": 60000, "sync": true }