C Oracle Blockchain Platform에서 EVM으로 Solidity Smart Contracts 실행

Oracle Blockchain Platform에서 체인 코드로 배포된 이더리움 가상 머신(EVM)을 사용하여 Solidity 스마트 계약을 실행할 수 있습니다.

EVM은 Ethereum 네트워크에서 Solidity 스마트 계약을 실행합니다. EVM은 Hyperledger Burrow 프로젝트를 통해 만들어졌으며 Hyperledger Fabric에 통합되었습니다. 이 프로젝트를 통해 Hyperledger Fabric 허가형 블록체인 플랫폼을 사용하여 Solidity와 같은 EVM 호환 언어로 작성된 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 Chaincode 및 Fab3 패키지 다운로드

Oracle Blockchain Platform 콘솔의 개발자 툴 탭에서 애플리케이션 개발 창을 열고 EVM 체인코드 패키지 다운로드를 누릅니다. 파일을 다운로드하려면 관리자 사용자여야 합니다.

Oracle Blockchain Platform에 EVM Chaincode 배포

EVM 체인코드 패키지를 다운로드한 후 Oracle Blockchain Platform에 배포합니다.

  1. Oracle Blockchain Platform 콘솔에 로그인합니다.
  2. 체인코드 탭에서 새 체인코드 배포를 누릅니다.
  3. 빠른 배치를 선택하고 다음 정보를 입력합니다.
    • 패키지 레이블: 체인코드 패키지에 대한 설명을 입력합니다.
    • 체인코드 언어: GoLang.
    • 체인 코드 이름: 체인 코드의 이름을 입력합니다. (예: soliditycc)
    • 버전: v1.
    • 초기 필수: 이 항목을 선택하지 않은 상태로 둡니다.
    • 채널: 체인코드를 설치할 채널을 선택합니다.
    • 패키지화된 체인코드임: 이 항목을 선택하지 않은 상태로 둡니다.
    • 체인코드 소스: 이전에 다운로드한 evmcc.zip 패키지를 업로드합니다.
    빠른 배치 마법사에 대한 자세한 내용 및 패키지 레이블체인코드 이름과 같은 필드에 대한 제한 사항은 빠른 배치 사용을 참조하십시오.

정보를 제출하면 EVM 체인코드가 체인코드 탭에 표시되고 설치하도록 선택한 각 채널에 배포된 체인코드로 나열됩니다.

Solidity Smart Contract 생성 및 컴파일

  1. 브라우저 기반 리믹스 IDE(https://remix.ethereum.org/)를 엽니다.
  2. Solidity 스마트 계약을 이미 작성한 경우 리믹스로 가져오세요.
  3. Solidity 스마트 계약서가 작성되지 않은 경우 리믹스에 Solidity 파일(.sol)을 만들고 다음 중 하나를 수행합니다.
    • Solidity에 익숙하다면 자신만의 스마트 계약 파일을 만들 수 있습니다.
    • Solidity 설명서에 제공된 Simple Storage 샘플 코드 단결성: 스마트 계약 소개를 사용할 수 있습니다.
    • 이 예제에 사용되는 샘플 코드를 사용할 수 있습니다. 이 예제에서는 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 버전을 누르고 Compile을 누릅니다.
    Remix 컴파일러 보기에서 Solidity 스마트 계약의 화면 캡처입니다.

  5. 파일이 컴파일된 후 Bytecode 아이콘을 눌러 바이트 코드를 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 주소입니다.
  • Ethereum 거래에 필요한 input.

스마트 계약을 배포하기 위해 to 필드는 주소가 0이고 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을 사용하여 이름이 solidityccOracle Blockchain Platform에 Solidity 스마트 계약을 배포합니다.
    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 프록시를 통해 배포된 스마트 계약과 상호 작용할 수 있습니다.

함수를 실행하려면 서로 다른 파라미터를 사용하여 호출 및 query 트랜잭션을 사용합니다. 샘플 계약에는 getset의 두 가지 기능이 포함되어 있습니다.

이러한 트랜잭션에서 to 필드는 계약 주소이고 input 필드는 필수 인수와 연결된 함수 실행 해시입니다.

트랜잭션을 실행하려면 함수 실행의 해시를 획득해야 합니다. 이 작업을 수행하는 간단한 방법은 리믹스 IDE의 함수를 실행한 다음 트랜잭션 로그에서 해시를 복사하는 것입니다.

  1. 리믹스 IDE에서 트랜잭션 배치 및 실행 패널을 엽니다. 계약 필드에서 계약이 선택되었는지 확인하고 배치를 누릅니다.
    배포될 Solidity 계약의 화면 캡처입니다.

    배포가 완료되면 배포된 계약 목록에 계약이 나열됩니다.
  2. 배포된 계약 목록에서 계약을 확장합니다. 스마트 계약 기능이 나열됩니다.
  3. 트랜잭션을 실행합니다. 제공된 예제에 대해 oracle을 입력한 다음 set를 누릅니다.
  4. 터미널 창에 트랜잭션 로그가 표시됩니다. 트랜잭션 로그가 최소화되면 로그를 눌러 확장합니다. 옆에 있는 아이콘을 눌러 input 필드(함수 실행 해시)의 값을 복사합니다. 이 값을 계약 주소와 동일한 위치에 저장하고 선행 0x를 제거합니다.
    완료된 트랜잭션 및 필드 값을 표시하고 함수 실행 해시 값을 포함하는 입력 필드를 가리키는 Deployment 페이지의 화면 캡처입니다.

  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 함수를 사용하여 질의와 같은 다른 트랜잭션을 실행하려면 리믹스에서 함수 실행 해시를 생성한 다음 이를 계약 주소와 결합할 수 있습니다.

  1. 거래 배포 및 실행 패널의 리믹스에서 계약이 배포된 계약 아래에 계속 나열되는지 확인합니다. 그렇지 않은 경우 재배치합니다.
  2. get을 누릅니다. set 트랜잭션에서 수행한 것처럼 트랜잭션에서 입력을 검색하여 저장하고 선행 0x를 제거합니다.
    입력 필드에 필수 함수 실행 해시가 포함되어 있음을 알리는 리믹스의 get 트랜잭션 화면 캡처입니다.

  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 문자열)이 포함됩니다.

다음 샘플 페이로드는 16진수 형식으로 인코딩된 입력을 사용하여 트랜잭션을 전송하는 또 다른 방법을 보여줍니다.

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

메소드 이름을 사용하여 스마트 계약과 상호 작용

선택적 setAbi 메소드를 사용하여 ABI(Application Binary Interface) 사양을 설정합니다. 이 사양을 사용하면 바이트 코드 대신 입력을 보내고 출력을 읽을 수 있는(16진수로 인코딩되지 않음) 형식으로 가져올 수 있습니다. 리믹스 IDE의 Solidity Compiler 패널에서 ABI 아이콘(Bytecode 아이콘 옆에 있음)을 눌러 ABI 사양을 가져옵니다. 읽을 수 있는 입력 형식에 대해 지원되는 입력 유형은 uint, string, address, bool, uint[], string[]address[]입니다. 메소드 대체 및 메소드 오버로드를 구현하는 스마트 계약에 대한 트랜잭션 실행은 REST 프록시에서만 fab3 프록시에서 지원되지 않습니다. 다음 샘플 페이로드는 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
}