C 在 Oracle Blockchain Platform 上執行 EVM 的固態智慧合約

您可以在 Oracle Blockchain Platform 上部署為鏈碼的 Ethereum Virtual Machine (EVM) 來執行 Solidity 智慧合約。

EVM 在乙太網路中執行 Solidity 智能合約。EVM 是透過 Hyperledger Burrow 專案建立,並整合到 Hyperledger Fabric 中。此專案可讓您使用 Hyperledger Fabric 允許的區塊鏈平台,與以 EVM 相容語言 (例如 Solidity) 撰寫的 Ethereum 智能合約互動。請參閱:Hyperledger Fabric EVM chaincode

下列步驟概述在已佈建的 Oracle Blockchain Platform 實例上執行 Solidity 智慧合約的程序:
  1. 將 EVM 鏈碼套件上傳至 Oracle Blockchain Platform
  2. 在通道上部署 EVM 鏈碼。
  3. 使用 Remix IDE 產生 Solidity 智慧合約的位元組碼。
  4. 將智慧合約位元組碼部署至部署的 EVM 鏈碼。使用從部署傳回的地址來傳送交易。
本主題中的步驟已經過 fabric-chaincode-evm:release-0.4 的測試,可能無法與其他版本搭配使用。

設定 EVM 鏈碼套件

您必須先設定 EVM 鏈碼套件,才能部署智能合約。完成下列步驟以建立鏈碼套件資料夾。

  1. 從下列 GitHub 儲存區域下載 EVM 鏈碼套件 (.zip 檔案):Hyperledger Fabric EVM 鏈碼
  2. 擷取下載的檔案 fabric-chaincode-evm-release-0.4.zip
  3. 在擷取的檔案中,導覽至 fabric-chaincode-evm-release-0.4/evmcc 目錄。
  4. 刪除 go.sum 檔案和 vendor 目錄。
  5. 使用 go mod 命令提供所有相依的 Go 模組的廠商:
    go mod tidy
    go mod vendor
  6. 瀏覽至 fabric-chaincode-evm-release-0.4/emvcc/vendor/github.com/hyperledger 目錄。
  7. /hyperledger 目錄中建立 fabric-chaincode-evm/evmcc 目錄。
  8. 將下列資料夾從 fabric-chaincode-evm-release-0.4/evmcc 目錄移至 fabric-chaincode-evm-release-0.4/evmcc/vendor/github.com/hyperledger/fabric-chaincode-evm/evmcc 目錄:
    • /address
    • /event
    • /eventmanager
    • /mocks
    • /statemanager
    目錄結構在完成時看起來與下列螢幕擷取類似:
    顯示先前步驟中所描述之修改目錄結構的螢幕擷取畫面。

  9. 壓縮 .zip 格式的最上層 fabric-chaincode-evm-release-0.4/evmcc 資料夾,然後重新命名。下列步驟使用 evmcc.zip 作為範例名稱。

Oracle Blockchain Platform 上部署 EVM Chaincode

在您建立 EVM 鏈碼套件後,將其部署到 Oracle Blockchain Platform

  1. 登入 Oracle Blockchain Platform 主控台。
  2. 鏈碼頁籤上,選取部署新的鏈碼
  3. 選取快速建置,然後輸入下列資訊:
    • 套裝程式標籤:輸入鏈碼套裝程式的描述。
    • 鏈碼語言:GoLang。
    • 鏈碼名稱:輸入鏈碼的名稱。例如,輸入 soliditycc
    • 版本:v1
    • Init-required:不選取此項目。
    • 通道:選取您要安裝鏈碼的通道。
    • 鏈碼來源:上傳您在先前步驟中建立的 evmcc.zip 套裝程式。
    如需「快速部署」精靈的詳細資訊,以及套件標籤鏈碼名稱等欄位的限制,請參閱:使用快速部署

送出資訊之後,鏈碼頁面中會顯示 EVM 鏈碼,並在您選取要安裝該鏈碼的每個通道上列為已部署的鏈碼。

