[Solidity] Chainlink Datafeed

임형석·2023년 11월 19일
0

Solidity


체인링크의 서비스 중 하나로, 오프체인 데이터를 온체인으로 전달해주는 역할을 한다. 데이터 종류에 따라 몇가지의 카테고리로 나뉜다.
가장 많이 쓰이는 4가지만 소개하면,

  1. Cryptocurrencies
    가장 많이 쓰이는 데이터이며, 암호화폐의 현재 가격을 알려준다.

  2. Proof of Reserve
    스테이블 코인에 페깅된 현재 USD 예치량을 알려준다.

  3. Stablecoins
    스테이블 코인의 USD 대비 현재 가격을 알려준다.

  4. Foreign Exchange
    유로화/달러, 위안화/달러 등의 화폐의 환율을 알려준다.

위 4가지 외에도

NFT Floor Price, Rate and Volatility, L2 Sequencer Uptime 가 있다.


Cryptocurrencies 데이터 중 하나인 BTC/USD 가격 데이터를 확인해보았다.

Answer 는 현재 비트코인의 가격을 알려준다.

사용 네트워크는 이더리움 메인넷이며 다른 네트워크인 아비트리움, 아발란체에서도 사용할 수 있다.

Trigger parameters 는 이 데이터의 갱신 조건을 나타낸 것이다.
Deviation threshold 0.5% 는 가격이 현재 Answer 에서 0.5% 만큼 변동이 생기면 갱신되며, Heartbeat 의 시간 값인 1시간마다 가격이 갱신된다.

Oracle Response 는 현재의 비트코인의 가격을 검증하고, 온체인으로 업데이트하는 오라클 노드를 말한다. 총 31개의 노드가 활성화 되어있으며 최소 활성화 노드는 21개이다.
갱신 조건이 활성화되면, 활성화된 모든 오라클 노드는 현재 가격 데이터를 온체인에 업데이트 해야한다.

아래의 Contract address 에서 직접 가격 데이터를 확인할 수 있다.

https://etherscan.io/address/0xf4030086522a5beea4988f8ca5b36dbc97bee88c#readContract

여기서 8번째 함수 latestAnswer 를 호출하면, 현재 가격 값을 8 decimals 에 맞추어 반환한다.

컨트랙트 내부에서 작동하는 방식은 아래의 사진과 같다.


사용 방법

price feed 를 이용해 현재 BTC/JPY, 1비트코인의 엔화가격 데이터를 스마트 컨트랙트로 받아보려고 한다.

사용 방법은 굉장히 간단하다.

위 코드를 컨트랙트에서 쓰면 된다.

AggregatorV3Interface feed = AggregatorV3Interface(address);
return feed.latestRoundData();

위 코드의 address 에 들어갈 주소 값을 찾아 넣어주면 된다.

먼저, 아래의 링크에 들어가 Sepolia 테스트넷의 BTC/USD, JPY/USD 컨트랙트의 주소를 복사해온다.

https://docs.chain.link/data-feeds/price-feeds/addresses?network=ethereum&page=1#sepolia-testnet

복사한 주소는 주석으로 정리해둔다.

    /**
     * Network: Sepolia
     * Aggregator: BTC/USD
     * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
     * Aggregator: JPY/USD
     * Address: 0x8A6af2B75F23831ADc973ce6288e5329F63D86c6
     */

정리한 주소를 사용하여 아래와 같이 인스턴스를 생성한다.

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract DataConsumerV3 {
    AggregatorV3Interface BTCUSD;
    AggregatorV3Interface JPYUSD;

    /**
     * Network: Sepolia
     * Aggregator: BTC/USD
     * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
     * Aggregator: JPY/USD
     * Address: 0x8A6af2B75F23831ADc973ce6288e5329F63D86c6
     */
    constructor() {
        BTCUSD = AggregatorV3Interface(0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43);
        JPYUSD = AggregatorV3Interface(0x8A6af2B75F23831ADc973ce6288e5329F63D86c6);
    }
}

최신 데이터를 가져오는 함수를 추가하고 Sepolia 테스트넷에 배포한다.

    function getBTCUSD() public view returns (int) {
        (,int256 answer,,,) = BTCUSD.latestRoundData();
        return answer;
    }

    function getJPYUSD() public view returns (int) {
        (,int256 answer,,,) = JPYUSD.latestRoundData();
        return answer;
    }

배포한 컨트랙트의 함수를 호출하면 아래와 같이 현재 1비트코인의 달러 가격과 1엔의 달러가격을 가져올 수 있다.

이 가격은 8 decimals 기준이다. 그러므로..

1 BTC = 36501.49213797 USD
1 JPY = 0.00668283 USD

가 되겠다.

위 가격 데이터를 사용하면, BTC/JPY 가격도 알 수 있다.

    function getBTCJPY() public view returns (int) {
        return (getBTCUSD()/getJPYUSD());
    }

컨트랙트로 받아온 가격 데이터이다.

실제 거래소의 가격이다.

왜 이러한 가격차이가 나는 것일까?


그 이유는 ..

JPY/USD 의 Heartbeat 는 24시간이며, Deviation 은 0.5 % 이기 때문이다.

그래서 갱신 시각을 확인해보니, 약 8시간 전이다.

또한, 가격에서 0.5% 이상의 변동이 없었다..

따라서, 가격 갱신이 이루어지지 않아 실제 가격 데이터와 차이가 생긴 것으로 볼 수 있다.


결론

체인링크의 데이터 피드는 오프체인 데이터를 온체인에서 자유롭게 사용할 수 있어 실제 많은 Defi 에서 이 가격 데이터 피드를 사용하고 있다.

특히, 비트코인이나 이더리움 같이 변동성이 높거나 인기가 많은 코인은 Heartbeat 시간이 1시간으로 비교적 짧아 자주 갱신되기도 하며, 아비트리움, 아발란체, 폴리곤의 EVM 기반 체인을 포함해 Solana 네트워크에서도 사용이 가능하다.

하지만, Deviation 이 보통 0.5% 로 설정되어 있기에, 0.5% 내의 가격 변동에도 민감한 앱이라면 사용하기 쉽지 않을 것 같다.

체인링크의 데이터피드를 사용해 앱을 만들 컨트랙트 개발자라면, Deviation 과 Heartbeat 시간을 신경써서 앱을 만들어야 할 것 같다.


0개의 댓글