soobook
DEFI

Blockchain Oracle

스마트 컨트랙트는 자기 체인 안의 데이터만 본다. 그런데 DeFi가 다루는 가격, 환율, 이벤트 결과는 거의 다 체인 밖에서 만들어진다. 이 간극을 메우는 미들웨어가 오라클이다.

오라클이 풀려는 문제

스마트 컨트랙트는 두 제약 위에서 동작한다. 결정론합의다.

같은 입력을 받은 모든 노드는 정확히 같은 결과를 내야 한다. 한 톨이라도 다르면 노드들은 서로 다른 상태로 갈라지고, 합의가 무너진다.

이 결정론이 외부 데이터와 정면으로 부딪힌다.

ETH 가격을 예로 들어보자. 노드 A가 거래소 API를 호출해 3,200달러를 받고, 같은 시각 노드 B가 호출해 3,201달러를 받았다고 하자. 둘은 같은 트랜잭션을 다른 결과로 실행한다. 합의는 거기서 끝이다.

블록체인이 외부 세계와 직접 통신할 수 없는 이유가 여기에 있다. 결정론은 닫힌 세계에서만 성립한다.

내부 데이터는 같은 체인의 상태에서 오기 때문에 모든 노드가 같은 값을 본다. 합의가 자동으로 따라온다. 외부 데이터는 API, 시장, 센서처럼 체인 밖에서 오는데, 노드마다 답이 갈릴 수 있어서 별도의 합의가 필요하다.

이 차이를 메우는 게 오라클이다.

오라클은 외부 데이터를 노드끼리 먼저 합의해 하나의 값으로 만든 뒤 체인에 올린다. 컨트랙트는 그 값 하나만 보면 되니까 노드마다 답이 갈리는 문제가 사라진다.

오라클은 데이터를 만드는 게 아니라, 노드 모두가 같은 데이터를 보게 한다.

Trust Model

오라클을 나누는 첫 번째 기준은 데이터를 누가 보장하느냐다.

가장 단순한 형태는 단일 노드 오라클이다. 한 운영자가 API를 호출해 그 결과를 체인에 올린다. 빠르고 싸지만, 그 한 명이 거짓말하거나 해킹당하면 그 위에 올라간 모든 컨트랙트가 같이 무너진다.

DeFi가 단일 오라클을 못 쓰는 이유다. 수억 달러의 청산 로직이 한 운영자의 정직성에 묶여 있는 구조는 누구도 받아들이지 않는다.

탈중앙 오라클은 여러 노드가 같은 데이터를 독립적으로 관측하고, 결과를 모아 단일 값을 합의한다.

graph LR
    subgraph "Off-chain Data Sources"
        S1[Coinbase]
        S2[Binance]
        S3[Kraken]
    end

    subgraph "Decentralized Oracle Network"
        N1[Node 1]
        N2[Node 2]
        N3[Node 3]
        N4[Node 4]
    end

    S1 --> N1
    S1 --> N2
    S2 --> N2
    S2 --> N3
    S3 --> N3
    S3 --> N4

    N1 --> AGG[Aggregation]
    N2 --> AGG
    N3 --> AGG
    N4 --> AGG

    AGG --> CHAIN[On-chain Contract]

여기서 두 가지 결정이 따라붙는다.

  1. 데이터 소스 다중화: 한 거래소가 거짓말해도 영향을 못 받게, 여러 거래소나 집계 사이트에서 가격을 본다.
  2. 노드 다중화: 한 노드가 거짓말해도 영향을 못 받게, 여러 노드가 독립적으로 데이터를 관측한다.

두 다중화가 모두 깨져야 오라클이 무너진다. 단일 거래소를 호출하는 단일 노드보다 공격 비용이 자릿수 단위로 비싸진다.

Push vs Pull

데이터를 체인에 올리는 시점도 가른다.

Push 모델은 가격이 일정 임계치 이상 움직이거나 정해진 주기가 되면 오라클이 자동으로 체인에 가격을 푸시한다. 컨트랙트는 언제든 최신값을 읽으면 된다.

Pull 모델은 가격을 체인에 미리 올려두지 않는다. 사용자가 필요할 때 오프체인 서명 가격을 가져와 트랜잭션 안에서 검증하고 사용한다.

구분Push 모델Pull 모델
업데이트 주체오라클 운영자사용자(트랜잭션 발신자)
가스 부담오라클이 매번 부담사용자가 호출 시점에 부담
업데이트 빈도정해진 임계치/주기사용자가 원하는 순간
신선도마지막 푸시 이후 시간트랜잭션 직전(수백 ms)
비용 한계체인 수, 페어 수에 비례해 폭발호출 빈도에 비례, 페어 수에 거의 무관

Push가 단순하지만 확장성이 약하다.

Chainlink Push 모델은 한때 가격 페어와 체인 수가 늘면서 업데이트 트랜잭션 비용이 폭발했다.

