체인링크 오라클 시리즈(1부)

avatar
ZAN Team
1주 전
이 글은 약 3254자,전문을 읽는 데 약 5분이 걸린다
블록체인 분야에서 오라클은 온체인 스마트 계약에 외부 정보를 제공할 수 있는 시스템입니다. 스마트 계약과 블록체인 외부 세계를 연결하는 미들웨어로서 오라클은 매우 중요한 인프라 역할을 합니다. 주요 기능은 블록체인의 스마트 계약에 대한 데이터를 제공하는 것입니다.

블록체인 분야에서 오라클은 온체인 스마트 계약에 외부 정보를 제공할 수 있는 시스템입니다. 스마트 계약과 블록체인 외부 세계를 연결하는 미들웨어로서 오라클은 매우 중요한 인프라 역할을 합니다. 주요 기능은 블록체인의 스마트 계약에 대한 데이터를 제공하는 것입니다.

예를 들어, 이더리움 네트워크에서 스마트 계약을 생성하고, 이 계약이 특정 날짜의 원유 거래량 데이터에 액세스해야 한다고 가정해 보겠습니다. 하지만 스마트 계약 자체는 이러한 오프체인 실제 데이터를 얻을 수 없으므로 오라클을 통해 구현해야 합니다. 이 경우, 스마트 계약은 필요한 날짜의 원유 거래량을 이벤트 로그에 기록합니다. 그런 다음 이벤트 로그를 모니터링하고 구독하기 위한 오프체인 프로세스가 시작됩니다. 거래에서 요청이 감지되면 프로세스는 체인상 거래를 제출하고, 계약의 관련 메서드를 호출하고, 지정된 날짜의 원유 거래량 정보를 스마트 계약에 업로드합니다.

체인링크 오라클 시리즈(1부)

https://defillama.com/oracles에서 가져온 데이터

체인링크

블록체인에서 체인링크 오라클은 가장 큰 시장 점유율을 가지고 있습니다. 체인링크는 실제 세계에서 생성된 데이터를 가장 안전한 방식으로 블록체인에 제공하는 역할을 하는 분산형 오라클 프로젝트입니다. Chainlink는 기본적인 오라클 원칙을 구현하여 경제적 인센티브를 통해 LINK 토큰을 중심으로 선순환 생태계를 구축했습니다. Chainlink 오라클은 LINK 토큰의 전송을 통해 트리거되어야 합니다. LINK는 이더리움 네트워크의 ERC 677 계약입니다. LINK ERC 677 토큰을 기반으로 하는 오라클 함수는 요청/응답 모드에 속합니다.

ERC 677 토큰의 transferAndCall

체인링크 오라클 시리즈(1부)

오라클은 본질적으로 서비스를 제공하는 당사자입니다. ChainLink가 오라클 프레임워크를 설계할 때 가장 먼저 떠올린 것은 오라클 사용자가 서비스를 제공하는 오라클에 서비스 수수료를 어떻게 지불할 수 있을까 하는 것이었습니다. 그러나 표준 동종 토큰 계약 ERC 20은 결제 후 서비스 제공에 대한 수요를 충족할 수 없기 때문에 ChainLink는 오라클 서비스 시나리오에 적합한 표준인 ERC 677을 제안했습니다.

위 코드에서 볼 수 있듯이 ERC 677은 실제로 표준 ERC 20을 기반으로 transferAndCall 메서드를 추가합니다. 이 메서드는 결제와 서비스 요청을 하나로 결합하여 오라클 비즈니스 시나리오의 요구 사항을 충족합니다.

체인링크 오라클 시리즈(1부)

사용자가 자금을 이체하기 위해 transferAndCall을 수행하는 경우, ERC 20 전송 외에도 수신 주소가 계약 주소인지 여부도 판별합니다. 그렇다면 to 주소의 onTokenTransfer 메서드가 호출됩니다. (여기서 ERC 677 Receiver는 onTokenTransfer라는 하나의 메서드만 갖습니다.)

LINK 토큰의 계약 소스 코드를 보려면 Etherscan으로 이동하세요: https://etherscan.io/address/0x514910771af9ca656af840dff83e8264ecf986ca#code

체인링크 오라클 시리즈(1부)

구현 중에 _to 주소를 여러 번 검증하는 것 외에도 LINK 토큰은 실제로 ERC 677의 transferAndCall 메서드를 상속받는 것을 볼 수 있습니다. 참고: 오라클 서비스를 요청하기 전에 오라클이 신뢰할 수 있는지 확인하세요. 오라클은 소비자에게 서비스를 제공하기 전에 결제를 요구하기 때문입니다. (누구나 오라클 서비스를 제공할 수 있습니다)

체인링크 오라클 시리즈(1부)

Oracle 신뢰성 분류

온체인 오라클 요청

Oracle 계약의 onTokenTransfer 메서드가 어떻게 구현되는지 살펴보겠습니다.