建立並編譯您的穩固智能合約

  1. 開啟瀏覽器型 Remix IDE:https://remix.ethereum.org/
  2. 如果您已撰寫 Solidity 智慧型合約,請將其匯入至 Remix。
  3. 如果您沒有寫入 Solidity 智慧合約,請在 Remix 中建立 Solidity 檔案 (.sol 檔案),然後採取下列其中一個步驟:
    • 如果您熟悉 Solidity,請建立自己的智能合約檔案。
    • 使用 Solidity 文件中提供的 SimpleStorage 範例程式碼: Solidity:Smart Contracts 簡介
    • 使用此範例所使用的範例程式碼,以 string name 值作為輸入,並使用 set(name)get() 函數來列印與輸出字串相同的值。
      pragma solidity ^0.4.0;
      contract Myname {
          string public yourName;
      
          function set(string name) public {
              yourName = name;
          }
          function get() public view returns (string) {
              return yourName;
          }
      }
      
    您可能會看到與智慧合約中指定之版本不符的預設編譯器版本相關的錯誤訊息。
  4. 編譯您的智能合約。開啟 Remix 中的實體編譯器面板,確定您的智慧型合約頁籤已開啟,以選取它作為要編譯的檔案,將編譯器版本設為最新的 4。X 版本,然後選取編譯
    「Remix 編譯器」檢視中測試 Solidity 智慧合約的螢幕擷取。

  5. 編譯檔案之後,請選取位元組碼圖示,將位元組碼複製為 JSON 文件至您的剪貼簿。
  6. 將複製的位元組碼貼到文字編輯器中並加以儲存。

部署智能合約

在複製的位元組碼中,您需要的區段是 "object" 欄位。這是樣本智慧合約的 EVM 位元組碼。
"object": "608060405234801561001057600080fd5b50610410806100206000396000f30060
8060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463
ffffffff1680634ed3885e1461005c5780636d4ce63c146100c5578063d97d663014610155575b600080fd5b34801561
006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402
602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101
e5565b005b3480156100d157600080fd5b506100da6101ff565b60405180806020018281038252838181518152602001
91508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b505050509050
90810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180
910390f35b34801561016157600080fd5b5061016a6102a1565b60405180806020018281038252838181518152602001
91508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b505050509050
90810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180
910390f35b80600090805190602001906101fb92919061033f565b5050565b6060600080546001816001161561010002
03166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615
6101000203166002900480156102975780601f1061026c57610100808354040283529160200191610297565b82019190
6000526020600020905b81548152906001019060200180831161027a57829003601f168201915b505050505090509056
5b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190
818152602001828054600181600116156101000203166002900480156103375780601f1061030c576101008083540402
83529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003
601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f01
6020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182
015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b61
03e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a72305820a990d4
0b57c66329a32a18e847b3c18d6c911487ffadfed2098e71e8cafa0c980029",
一般而言,EVM 需要兩個引數:
  • to 位址。
  • 乙太網路交易所需的 input 位元組碼。

若要部署智慧型合約,to 欄位為零位址,而 input 為已編譯的合約 EVM 位元組碼。因此,invoke 指令提供兩個引數。第一個在傳統上應該是鏈碼中的函數名稱,現在是 0000000000000000000000000000000000000000,第二個引數是 Solidity 智慧型合約位元組碼。

  1. 若要在 Oracle Blockchain Platform 上部署 Solidity 智慧合約,您可以進行下列 REST 代理呼叫,將兩個引數傳送至 EVM。
    {
        "chaincode": "<evmcc-ccid>",
        "args": [
            "0000000000000000000000000000000000000000",
            "<bytecode-of-the-smart-contract>"
        ],
        "timeout": 0,
        "sync": true
    }
    下列範例使用 cURL,將 Solidity 智慧合約部署至名稱為 solidityccOracle Blockchain Platform
    curl -L -X POST 'https://<hostname>:443/restproxy/api/v2/channels/<channelname>/transactions' \
    -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
    -H 'Content-Type: application/json' \
    --data-raw '{"chaincode":"<evmcc-ccid>","args":["0000000000000000000000000000000000000000","<bytecode-of-the-smart-contract>"],"timeout":0,"sync":true}'
  2. 交易的回應 payload 是已部署合約的合約地址。複製此地址並儲存。當您執行智慧型合約功能時,會使用合約地址。
    API 呼叫與回應的畫面擷取,其中顯示有效負載回應欄位中的智慧型合約地址。
    在此範例中,智慧型合約地址為 66b92979bb66d645371b3247177e4b2513cb9834