Pyth는 처음부터 Pull로 설계됐다. 가격 데이터는 Pythnet이라는 별도 앱체인에서 400 ms 단위로 갱신되고, 사용자가 다른 체인에서 그 가격을 쓸 때만 Wormhole로 서명된 메시지를 가져와 검증한다. 가격 페어 수와 체인 수가 폭발해도 오라클 비용이 거의 늘지 않는다.

Chainlink도 Data Streams로 Pull 모델을 도입했다. 두 모델은 더 이상 진영의 차이가 아니라 같은 시스템이 둘 다 제공하는 옵션에 가깝다.

OCR

Chainlink가 데이터 신선도와 가스 비용을 동시에 잡은 핵심이 OCR(Off-Chain Reporting)이다.

소박한 오라클은 노드 N개가 각자 가격을 트랜잭션으로 올리고 컨트랙트가 중앙값을 계산했다. 이 방식은 가스가 N에 비례해 늘어 노드를 늘릴수록 비싸진다.

OCR은 노드 합의를 오프체인 P2P 네트워크로 옮긴다.

sequenceDiagram
    participant N1 as Node 1
    participant N2 as Node 2
    participant N3 as Node 3
    participant L as Leader (rotating)
    participant C as On-chain Contract

    N1->>L: 관측값 + 서명
    N2->>L: 관측값 + 서명
    N3->>L: 관측값 + 서명

    Note over L: 중앙값 계산<br/>모든 서명 첨부

    L->>C: 단일 트랜잭션<br/>(보고서 + 모든 서명)
    Note over C: 서명 N개 검증 후<br/>가격 갱신

노드들은 P2P로 가격을 교환해 한 라운드의 보고서를 만든다.

리더가 정족수(2f+12f+1)의 서명을 첨부해 단일 트랜잭션으로 체인에 올린다.

가스 비용이 한 트랜잭션으로 압축되면서 노드 N을 늘려도 온체인 비용은 거의 변하지 않는다. 그러면서도 책임 추적은 살아 있다. 모든 서명이 보고서에 박혀 있어 사후에 어느 노드가 어떤 값을 보고했는지 검증 가능하다.

OCR로 Chainlink는 같은 가격 페어의 가스 비용을 90% 가까이 줄이면서, 한 라운드에 참여하는 노드 수를 31개까지 늘릴 수 있었다.

Aggregation

노드 여러 개가 각자 가격을 봤다고 하자. A는 3,200달러, B는 3,201달러, C는 3,199달러를 봤다. 컨트랙트는 결국 단일 값 하나만 받아야 하는데, 어떻게 합쳐야 할까.

가장 간단한 답은 평균이다. 그런데 평균은 한 노드가 극단값을 보고하면 결과가 그쪽으로 끌려간다. 한 노드만 매수해도 가격이 왜곡된다는 뜻이다.

오라클이 표준으로 쓰는 답은 중앙값(median)이다.

NN개 보고값을 정렬했을 때 가운데 값을 채택한다. ff개 노드가 거짓말을 해도, N2f+1N \geq 2f+1이면 중앙값은 정직한 노드의 범위 안에 머문다.

 

중앙값은 비잔틴 노드  f  명까지의 영향을 0으로 만든다\textbf{\text{중앙값은 비잔틴 노드 } f \text{ 명까지의 영향을 0으로 만든다}}

 

데이터 소스 단계에서도 같은 논리가 작동한다. 각 노드는 단일 거래소가 아니라 여러 거래소의 가격을 거래량 가중 평균(VWAP)으로 합쳐 자기 보고값을 만든다. 한 거래소가 일시적으로 호가를 비틀어도 VWAP가 그 영향을 흡수한다.

정리하면 노드 내부에서는 VWAP가 단일 거래소 조작을 막고, 네트워크 차원에서는 중앙값이 비잔틴 노드와 노드 매수를 막는다. 어느 한 단계가 빠지면 공격 비용이 자릿수 단위로 떨어진다.

Optimistic Oracle

가격은 1초에 수십 번 바뀐다. 그래서 가격 오라클은 끊임없이 데이터를 갱신해야 한다.

그런데 “이번 미국 대선에서 누가 이겼나” 같은 이벤트는 결과가 한 번만 정해진다. 1초 안에 답할 필요가 없고, 대신 답을 검증할 시간이 충분하다.

UMA의 Optimistic Oracle이 이 영역을 노린다.

flowchart LR
    A[Asker: 질문 등록] --> B[Proposer: 답 제안 + 본드]
    B --> C{Liveness 기간<br/>2h ~ 2d}
    C -->|이의 없음| D[답 채택]
    C -->|Disputer 등장| E[DVM 투표]
    E --> F[UMA 토큰 holder<br/>commit-reveal]
    F --> G[정직측 본드 회수<br/>거짓측 본드 압수]

흐름은 단순하다.

  1. 누군가가 질문을 등록하고, Proposer가 답을 제안하면서 본드를 건다.
  2. 정해진 liveness 기간(보통 2시간~2일) 동안 아무도 이의를 제기하지 않으면 답이 채택된다.
  3. Disputer가 본드를 걸고 이의를 제기하면 DVM(Data Verification Mechanism)으로 넘어가 UMA 토큰 holder들이 투표한다.

