+-+-+ +-+ +-+-+-+-+
|G|O| |4| |H|I|V|E|
+-+-+ +-+ +-+-+-+-+

 --- A GOPHER-LIKE INTERFACE FOR HIVE BLOCKCHAIN ---

[Mastering Ethereum] Oracle

BY: @modolee | CREATED: Dec. 2, 2018, 10:23 a.m. | VOTES: 10 | PAYOUT: $0.02 | [ VOTE ]

https://steemitimages.com/DQmWQDjyP5d1RNW3mkCWUkDQ6yh3uDJFUZErPpaKBwKi4gM/iron_modolee.png
안녕하세요. 개발자 모도리입니다.
요즘 참여하고 있는 스터디에서 Mastering Ethereum 를 교재로 하여 매주 스터디를 진행하고 있습니다. 이번에는 이더리움 지갑에 대해 정리해서 올립니다.

오라클

오라클이 왜 필요한가?

이더리움 내부에서는 랜덤 소스가 없다.

외부 데이터는 트랜잭션 data payload를 통해서만 이더리움 내부로 들어올 수 있다.

오라클 사용 사례 및 예시

오라클 디자인 패턴

모든 오라클이 공통적으로 제공하는 기능

  1. 오프 체인 소스로 부터 데이터를 수집한다.
  2. 서명 된 트랜잭션에 데이터를 온 체인에 전송한다.
  3. 데이터를 스마트 컨트랙트의 저장소에 저장하여 사용 가능하게 한다.

오라클을 설정하는 방법은 크게 3가지로 나눌 수 있다.

즉시 읽기

publish - subscribe

request - response

  1. dApp으로부터 쿼리를 받는다.
  2. 쿼리를 파싱한다.
  3. 지불 및 데이터 액세스 권한이 제공되는지 확인한다.
  4. 오프 체인 소스에서 관련 데이터를 검색한다. (필요한 경우 암호화)
  5. 데이터가 포함 된 거래에 서명한다.
  6. 트랜잭션을 네트워크로 브로드 캐스트한다.
  7. 알림 등 필요한 추가 트랜잭션을 스케줄링한다.

데이터 인증

진위성 증명