有兩種方式可與已部署的智慧合約互動。
  1. 使用方法的雜湊值和輸入參數進行互動。
  2. 直接使用方法名稱和輸入參數進行互動。

使用雜湊值與智慧型合約互動

擁有智慧型合約地址後,您可以使用下列呼叫,透過 REST 代理與已部署的智慧型合約互動。

若要執行函數,您可以使用呼叫和查詢交易,但使用不同的參數。範例合約包含兩個函數:getset

在這些交易中,to 欄位是合約地址,而 input 欄位是函數執行雜湊與任何必要引數串連。

您必須取得函數執行的雜湊,才能執行交易。若要這麼做,簡單的方法是執行 Remix IDE 中的函數,然後從交易日誌複製雜湊:

  1. 在 Remix IDE 中,開啟部署並執行交易面板。請確定已在合約欄位中選取您的合約,然後選取部署
    即將部署之 Solidity 合約的畫面擷取。

    部署完成後,合約將會列在已部署的合約清單中。
  2. 已部署合約清單中展開合約。智慧合約功能會列出。
  3. 執行異動。針對提供的範例,輸入 oracle ,然後選取 set
  4. 「終端機」視窗會顯示交易記錄檔。如果交易記錄最小化,請選取記錄以展開。Copy the value of the input field (which is the function execution hash) by selecting the icon next to it. 將此值儲存至與合約地址相同的地點,移除前導 0x
    「部署」頁面的螢幕擷取畫面,其中顯示已完成的交易和欄位值,並指向包含函數執行雜湊值的輸入欄位。

  5. 在您擁有函數執行雜湊和合約位址之後,就可以使用雜湊和位址作為原始資料引數,在 Oracle Blockchain Platform 上執行設定交易。
    
    --data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<setfunctionexecutionhash>"]}'
    
    下列範例顯示如何使用 cURL 來執行交易:
    curl -L -X POST 'https://<hostname>:443/restproxy/api/v2/channels/<channelname>/transactions' \
    -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
    -H 'Content-Type: application/json' \
    --data-raw '{"chaincode":"soliditycc","args":["66b92979bb66d645371b3247177e4b2513cb9834","4ed3885e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066f7261636c650000000000000000000000000000000000000000000000000000"]}'
    
  6. 開啟 Oracle Blockchain Platform 主控台,並檢查交易是否列在分類帳中。

若要使用智慧型合約的 get 函數來執行其他交易 (例如查詢),您可以在「混搭」中產生函數執行雜湊,然後將其與合約地址合併:

  1. 部署與執行交易畫面的 Remix 中,確定您的合約仍列在已部署的合約下。如果不是,請重新部署。
  2. 選取 get 。依照設定交易的方式,從交易擷取並儲存輸入,移除前置 0x
    在 Remix 中擷取取得交易的畫面,確認輸入欄位包含必要的函數執行雜湊。

  3. 使用此交易雜湊和合約地址,對部署在 Oracle Blockchain Platform 上的鏈碼執行查詢交易。
    
    --data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<getfunctionexecutionhash>"]}'
    
    下列範例顯示如何使用 cURL 來執行交易:
    curl -L -X POST 'https://<hostname>:443/restproxy/api/v2/channels/<channelname>/chaincode-queries' \
    -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
    -H 'Content-Type: application/json' \
    --data-raw '{"chaincode":"soliditycc","args":["66b92979bb66d645371b3247177e4b2513cb9834","6d4ce63c"]}'
    
    傳回的有效負載將包含正在查詢的資產,在範例中為字串 oracle