Creazione e distribuzione del contratto smart

Per creare lo smart contract, è necessario definire le entità da memorizzare e gestire in Blockchain come mostrato nel modello di entità della seguente immagine.


Descrizione di oracle-blockchain-cms-entity.png
Descrizione dell'immagine oracle-blockchain-cms-entity.png

Tutte queste entità e le relative relazioni, tutta la logica necessaria per gestire e interagire con le entità e anche per renderle persistenti nel libro contabile della blockchain è definita nello smart contract.

La cartella è rappresentata come token NFT, quindi verrà sviluppata e inizializzata come NFT. Le altre entità dipendenti (Documenti e Proprietà), sono entità standard e sono entità figlio della cartella, quindi verranno sviluppate come entità standard senza la necessità di inizializzazione.

Una volta creato lo smart contract, lo installeremo e lo implementeremo nella Blockchain Network che abbiamo creato.

Creazione del contratto smart

Dopo aver configurato Oracle Blockchain App Builder, è possibile creare il file di specifica. Il file di specifica può essere creato come un semplice file YAML mostrato nel codice seguente.

Nota

È anche possibile scaricare questo file da GitHub: scaricare il file 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 

In questo file di specifica, nella prima entità definita (folderNFT) è possibile visualizzare tutte le sezioni e gli attributi per la rappresentazione di un token NFT. Panoramica delle sezioni definite nel file:

  • Asset: luogo in cui sono definiti i diversi asset (entità standard, FT, NFT). All'interno di ogni asset possiamo distinguere diverse sezioni che possono variare a seconda del tipo di asset rappresentato. Per NFT e FT, queste sono le diverse sottosezioni:
    • Tipo/Simbolo/Standard: specificare che questo token è basato sullo standard ERC-721 e assegnargli un identificativo simbolo univoco.
    • Anatomia: specificare se si tratta di un NFT e se è suddiviso in frazioni più piccole (oggi "intero" è l'unica opzione per i token NFT).
    • Comportamento: definisce se il token può essere coniato e, in tal caso, qual è il numero massimo di token utilizzabili. Qui devi anche dire che è un token indivisibile, se è singleton per ogni classe, trasferibile e bruciabile che è simile alla sua cancellazione (ma non scompare, quindi è ancora lì ma non utilizzabile affatto). Anche in questa sezione è possibile limitare il comportamento dei token a ruoli specifici.
    • Metadati: definisce un tipo di proprietà che deve essere impostato durante la creazione del token e che non può essere modificato in futuro. Quindi il suo valore rimarrà immutabile per tutta la vita del token.
    • Proprietà: definisce gli attributi standard del token che possono variare durante il ciclo di vita del token, ad esempio l'array di documenti che compongono la cartella.
  • customMethods: posizione in cui è necessario definire l'elenco dei metodi personalizzati. Per questi metodi, Oracle Blockchain App Builder genererà solo la firma del metodo, senza alcuna implementazione su di essi. L'implementazione di questi metodi è l'unico codice che può essere implementato dallo sviluppatore.

I seguenti collegamenti descrivono come configurare qualsiasi tipo di entità (NFT, FT o entità standard) in base alle esigenze aziendali:

Una volta creato il file di specifica, possiamo richiedere a Oracle Blockchain App Builder di creare lo scaffold del progetto seguendo questi passi successivi.

  1. Se il file di specifica è stato creato all'esterno di Oracle Blockchain App Builder, è necessario importare il file di specifica in Oracle Blockchain App Builder. Fare clic sui puntini di sospensione accanto al frame SPECIFICATIONS e dal popup fare clic su Importa specifica.
  2. Selezionare il file di specifica e fare clic su Importa specifica.
  3. Per poter creare un nuovo progetto con codice concatenato basato sul file di specifica importato, fare clic sull'icona + nell'angolo superiore destro del frame CHAINCODES. Verrà aperta la procedura guidata Crea codice concatenato.
  4. Nella procedura guidata Crea codice concatenato è necessario specificare i dettagli riportati di seguito.
    • Nome: il nome del progetto.
    • Lingua: lingua per creare lo scaffold del progetto. È possibile selezionare solo Typescript e GoLang. Poiché stiamo usando Typescript in questo playbook di soluzioni per l'implementazione dei metodi personalizzati, consigliamo di selezionare Typescript.
    • Specifica: selezionare il file di specifica appena creato nei passi precedenti.
    • Posizione/dominio: a seconda della lingua selezionata, verrà richiesto di definire la posizione in cui verrà posizionato il progetto per la lingua di scrittura tipo o il dominio per la lingua GoLang.
    Se tutti i dettagli sono corretti, dovrebbe essere visualizzato un messaggio verde nella procedura guidata. In caso contrario, controllare l'output generato durante la creazione del ponteggio del progetto.
  5. Nella sezione CHAINCODES, dovremmo vedere il nuovo progetto generato. Facendo clic sul progetto, passare alla cartella src all'interno del progetto, in cui è stato generato il codice sorgente:
    • All'interno della cartella src/controller, vedremo la classe principale che rappresenta il nostro smart contract, con tutti i metodi generati automaticamente per gestire le nostre entità.
    • All'interno della cartella src/model verrà visualizzata la classe che rappresenta l'entità NFT.
  6. Passare alla cartella src/controller e selezionare la classe del controller, verrà visualizzato tutto il codice generato automaticamente da Oracle Blockchain App Builder e, andando alla fine del file, verranno visualizzate tutte le firme dei metodi personalizzati senza alcuna implementazione.
  7. A questo punto dovremmo creare l'implementazione dei metodi personalizzati. Per semplicità, abbiamo fornito tutti i codici di implementazione per tali metodi nel file CMS_customMethods.ts disponibile in GitHub. È sufficiente sostituire le firme generate automaticamente da Oracle Blockchain App Builder con il contenuto nel file di riferimento.
La classe Controller, righe prima dei metodi personalizzati, include tutto il codice generato automaticamente per gestire il ciclo di vita dei token NFT. L'immagine seguente illustra le diverse aree coperte da tali metodi.

oracle-blockchain-nft-token-oracle.zip

A questo punto il codice concatenato è pronto per essere utilizzato, quindi possiamo distribuire e testare il codice concatenato localmente seguendo le istruzioni da Test del codice concatenato su una rete Hyperledger Fabric locale.

Distribuire il contratto smart

Dopo aver testato localmente il codice concatenato, procedere alla distribuzione nella rete reale creata in precedenza utilizzando la console del servizio Oracle Blockchain effettuando le operazioni riportate di seguito.

  • Confezionamento del progetto codice concatenato.
  • Installazione e distribuzione del package chaincode nella singola istanza (founder).
Nella sezione seguente vengono descritti i passi dettagliati per eseguire la distribuzione.
  1. Creare il package distribuibile dal progetto codice concatenato. Da Visual Studio, fare clic sul pulsante destro sopra il nome del progetto del codice concatenato, selezionare l'opzione Pacchetto dal menu popup e selezionare la directory per salvare il file del package del codice concatenato.
  2. Accedere alla console di Oracle Blockchain Service per installare e distribuire il package chaincode nell'istanza fondatore.
  3. Passare alla scheda Codice di catena e fare clic su Distribuisci un nuovo codice di catena.
  4. Selezionare l'opzione Distribuzione avanzata.
  5. Impostare tutti i valori per installare il package codice concatenato nell'istanza fondatore e fare clic su Avanti.
    • Etichetta pacchetto: fornire un nome che consenta di identificare il pacchetto installato nei diversi canali esistenti. Poiché è possibile distribuire più di una versione dello stesso smart contract in canali diversi, è consigliabile impostare un nome di etichetta del pacchetto simile al seguente:
      <smartContractName>_<channel>_<version>
      
    • Lingua codice di catena: selezionare una delle diverse lingue in base alla lingua in cui è stato sviluppato il codice di catena.
    • Peer di destinazione: selezionare i peer in cui si desidera installare il package codice concatenato.
    • Codice concatenato in package: lasciare deselezionata questa casella di controllo se si sta caricando un file zip. Selezionare la casella di controllo per i file tar.gz.
    • Origine codice catena: fare clic su Carica file codice catena e selezionare il file zip codice catena.
  6. Se l'installazione riesce, verrà visualizzato il messaggio di operazione riuscita. Il passo successivo è la distribuzione del codice concatenato nel canale selezionato, pertanto è necessario impostare tutti i valori correlati alla fase di distribuzione e fare clic su Avanti.
    • Canale: selezionare il canale in cui si desidera distribuire lo smart contract.
    • Nome codice di connessione: impostare il nome con cui verrà distribuito il contratto smart sul canale.
    • Versione: assegnare un numero a questa distribuzione, allineato al pacchetto installato in precedenza. In questo modo, sarà possibile correlare i pacchetti installati con i codici concatenati distribuiti in canali diversi.
    • Init-required: selezionare questa casella di controllo se è necessario richiamare il metodo init del codice concatenato prima di consentire le transazioni utente.
    • Criterio di dichiarazione a sostegno: specificare i criteri di dichiarazione a sostegno durante la distribuzione. In questo esempio di guida sulla soluzione, non stiamo utilizzando criteri di approvazione.
    • Raccolta dati privati: impostare le raccolte dati privati, se necessario. In questo esempio di playbook di soluzioni, non verrà impostata la raccolta di dati privati.
Se la distribuzione riesce, dopo aver chiuso l'installazione e la distribuzione, si dovrebbe vedere come il pacchetto è stato installato nei due peer dell'istanza e anche creato un'istanza in uno dei canali.

Inizializza contratto smart

Quando si tratta di token FT e NFT, è necessario eseguire una serie di azioni amministrative prima di poter eseguire i metodi aziendali. Con Oracle Blockchain, tutti i task amministrativi possono essere eseguiti come semplici chiamate REST e riduce notevolmente lo sforzo necessario per inizializzare lo smart contract.

Nota

Prima di eseguire uno dei seguenti passi, è necessario creare enrollmentIDs nei proxy REST per gli utenti a cui è stato concesso l'accesso ai metodi di smart contract. L'iscrizione è un mapping tra il nome utente che richiama l'API REST e gli account gestiti internamente dalla blockchain a cui verranno assegnati i token come descritto nell'argomento relativo alla creazione di iscrizioni nei nodi proxy REST.

Utilizzare la seguente raccolta Postman per inizializzare facilmente lo smart contract: Scarica la raccolta Postman

Nella cartella AdminSteps di questa raccolta Postman sono presenti tre chiamate di richiesta da eseguire per l'inizializzazione dello smart contract.

La raccolta Postman è pronta per essere utilizzata, ma esiste un set di variabili che deve essere configurato in modo adeguato al proprio ambiente (password, URL e così via). Queste variabili vengono impostate nella scheda Variabili dell'insieme Postman. La tabella seguente mostra tutte le variabili definite e che devono essere adattate all'ambiente in uso.

Nome variabile Valore variabile
bc_founder_provider_url https://org1-w....
bc_timeout 60.000
bc_nft_founder_userid1 cmsleg001
bc_nft_founder_userid1_pwd password
bc_nft_founder_userid2 cmsfin001
bc_nft_founder_userid2_pwd password
bc_nft_founder_userid3 cmsrsk001
bc_nft_founder_userid4_pwd password
bc_channel_name wedocms
bc_chaincode_name WEDOCMS

Trovare l'endpoint in cui l'API REST è accessibile dalla console del servizio Blockchain.

  1. Accedi alla console del servizio Blockchain tramite OCI Console.
  2. Andare alla scheda Nodi. Verranno visualizzati tutti i nodi che compongono questa istanza. Nel nodo restproxy verrà visualizzato l'URL dell'endpoint nella colonna Instradamento.
    Ricorda che le iscrizioni vengono create a livello di istanza, non a livello di rete, quindi la registrazione per l'utente sarà disponibile solo tramite l'URL restproxy dell'istanza fondatore, quindi, se le nuove istanze entrano nella rete, con i nuovi utenti autorizzati ad accedere alla rete, tali utenti dovranno esistere nella tenancy appropriata e le iscrizioni per tali utenti devono essere create anche nel proxy di ripristino dell'istanza corrispondente.
Una volta configurata correttamente la raccolta Postman, possiamo procedere con l'inizializzazione dello smart contract. L'inizializzazione di uno smart contract NFT è notevolmente più semplice dell'inizializzazione di uno smart contract FT, basta eseguire tre passaggi:
  1. Inizializzazione Smart Contract (Init Admin User Accounts).
  2. Creazione di portafogli per gli utenti che possono possedere i token NFT.
  3. Assegnare il ruolo minter agli utenti che devono disporre di tale privilegio.
Le seguenti chiamate REST API corrispondono alle chiamate nella cartella AdminSteps dalla raccolta Postman fornita.
  1. Inizializzare il codice concatenato (Passo 0: inizializza account utente amministratore) indicando gli account utente ai quali sarà consentito eseguire task amministrativi. È importante impostare correttamente gli argomenti del metodo init: 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
    }
    
  2. Creare account utente per tutti gli utenti che possono essere custodi degli asset NFT che rappresentano gli asset fisici. È possibile eseguire questa operazione eseguendo la richiesta Postman Passo 1: Crea account. Per le specifiche del nostro caso d'uso, ci sono solo tre utenti correlati con la stessa singola organizzazione appartenente alla rete. Questa chiamata deve essere eseguita tutte le volte che gli utenti per i quali si desidera creare un account. Nel nostro caso tre volte, ciascuno con i seguenti parametri:
    • "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
    }
    
  3. Impostare l'utente a cui è consentito coniare i token. In questo caso coniare un token significa creare una nuova cartella contenente un nuovo set di documenti, in modo da poter decidere quale dei tre utenti esistenti (cmsleg001, cmsfin001 o cmsrsk001) può eseguire queste azioni e per tali utenti eseguire la richiesta Passo 2: AddRole dall'insieme Postman.
    
    {
        "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name
        "args": [
            "addRole", //Method name
            "minter","org1","cmsleg001" //Role, OrgId, UserID
            ],
        "timeout": 60000,
        "sync": true
    }