C 在 Oracle Blockchain Platform 上使用 EVM 執行 Solidity Smart Contracts

您可以與在 Oracle Blockchain Platform 上部署為鏈碼的以太坊虛擬機器 (EVM) 執行 Solidity 智慧合約。

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

以下步驟概述在已佈建的 Oracle Blockchain Platform 上執行 Solidity 智慧合約的程序:
  1. Oracle Blockchain Platform 主控台下載 EVM 鏈碼套裝程式。
  2. 在通道上部署 EVM 鏈碼。
  3. 使用 Remix IDE 產生 Solidity 智慧合約的位元組碼。
  4. 將智慧合約位元組碼部署到部署的 EVM 鏈碼中。使用從部署傳回的地址來傳送交易。
本主題中的步驟已經使用 Oracle Blockchain Platform 主控台提供的 EVM 鏈碼套裝程式進行測試,可能無法與其他版本搭配使用。

附註:

如果您的鏈碼先前安裝在 Hyperledger Fabric v1.4.7 執行處理上,當您的執行處理升級至 Hyperledger Fabric v2.x 時,它應該會繼續如預期般運作。

下載 EVM 鏈碼和 Fab3 套裝程式

Oracle Blockchain Platform 主控台的開發人員工具頁籤上,開啟應用程式開發窗格,然後按一下下載 EVM 鏈碼套裝程式。您必須是管理員使用者才能下載檔案。

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 文件中提供的 Simple Storage 範例程式碼: Solidity:Introduction to 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 中的 Solidity Compiler 面板,確定已開啟您的智慧型合約頁籤,將它選取為要編譯的檔案,並將編譯器版本設為最新的 4。X 版本,然後按一下編譯。
    在 Remix Compiler 檢視中測試 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>:7443/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. 在「混搭 IDE」中,開啟部署與執行交易面板。確定已在合約欄位中選取您的合約,然後按一下部署
    即將部署之 Solidity 合約的螢幕擷取畫面。

    部署完成後,合約應列在已部署的合約清單中。
  2. 展開已部署的合約清單中的合約。智慧合約功能會列出。
  3. 執行交易。在提供的範例中,輸入 oracle ,然後按一下 set
  4. The Terminal window shows the transaction logs. If the transaction logs are minimized, expand them by clicking the log. Copy the value of the input field (which is the function execution hash) by clicking the icon next to it. Save this value to the same location as your contract address, removing the leading 0x.
    「部署」頁面的畫面擷取,其中顯示已完成的交易與欄位值,並指向包含函數執行雜湊值的輸入欄位。

  5. 在您擁有函數執行雜湊和合約位址之後,您可以使用雜湊和位址作為原始資料引數,在 Oracle Blockchain Platform 上執行設定交易。
    
    --data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<setfunctionexecutionhash>"]}'
    
    例如,使用 cURL:
    curl -L -X POST 'https://<hostname>:7443/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 函數來執行其他交易 (例如查詢),您可以在 Remix 中產生函數執行雜湊,然後將其與合約地址合併:

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

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

下列範例有效負載說明使用以十六進位格式編碼的輸入來傳送交易的另一種方式。

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "<smart-contract-address>",
        "<hexadecimal-encoded-method-and-input-parameters>"
    ],
    "sync": true
}

使用方法名稱與智慧型合約互動

使用選擇性的 setAbi 方法來設定「應用程式二進位介面 (ABI)」規格,讓您可以用可讀 (非十六進位編碼) 格式來傳送輸入並取得輸出,而不使用位元組碼。按一下 Remix IDE 之 Solidity Compiler 面板上的 ABI 圖示 (位於位元組碼圖示旁),以取得 ABI 規格。可讀取的輸入格式支援下列輸入類型:uintstringaddress booluint[]string[]address[]fab3 代理主機僅支援從 REST 代理主機執行實行方法覆寫和方法超載之智慧合約上的交易。下列範例有效負載使用 setAbi 方法來設定 ABI 規格。

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "setABI",
        "<smart-contract-address>",
        "<abi-spec-of-smart-contract>" --> use the string format of the abi specification
    ],
    "sync": true
}

您也可以直接使用方法名稱與輸入參數進行呼叫,如下列範例有效負載中所示。

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "<smart-contract-address>",
        "<smart-contract-method-name>",
		"[<array-of-input-parameters>]", --> empty array if there are no input parameters.
		"[<string-array-of-input-types>]" --> this is optional and is needed when there is method overriding in the smart contract.
    ],
    "sync": true
}

設定燃氣金額

您可以使用 setGasAmountgetGasAmount 方法來設定燃氣量,如下列範例有效負載中所示。

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "setGasAmount",
        "<gas-amount>"
    ],
    "sync": true
}
{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "getGasAmount"
    ],
    "sync": true
}