체인링크 오라클 시리즈(1부)

오라클 소비자가 transferAndCall 메서드를 사용하여 수수료를 지불하고 오라클 서비스를 요청하는 경우, 여기의 주소는 요청된 오라클의 주소입니다. Oracle의 onTokenTransfer 메서드는 먼저 전송이 LINK 토큰(onlyLINK)인지 확인합니다. 이는 실제로 msg.sender가 LINK 토큰 계약의 주소인지 여부를 확인하기 위한 것입니다. 그런 다음 _data의 길이가 최대 한도를 초과하는지 여부를 판별합니다. 마지막으로, _data에 oracleRequest로 시작하는 함수 선택자가 있는지 확인합니다. 물론, 여기의 기능 선택기는 오라클이 제공하는 서비스에 맞게 사용자 정의할 수 있습니다. 반드시 oracleRequest일 필요는 없습니다. 이는 오라클이 어떤 종류의 인터페이스를 노출하는지에 따라 달라집니다.

이러한 모든 수정자가 전달되면 현재 함수 호출자와 전송량이 _data에 있는 것과 같은지 확인합니다. 모든 보안 검사를 통과한 후, 현재 오라클 계약은 delegatecall을 통해 호출됩니다. 물론, _data에서 함수 선택기를 이미 확인했으므로 실제로 호출되는 것은 oracleRequest 메서드입니다.

체인링크 오라클 시리즈(1부)

먼저, 오라클 요청자와 그가 보낸 nonce를 연결하여 해시하여 이 요청에 대한 requestId를 만들고, 커밋 매핑을 검사하여 고유한 ID인지 확인합니다. 모든 것이 괜찮다면 만료 시간을 설정하고, 커밋에 requestId를 추가하고, _payment, _callbackAddress, _callbackFunctionId 및 expiration을 값으로 연결합니다. 가장 중요한 점은 요청 데이터 _data를 포함하는 OracleRequest 이벤트가 발행된다는 것입니다. 이 데이터는 간결한 이진 객체 표현(CBOR) 데이터입니다. 이 인코딩 형식은 가볍고 간결하며, 간단히 이진 JSON 형식으로 이해할 수 있습니다. 이러한 데이터는 오프체인 노드가 어떻게 설계되었는지에 따라 다양한 형태가 될 수 있습니다.

예를 들어, Chainlink: ETH/USD Aggregator에는 OracleRequest 이벤트가 포함된 트랜잭션이 있습니다.

체인링크 오라클 시리즈(1부)

OracleRequest 이벤트 예제

이 이벤트를 통해 ETH/USD 가격 집계기 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F가 오라클에 가격 데이터 요청(0x7e94a8a23687d8c7058ba5625db2ce358bcbd244)을 보낸다는 것을 알 수 있습니다. 오라클이 요청한 데이터를 반환하면 반환된 계약 주소(0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F), 호출할 메서드 ID(6 A 9705 B 4), 만료 시간(1618185924)을 확인할 수 있습니다.

오프체인 노드 응답

3.1 체인 밖에서 fulfillOracleRequest 호출

체인링크 오라클 시리즈(1부)

첫 번째 확인:

  • onlyAuthorizedNode: 함수 호출자(msg.sender)는 계약 소유자이거나 승인 목록에 있어야 합니다.

  • isValidRequest: 커밋 매핑에 requestId가 있는지 여부를 계속 확인합니다.

  • payment, callbackAddress, _callbackFunctionId, expiration을 연결하고, 이것들이 commitments 맵의 requestId에 해당하는 값인지 확인합니다.

이러한 모든 검사를 통과하면 이 요청 비용이 인출 가능 토큰에 추가되어 인출 가능한 금액을 기록합니다. 그런 다음 _requestId가 커밋 맵에서 제거됩니다. 마지막으로, 요청을 발행한 계약의 콜백 함수를 실행하는 데 필요한 최소 가스 양인 MINIMUM_CONSUMER_GAS_LIMIT보다 남은 가스 양을 계산합니다.

위의 모든 검사를 통과하면 요청자 계약의 콜백 함수는 call 형태로 정식으로 호출될 수 있습니다.