핵심은 이의 제기에 본드가 필요하다는 점이다.

답이 명백하면 이의를 제기할 이유가 없다. 거짓말을 시도하려면 본드를 걸어야 하는데, 정직한 답이 통과되면 그 본드는 압수된다.

Polymarket이 가장 큰 사용자다. 시장에 걸린 베팅 결과가 정해지면 누군가 답을 제안하고, 이의가 없으면 그대로 정산된다. 가격 오라클이 가질 수 없는 검증 시간을 확보하는 대신, 신선도를 포기한 모델이다.

가격 피드와 Optimistic Oracle은 같은 문제를 푸는 게 아니다. 시간 압력이 다른 두 도메인을 위한 두 도구다.

VRF

오라클이 가져오는 게 가격뿐인 건 아니다.

체인 위 게임이나 NFT 발행에서는 검증 가능한 난수가 필요하다. 그런데 블록체인 위에서 난수를 만들기는 까다롭다. block.timestamp나 블록 해시를 시드로 쓰면 채굴자나 시퀀서가 결과를 미리 알고 조작할 수 있다.

Chainlink VRF는 이 문제를 검증 가능 난수 함수(Verifiable Random Function)로 푼다.

오라클이 비밀키로 입력값을 서명해 난수를 만들고, 그 결과와 함께 cryptographic proof를 컨트랙트에 올린다. 컨트랙트는 proof를 공개키로 검증해 난수가 정해진 입력에 대해 정직하게 만들어졌음을 확인한다.

오라클이 결과를 미리 알아도 입력을 마음대로 고를 수는 없다. 입력은 사용자가 정하기 때문이다. 결과는 입력에서 결정적으로 나오지만, 누구도 미리 그 결과를 알 수 없다.

NFT 민팅 순서, 게임 가챠, 추첨처럼 결과의 공정성이 신뢰의 핵심인 곳에 VRF가 쓰인다.

Oracle Manipulation

오라클이 DeFi의 미들웨어가 되면서, 그 자체가 가장 큰 공격 표면이 됐다.

2024~2025년 DeFi 손실 중 오라클 조작이 차지한 비중이 4억 달러를 넘는다. 공격은 거의 같은 패턴을 따른다.

  1. 공격자가 flash loan으로 거대한 자본을 빌린다.
  2. 그 자본으로 한 거래소나 AMM의 가격을 일시적으로 비튼다.
  3. 비뚤어진 가격을 오라클이 그대로 가져온다.
  4. 비뚤어진 가격으로 청산이나 차입 한도를 조작해 차익을 챙긴다.
  5. flash loan을 갚는다. 모두 한 트랜잭션 안에서 일어난다.

이 공격이 통하는 이유는 단순하다. 현재가는 한 시점의 한 거래소 가격일 뿐이고, flash loan으로 그 가격을 흔드는 비용이 빌린 자본의 수수료 수준에 불과하기 때문이다.

표준 방어는 TWAP(Time-Weighted Average Price)다.

TWAP(T)=1Tt0t0+TP(t)dt\text{TWAP}(T) = \frac{1}{T} \int_{t_0}^{t_0 + T} P(t)\,dt

일정 시간 TT의 가격을 평균 낸다. 한 시점의 가격을 비트는 비용이 자본의 수수료 수준이라면, TT 시간 동안 그 가격을 유지하는 비용은 자본을 그 시간만큼 묶어두는 기회비용으로 폭발한다.

방어 기법막는 공격비용
다중 데이터 소스단일 거래소 가격 조작노드별 데이터 비용 증가
다중 노드 + 중앙값단일 노드 매수노드 운영 비용
TWAPflash loan 단일 블록 조작가격 신선도 희생
Circuit breaker비정상 가격 진입가격이 정말 빠르게 움직일 때 컨트랙트 멈춤

오라클 보안은 이 네 층의 결합이다. 어느 한 층이 빠지면 공격 비용이 자릿수 단위로 떨어진다.

정리

정리하면 오라클이 푸는 문제는 한 줄이다.

결정적인 닫힌 시스템 안에서, 비결정적인 외부 데이터를 안전하게 쓰려면 어떻게 해야 하는가.

답은 데이터 자체를 합의의 대상으로 만드는 것이다. 외부에서 가져온 데이터를 한 번 더 합의에 통과시키고, 그 합의된 단일 값에 대해서만 본 합의를 돌린다.

이 추가 합의를 어떻게 설계하느냐가 오라클을 가른다.

  • 누가 데이터를 게시하는가 (독립 노드 vs 거래소 직접)
  • 언제 체인에 올리는가 (Push vs Pull)
  • 어떻게 단일 값으로 합치는가 (중앙값 vs 가중 평균 vs propose-dispute)
  • 어떻게 조작을 막는가 (다중화, TWAP, 본드)

DeFi가 처리하는 자본이 커질수록 오라클의 정확성과 신선도, 그리고 공격 비용이 시스템 안전의 한계를 결정한다. 그래서 오라클의 설계는 계속 갱신된다.

References