建立與部署智慧型合約

若要建立智慧合約,我們需要定義要在區塊鏈中儲存和管理的實體,如以下影像的實體模型所示。


oracle-blockchain-cms-entity.png 的描述如下
oracle-blockchain-cms-entity.png 圖解描述

所有這些實體及其關係、管理實體和與實體互動所需的所有邏輯,以及將它們保存到區塊鏈分類帳的定義在智慧合約中。

此資料夾以 NFT 權杖表示,因此將開發並起始為 NFT。其他相依實體 (文件和特性) 是標準實體,也是資料夾的子實體,因此將開發為標準實體,而不需要初始化。

智慧合約建立後,我們將在我們建立的區塊鏈網路中安裝並部署。

建立智慧型合約

設定好 Oracle Blockchain App Builder 之後,就可以建立規格檔案。規格檔案可以建立為簡單的 YAML 檔案,如下列程式碼所示。

附註:

您也可以從 GitHub 下載此檔案:下載 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 

在此規格檔案中,您可以在定義的第一個實體 (folderNFT) 中看到 NFT 記號表示的所有區段和屬性。檔案中定義的區段概述:

  • 資產:定義不同資產 (標準實體、財務交易、NFT) 的位置。在每個資產中,我們可以區分不同的區段,這些區段會根據所代表資產的種類而有所不同。針對 NFT 與 FT,這些是不同的子區段:
    • 類型 / 符號 / 標準:指定此記號以「ERC-721 標準」為基礎,並指定唯一的符號縮排。
    • 解剖學:指定為 NFT,且是否細分為較小的分數 (現在的「整個」是 NFT 記號的唯一選項)。
    • 行為:定義記號是否可以被提示,在此情況下,它是可輸入記號的最大數目。在這裡,您必須也說明它是不可分割的記號,如果每個類別是單一的,可傳輸和可燒錄的,這與它的刪除類似 (但不會消失,所以它仍在那裡,但完全無法使用)。您也可以在此段落中將記號行為限制在特定角色。
    • 描述資料:定義在建立記號時必須設定且未來無法變更的特性排序。因此,其價值在權杖的整個生命週期中將維持不可變。
    • 特性:定義記號的標準屬性,在記號的存留期間可能會有所不同,例如構成資料夾的文件陣列。
  • customMethods:必須定義自訂方法清單的位置。對於這些方法,Oracle Blockchain App Builder 只會產生方法的簽章,不會對其進行任何實作。這些方法的實行是開發人員可以實行的唯一程式碼。

下列連結描述如何根據您的業務需求設定任何類型的實體 (NFT、FT 或標準實體):

建立規格檔案之後,我們可以依照下列步驟要求 Oracle Blockchain App Builder 建立專案結構。

  1. 如果規格檔案是在 Oracle Blockchain App Builder 外部建立,則必須將規格檔案匯入 Oracle Blockchain App Builder。按一下 SPECIFICATIONS 框架旁邊的省略符號,然後從即現式視窗按一下匯入規格
  2. 選取規格檔案,然後按一下匯入規格
  3. 若要能夠根據匯入的規格檔案建立新的鏈碼專案,請按一下 CHAINCODES 框架右上角的 + 圖示。它會開啟建立鏈碼精靈。
  4. 建立鏈碼精靈中,您必須指定下列詳細資訊:
    • 名稱:專案的名稱。
    • 語言:建立專案鷹架的語言。您只能選取 Typescript 和 GoLang。由於我們正在本解決方案手冊中使用 Typescript 來導入自訂方法,因此建議您選取 Typescript。
    • 規格:選取我們先前步驟中所建立的規格檔案。
    • 位置 / 網域:視選取的語言而定,系統會提示您定義要為 Typescript 語言或 GoLang 語言網域放置專案的位置。
    如果所有詳細資訊都正確,我們應該會在精靈中看到綠色訊息。如果不是這樣,請檢查在建立專案鷹架期間產生的輸出。
  5. 在 CHAINCODES 區段中,我們應該會看到新產生的專案。按一下專案,瀏覽至專案內的 src 資料夾,其中已產生原始程式碼:
    • src/controller 資料夾中,我們將看到代表我們智能合約的主要類別,以及管理實體的所有自動產生方法。
    • src/model 資料夾中,我們會看到代表 NFT 實體的類別。
  6. 瀏覽至 src/controller 資料夾並選取控制器類別,我們會看到 Oracle Blockchain App Builder 自動產生的所有程式碼,然後移至檔案結尾,我們會看到自訂方法的所有簽章,而不會對其進行任何實行。
  7. 此時,我們應該建立自訂方法的實行。For simplicity, we have provided all the implementation code for such methods in the file CMS_customMethods.ts available in GitHub.您只需要將 Oracle Blockchain App Builder 自動產生的簽章取代為參照檔案中的內容。
Controller 類別 (在自訂方法之前) 會包含管理 NFT 記號生命週期的所有自動產生程式碼。下圖說明此類方法所涵蓋的不同區域。

oracle-blockchain-nft-token-oracle.zip

此時,鏈碼已可供使用,因此我們可以依照在本機 Hyperledger Fabric 網路上測試您的鏈碼的指示,在本機部署並測試鏈碼。

部署智慧型合約

在本機測試鏈碼之後,請透過下列方式,繼續在先前使用 Oracle Blockchain Service Console 建立的真實網路中部署該鏈碼:

  • 封裝鏈碼專案。
  • 將鏈碼套裝程式安裝並部署到單一執行處理 (創立者)。