[IMAGE: https://cdn-images-1.medium.com/max/1600/0*5qiPf50N-wSYXZa9.png]

신뢰할 수 있는 실행 환경(TEE)

계산 오라클

public class SampleContractCryptlet : Cryptlet
  {
        public SampleContractCryptlet(Guid id, Guid bindingId, string name,
            string address, IContainerServices hostContainer, bool contract)
            : base(id, bindingId, name, address, hostContainer, contract)
        {
            MessageApi = new CryptletMessageApi(GetType().FullName,
                new SampleContractConstructor())

TrueBit

탈중앙화 된 오라클

ChainLink

Solidity용 오라클 클라이언트 인터페이스

Oraclize

[IMAGE: https://cdn-images-1.medium.com/max/800/1*5KrHGg6BdR3SNWjY5EM0-w.png]

/*
   Kraken-based ETH/XBT price ticker
   This contract keeps in storage an updated ETH/XBT price,
   which is updated every ~60 seconds.
*/
pragma solidity ^0.4.0;

import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";


contract KrakenPriceTicker is usingOraclize {

    string public priceETHUSD;

    event NewOraclizeQuery(string description);
    event NewKrakenPriceTicker(string price);

    function KrakenPriceTicker() public {
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        update();
    }

    function __callback(bytes32 myid, string result, bytes proof) public {
        if (msg.sender != oraclize_cbAddress()) revert();
        priceETHUSD = result;
        NewKrakenPriceTicker(priceETHUSD);
        update();
    }

    function update() public payable {
        if (oraclize_getPrice("URL") > this.balance) {
            NewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
        } else {
            NewOraclizeQuery("Oraclize query was sent, standing by for the answer..");
            oraclize_query(60, "URL", "json(https://api.kraken.com/0/public/Ticker?pair=ETHUSD).result.XETHZUSD.c.0");
        }
    }
}
  1. oraclize_query를 이용해서 쿼리에 대한 데이터를 요청한다.
  2. 요청은 __callback 함수를 통해서 전달되며, 원하는 동작을 하도록 구현한다.

BlockOne IQ

pragma solidity ^0.4.11;

contract Oracle {
    uint256 public divisor;
    function initRequest(
       uint256 queryType, function(uint256) external onSuccess,
       function(uint256
    ) external onFailure) public returns (uint256 id);
    function addArgumentToRequestUint(uint256 id, bytes32 name, uint256 arg) public;
    function addArgumentToRequestString(uint256 id, bytes32 name, bytes32 arg)
        public;
    function executeRequest(uint256 id) public;
    function getResponseUint(uint256 id, bytes32 name) public constant
        returns(uint256);
    function getResponseString(uint256 id, bytes32 name) public constant
        returns(bytes32);
    function getResponseError(uint256 id) public constant returns(bytes32);
    function deleteResponse(uint256 id) public constant;
}

contract OracleB1IQClient {

    Oracle private oracle;
    event LogError(bytes32 description);

    function OracleB1IQClient(address addr) public payable {
        oracle = Oracle(addr);
        getIntraday("IBM", now);
    }

    function getIntraday(bytes32 ric, uint256 timestamp) public {
        uint256 id = oracle.initRequest(0, this.handleSuccess, this.handleFailure);
        oracle.addArgumentToRequestString(id, "symbol", ric);
        oracle.addArgumentToRequestUint(id, "timestamp", timestamp);
        oracle.executeRequest(id);
    }

    function handleSuccess(uint256 id) public {
        assert(msg.sender == address(oracle));
        bytes32 ric = oracle.getResponseString(id, "symbol");
        uint256 open = oracle.getResponseUint(id, "open");
        uint256 high = oracle.getResponseUint(id, "high");
        uint256 low = oracle.getResponseUint(id, "low");
        uint256 close = oracle.getResponseUint(id, "close");
        uint256 bid = oracle.getResponseUint(id, "bid");
        uint256 ask = oracle.getResponseUint(id, "ask");
        uint256 timestamp = oracle.getResponseUint(id, "timestamp");
        oracle.deleteResponse(id);
        // Do something with the price data
    }

    function handleFailure(uint256 id) public {
        assert(msg.sender == address(oracle));
        bytes32 error = oracle.getResponseError(id);
        oracle.deleteResponse(id);
        emit LogError(error);
    }

}
  1. initRequest 함수에 쿼리 유형, 성공, 실패 시의 callback 함수를 지정한다.
  2. addArgumentToRequestString, addArgumentToRequestUint로 매개변수를 지정한다.
  3. executeRequest를 실행해서 요청한다.
  4. 성공, 실패에 따라 해당 callback 함수로 가서 원하는 작업을 수행한다.

결론

https://steemitimages.com/DQmWQDjyP5d1RNW3mkCWUkDQ6yh3uDJFUZErPpaKBwKi4gM/iron_modolee.png
* 저는 블록체인 개발사 (주)34일에서 블록체인 엔지니어로 일하고 있습니다.
* 880만 팔로워 전세계 1위 한류 미디어 케이스타라이브(KStarLive)와 함께 만든 한류 플랫폼에서 사용되는 케이스타코인(KStarCoin) 프로젝트를 진행 중입니다. 팬 커뮤니티 활동을 하면서 코인을 얻을 수 있으며, 한류 콘텐츠 구매, 공연 예매, 한국 관광 상품 구매, 기부 및 팬클럽 활동 등에 사용 될 계획입니다.

TAGS: [ #kr-dev ] [ #kr ] [ #ethereum ] [ #oracle ] [ #kstarlive ]

Replies

@noisysky | Dec. 2, 2018, 11:02 a.m. | Votes: 0 | [ VOTE ]

몬가 굉장히 어렵네요
저도 공부해보고 싶네요
케이스타코인 응원합니다

@modolee | Dec. 2, 2018, 1:53 p.m. | Votes: 0 | [ VOTE ]

감사합니다~^^

[ BACK TO TRENDING ] [ BACK TO MENU ]
CMD>