요청에 대한 응답은 가능한 한 빨리 이루어져야 하므로, 응답 속도를 높이기 위해 ZAN의 노드 서비스( https://zan.top/home/node-service?chInfo=ch_WZ )를 사용하는 것이 좋습니다. 오프체인으로 트랜잭션을 전송하는 속도를 높이려면 노드 서비스 콘솔에서 해당 RPC 링크를 찾을 수 있습니다.

체인링크 오라클 시리즈(1부)

3.2 콜백 함수

우리는 이전에 oracleRequest에서 콜백 함수 ID가 6 A 9705 B 4이고 메서드가 chainlinkCallback(bytes 32, int 256임을 알게 되었습니다.

체인링크 오라클 시리즈(1부)

체인링크 오라클 시리즈(1부)

validateChainlinkCallback은 사용자 정의가 가능한 함수입니다. 다음은 수정자입니다.

체인링크 오라클 시리즈(1부)

pendingRequests에서 _requestId가 요청된 oracle과 일치하는지 확인합니다. 그리고 ChainlinkFulfilled 이벤트를 내보냅니다.

체인링크 오라클 시리즈(1부)

모든 검사를 통과하면 응답을 추가로 처리하여 답변 매핑을 업데이트할 수 있습니다. 가격 오라클인 경우 응답된 가격 데이터는 currentPrice에 할당되어 해당 가격 업데이트가 수행됩니다.

체인링크 오라클 시리즈(1부)

위는 일반 오라클 서비스의 전체 프로세스입니다.

Chainlink에서 제공하는 TestnetConsumer 계약의 requestEthereumPrice 메서드를 예로 들어 가격 오라클 요청 응답 프로세스를 간략하게 설명해 보겠습니다. 이 함수는 다음과 같이 정의됩니다.

체인링크 오라클 시리즈(1부)

이 함수가 구현하는 기능은 지정된 API(cryptocompare)에서 ETH/USD의 거래 가격을 얻는 것입니다. 함수에 전달되는 매개변수는 지정된 Oracle 주소와 jobId입니다. 일련의 요청 매개변수를 설정한 후 sendChainlinkRequestTo 메서드를 호출하여 요청을 보냅니다. sendChainlinkRequestTo는 Chainlink에서 제공하는 라이브러리에 정의된 인터페이스 메서드이며, 다음과 같이 정의됩니다.

체인링크 오라클 시리즈(1부)

전송을 수신한 후 Oracle 계약은 onTokenTransfer 메서드를 트리거하여 전송의 유효성을 확인하고 OracleRequest 이벤트를 발행하여 더 자세한 데이터 정보를 기록합니다.

이 로그는 오라클 계약 로그에서 찾을 수 있습니다. 체인 아래의 노드는 주제의 로그를 구독합니다. 기록된 로그 정보를 얻은 후, 노드는 요청의 구체적인 정보를 구문 분석하고 네트워크 API 호출을 통해 요청의 결과를 얻습니다. 그런 다음 트랜잭션을 제출하여 Oracle 계약에서 fulfillOracleRequest 메서드를 호출하여 체인에 데이터를 제출합니다.

일련의 검사를 수행한 후, 이 메서드는 이전에 기록된 콜백 주소와 콜백 함수를 통해 결과를 소비자 계약으로 반환합니다.

개발자로서 저는 이러한 URL을 직접 지정하지 않고 기존 통화 쌍 가격만 사용하고 싶습니다. 그게 가능할까요?

대답은 예입니다. 첫 번째 사용 방법은 다음과 같습니다.

체인링크 오라클 시리즈(1부)

첫째, 각 거래 쌍에는 별도의 가격 피드(Aggregator라고도 함)가 있습니다. 이는 실제로는 아래에 표시된 대로 AggregatorProxy입니다.

체인링크 오라클 시리즈(1부)

이 인터페이스의 구체적인 구현은 비교적 간단합니다. AAVE/ETH 쌍을 참조할 수 있습니다: https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012#code

총 5가지 쿼리 방법이 있습니다.

  • decimals(): 반환된 가격 데이터의 정밀도 자릿수(일반적으로 8 또는 18)

  • description(): 일반적으로 ETH/USD와 같은 거래 쌍의 이름입니다.

  • version(): 주로 프록시가 가리키는 Aggregator의 유형을 식별하는 데 사용됩니다.

  • getRoundData(_roundId): 라운드 ID를 기반으로 현재 가격 데이터를 가져옵니다.

  • latestRoundData(): 최신 가격 데이터를 가져옵니다

대부분의 애플리케이션 시나리오에서 계약은 최신 가격만 읽어야 할 수도 있습니다. 즉, 마지막 메서드를 호출하고 반환 매개변수의 답은 최신 가격입니다.

또한, 대부분의 애플리케이션은 토큰을 읽는 데 측정 단위로 USD를 사용합니다. 그렇다면 USD로 표시된 통화쌍의 정밀도는 모두 8자리이므로 일반적으로 토큰마다 다른 정밀도 문제를 처리할 필요가 없습니다.

이 글은 ZAN Team(X 계정 @zan_team )의 XiG(X 계정 @SHXiGi )가 작성했습니다.

창작 글, 작자:ZAN Team。전재 / 콘텐츠 제휴 / 기사 요청 연락처 report@odaily.email;违규정 전재 법률은 반드시 추궁해야 한다.

ODAILY는 많은 독자들이 정확한 화폐 관념과 투자 이념을 수립하고 블록체인을 이성적으로 바라보며 위험 의식을 확실하게 제고해 달라고 당부했다.발견된 위법 범죄 단서에 대해서는 관련 부서에 적극적으로 고발하여 반영할 수 있다.

추천 독서
편집자의 선택