以下段落描述執行建置的詳細步驟。
  1. 從鏈碼專案建立可部署的套件。從 Visual Studio 按一下鏈碼專案名稱頂端的右側按鈕,從快顯功能表中選取套裝程式選項,然後選取要儲存鏈碼套裝程式檔案的目錄。
  2. 存取 Oracle Blockchain Service Console,將鏈碼套件安裝並部署到創始人執行個體中。
  3. 瀏覽至鏈碼頁籤,然後按一下部署新鏈碼
  4. 選取進階部署選項。
  5. 設定所有值,將鏈碼套裝程式安裝至創辦人執行處理,然後按一下下一步
    • 套裝軟體標籤:提供名稱以協助您識別哪些套裝軟體已安裝在不同的現有通道中。由於您可以在不同的管道中部署多個版本的相同智慧型合約,因此設定套件標籤名稱是很好的做法,例如:
      <smartContractName>_<channel>_<version>
      
    • 鏈碼語言:根據您開發鏈碼的語言,選取不同的語言。
    • 目標對等:選取您要安裝鏈碼套裝程式的對等體。
    • 封裝的鏈碼:如果上傳壓縮檔,請取消選取此核取方塊。選取 tar.gz 檔案的核取方塊。
    • 鏈碼來源:按一下上傳鏈碼檔案,然後選取鏈碼壓縮檔。
  6. 如果安裝成功,我們就會看到成功訊息。下一步是在選取的通道中建置鏈碼,因此您必須設定與建置階段相關的所有值,然後按一下下一步
    • 通路:選取您要部署智慧型合約的通路。
    • 鏈碼名稱:設定將在通道上部署智慧型合約的名稱。
    • 版本:為此部署指定一個編號,此編號會與先前安裝的套件一致。如此一來,您就可以將安裝的套裝軟體與不同通道中部署的鏈碼相關聯。
    • 需要初始:如果需要在允許使用者交易之前呼叫鏈碼的 init 方法,請選取此核取方塊。
    • 背書原則:在建置期間指定背書原則。在此解決方案手冊範例中,我們並未使用背書原則。
    • 專用資料收集:視需要設定「專用資料收集」。在此解決方案手冊範例中,我們將不會設定私密資料收集。
如果部署成功,在關閉安裝與部署之後,您應該會看到套裝軟體如何安裝在執行處理的兩個對等體中,也會在其中一個通道中建立。

初始化智慧型合約

當您處理財務交易與 NFT 權杖時,必須先執行一組管理動作,才能執行您的業務方法。使用 Oracle Blockchain 時,所有管理工作都可以以簡單的 REST 呼叫方式執行,並且大幅減少初始化智慧型合約所需的工作量。

附註:

在執行下列任何步驟之前,我們必須先為授予智慧型合約方法存取權的使用者在 REST 代理主機中建立 enrollmentIDs。註冊是呼叫 REST API 的使用者名稱與由區塊鏈內部管理的帳戶之間的對應,如在 REST 代理主機節點中建立註冊主題中所述。

使用下列 Postman 集合輕鬆初始化智能合約:下載 Postman 集合

在此 Postman 集合的 AdminSteps 資料夾中,需要執行三次智慧型合約初始化要求呼叫。

Postman 集合已可供使用,但有一組變數需要配置足以符合您自己的環境 (密碼、URL 等等)。這些變數是在 Postman 集合的變數頁籤中設定。下表顯示我們定義的所有變數,且必須適應您的環境。

變數名稱 變數值
bc_founder_provider_url https://org1-w....
bc_timeout 60000
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 星期三

從「區塊鏈服務主控台」尋找可存取 REST API 的端點。

  1. 透過 OCI 主控台存取區塊鏈服務主控台。
  2. 移至節點頁籤。它會顯示構成此執行處理的所有節點,以及在 restproxy 節點中,您將會在路由資料欄中看到端點 URL。
    請記住,註冊是在執行處理層次 (而非網路層次) 建立,因此使用者註冊只能透過創辦人執行處理的 restproxy URL 取得,因此,如果新執行處理加入網路,若有允許存取網路的新使用者,這些使用者必須存在於適當的租用戶中,而且也必須在對應執行處理的 restproxy 中建立這些使用者的註冊。
正確設定 Postman 收帳後,我們可以繼續進行智能合約初始化。NFT 智能合約的初始化比 FT 智能合約的初始化更為簡單,我們只需要執行三個步驟:
  1. 智慧型合約初始化 (初始化管理員使用者帳戶)。
  2. 為可以擁有 NFT 權杖的使用者建立公事包。
  3. 為那些應具有該權限的使用者指定較小角色。
下列 API REST 呼叫對應至所提供 Postman 集合中 AdminSteps 資料夾的呼叫。
  1. 初始化鏈碼 ( Step-0:初始化管理員使用者帳號 ),以指出允許哪些使用者帳號執行管理工作。請務必正確設定 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. 為可作為代表實體資產之 NFT 資產託管人的所有使用者建立使用者帳戶。執行步驟 1:建立帳戶 Postman 請求即可完成此作業。對於使用案例的細節,只有三位使用者與屬於網路的相同單一組織相關。此通話的執行次數必須與要建立帳戶的使用者相同。在我們的案例中,每一次都有以下參數:
    • "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. 設定允許哪些使用者輸入記號,在此情況下,提示記號代表建立新資料夾來保留一組新的文件,因此您可以決定三個現有使用者 (cmsleg001cmsfin001cmsrsk001) 中可以執行這些動作,而這些使用者則可從 Postman 集合執行步驟 2:AddRole 要求。
    
    {
        "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name
        "args": [
            "addRole", //Method name
            "minter","org1","cmsleg001" //Role, OrgId, UserID
            ],
        "timeout": 60000,
        "sync": true
    }