Cryptocompare GET /data/pricemultifull API를 호출하기 위해 탈중앙화 오라클 네트워크에 요청을 보내는 방법을 안내합니다.
OCR이 오프체인 계산과 집계를 완료하면, ETH/USD의 자산 가격을 스마트 계약으로 반환합니다.
HTTP 쿼리 매개변수를 구성하여 다른 자산 가격을 요청하는 방법도 보여줍니다.
시작하기 전에
사전 준비
링크에 있는 내용을 해보고, 준비하셔야 지금 페이지의 내용을 따라 올 수 있습니다.
Chainlink Functions Starter Kit의 tutorials 브랜치로 깃 체크아웃해야합니다.
git checkout tutorials
예제는 /tutorials/2-call-api directory 에 위치해 있습니다.
이 튜토리얼은 ETH/USD 가격을 가져오도록 구성되어 있습니다. 코드 예제에 대한 자세한 설명은 "설명" 섹션을 읽어보세요.
먼저, config.js 파일을 열어보세요. args 값은 ["ETH", "USD"]로 설정되어 있으며, 이는 현재 ETH/USD 가격을 가져옵니다. 다른 자산 가격을 가져오기 위해 args를 수정할 수 있습니다. 지원되는 심볼 목록을 확인하려면 CryptoCompare API 문서를 참조하세요. 요청 구성 파일에 대한 자세한 설명은 요청 구성 설명을 읽어보세요.
그 다음, source.js를 열어 JavaScript 소스 코드를 분석하세요. 소스 코드에 대한 자세한 설명은 소스 코드 설명을 읽어보세요.
Chainlink Functions Hardhat Starter Kit에는 로컬 환경에서 코드를 테스트할 수 있는 시뮬레이터가 포함되어 있습니다. functions-simulate 명령을 사용하면 코드를 로컬에서 실행하고, 엔드 투 엔드 플루필먼트를 시뮬레이션할 수 있습니다. 이를 통해 Decentralized Oracle Network에 함수를 제출하기 전에 문제를 미리 해결할 수 있습니다.
functions-simulate 태스크를 실행하여 소스 코드가 올바르게 작성되었는지 확인해보세요.
이때 config.js와 source.js 파일이 정확하게 작성되어 있는지 확인해야 합니다.
npx hardhat functions-simulate --configpath REPLACE_CONFIG_PATH
Example
$ npx hardhat functions-simulate --configpath tutorials/2-call-api/config.js
secp256k1 unavailable, reverting to browser version
__Compiling Contracts__
Nothing to compile
Duplicate definition of Transfer (Transfer(address,address,uint256,bytes), Transfer(address,address,uint256))
Executing JavaScript request source code locally...
__Console log messages from sandboxed code__
HTTP GET Request to https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD
ETH price is: 1813.50 USD
__Output from sandboxed source code__
Output represented as a hex string: 0x000000000000000000000000000000000000000000000000000000000002c466
Decoded as a uint256: 181350
__Simulated On-Chain Response__
Response returned to client contract represented as a hex string: 0x000000000000000000000000000000000000000000000000000000000002c466
Decoded as a uint256: 181350
Gas used by sendRequest: 367881
Gas used by client callback function: 75029
위의 예시 출력을 읽으면 ETH/USD 가격을 확인할 수 있습니다. 하지만 Solidity는 소수를 지원하지 않기 때문에, 이를 정수처럼 보이도록 소수점을 이동시켜 181350과 같은 정수 형태로 반환합니다. 그런 다음, 콜백에서는 해당 값을 바이트로 인코딩하여 0x000000000000000000000000000000000000000000000000000000000002c466과 같은 값으로 반환합니다. 소스 코드에 대한 자세한 설명은 소스 코드 설명을 참조하세요.
각 튜토리얼은 별도의 Git 브랜치에 있으며 일부는 .env.enc 파일에 고유한 항목이 필요합니다.
Decentralized Oracle Network에 자산 가격을 가져오기 위해 요청을 보내세요. functions-request 작업을 실행하면서 subid (구독 ID)와 계약 매개변수를 함께 전달하세요. 이 작업은 함수 JavaScript 소스 코드, 인수 및 비밀 정보를 배포된 FunctionsConsumer 계약의 executeRequest 함수에 전달합니다. FunctionsConsumer 섹션에서 소비자 계약에 대한 자세한 정보를 확인하세요.
npx hardhat functions-request --subid REPLACE_SUBSCRIPTION_ID --contract REPLACE_CONSUMER_CONTRACT_ADDRESS --network REPLACE_NETWORK --configpath REPLACE_CONFIG_PATH
Example
$ npx hardhat functions-request --subid 443 --contract 0x4B4BA2Fd6b93aDF8d6b6002E10540E58394388Ea --network polygonMumbai --configpath tutorials/2-call-api/config.js
secp256k1 unavailable, reverting to browser version
Estimating cost if the current gas price remains the same...
The transaction to initiate this request will charge the wallet (0x9d087fC03ae39b088326b67fA3C788236645b717):
0.000496339505294288 MATIC, which (using mainnet value) is $0.0005516547067031669
If the request's callback uses all 100,000 gas, this request will charge the subscription:
0.200148503810857266 LINK
Continue? Enter (y) Yes / (n) No
y
Simulating Functions request locally...
__Console log messages from sandboxed code__
HTTP GET Request to https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD
ETH price is: 1813.96 USD
__Output from sandboxed source code__
Output represented as a hex string: 0x000000000000000000000000000000000000000000000000000000000002c494
Decoded as a uint256: 181396
⣾ Request 0x5e89f3e84cbf80d65de53de816052d1b79c50c1f1f9f283aadc3ad36d33d41aa has been initiated. Waiting for fulfillment from the Decentralized Oracle Network...
ℹ Transaction confirmed, see https://mumbai.polygonscan.com/tx/0x36029c2e49d0d890d00a1b554e4bea564444e48c5449f9d5deaed5d42114d91e for more details.
✔ Request 0x5e89f3e84cbf80d65de53de816052d1b79c50c1f1f9f283aadc3ad36d33d41aa fulfilled! Data has been written on-chain.
Response returned to client contract represented as a hex string: 0x000000000000000000000000000000000000000000000000000000000002c48b
Decoded as a uint256: 181387
Actual amount billed to subscription #443:
┌──────────────────────┬─────────────────────────────┐
│ Type │ Amount │
├──────────────────────┼─────────────────────────────┤
│ Transmission cost: │ 0.000063268449037502 LINK │
│ Base fee: │ 0.2 LINK │
│ │ │
│ Total cost: │ 0.200063268449037502 LINK │
└──────────────────────┴─────────────────────────────┘
위의 예시 출력에서 다음과 같은 정보를 얻을 수 있습니다:
언제든지 contract 매개변수와 함께 functions-read 작업을 실행하여 최신 응답을 확인할 수 있습니다.
npx hardhat functions-read --contract REPLACE_CONSUMER_CONTRACT_ADDRESS --network REPLACE_NETWORK --configpath REPLACE_CONFIG_PATH
Example
$ npx hardhat functions-read --contract 0x4B4BA2Fd6b93aDF8d6b6002E10540E58394388Ea --network polygonMumbai --configpath tutorials/2-call-api/config.js
secp256k1 unavailable, reverting to browser version
Reading data from Functions client contract 0x4B4BA2Fd6b93aDF8d6b6002E10540E58394388Ea on network mumbai
On-chain response represented as a hex string: 0x000000000000000000000000000000000000000000000000000000000002c48b
Decoded as a uint256: 181387
Chainlink Functions 소비자 컨트랙트를 작성하기 위해서는 컨트랙트에서 FunctionsClient.sol을 import해야 합니다. FunctionsClient.sol은 NPM 패키지로 제공되지 않기 때문에 프로젝트 내에서 다운로드하여 import해야 합니다.
import { Functions, FunctionsClient } from "./dev/functions/FunctionsClient.sol";
Chainlink Functions 요청을 생성하는 데 필요한 모든 함수를 사용하기 위해 Functions.sol 라이브러리를 사용합니다. 다음과 같이 Functions 라이브러리를 사용하도록 선언합니다.
using Functions for Functions.Request;
최신 요청 ID, 최신 수신 응답 및 최신 수신 오류(있는 경우)는 상태 변수로 정의됩니다. latestResponse 및 latestError는 동적 크기의 바이트 배열로 인코딩되므로 응답이나 오류를 읽으려면 여전히 디코딩해야 합니다.
bytes32 public latestRequestId;
bytes public latestResponse;
bytes public latestError;
콜백 중에 스마트 컨트랙트에서 발생하는 OCRResponse 이벤트를 정의합니다.
event OCRResponse(bytes32 indexed requestId, bytes result, bytes err);
컨트랙트를 배포할 때 네트워크에 대한 오라클 주소를 전달합니다.
constructor(address oracle) FunctionsClient(oracle)
언제든지 updateOracleAddress 함수를 호출하여 오라클 주소를 변경할 수 있습니다.
남은 두 가지 함수는 다음과 같습니다:
Functions.Request memory req;
req.initializeRequest(Functions.Location.Inline, Functions.CodeLanguage.JavaScript, source);
if (secrets.length > 0) {
req.addRemoteSecrets(secrets);
}
if (args.length > 0) req.addArgs(args);
sendRequest(req, subscriptionId, gasLimit);
latestRequestId = assignedReqID;
function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) public override {
latestResponse = response;
latestError = err;
emit OCRResponse(requestId, response, err);
}
자세한 설정에 대한 설명은 "Request Configuration" 섹션에서 확인할 수 있습니다. 이 예제에서의 설정은 다음과 같습니다:
예상 API 응답을 확인하려면 다음 URL을 브라우저에 직접 붙여넣거나 터미널에서 curl 명령을 실행할 수 있습니다:
curl -X 'GET' \
'https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD' \
-H 'accept: application/json'
응답은 다음 예시와 유사해야 합니다:
{
"RAW": {
"ETH": {
"USD": {
"TYPE": "5",
"MARKET": "CCCAGG",
"FROMSYMBOL": "ETH",
"TOSYMBOL": "USD",
"FLAGS": "2049",
"PRICE": 2867.04,
"LASTUPDATE": 1650896942,
"MEDIAN": 2866.2,
"LASTVOLUME": 0.16533939,
"LASTVOLUMETO": 474.375243849,
"LASTTRADEID": "1072154517",
"VOLUMEDAY": 195241.78281014622,
"VOLUMEDAYTO": 556240560.4621655,
"VOLUME24HOUR": 236248.94641103,
...
}
}
}
}
가격은 RAW,ETH,USD,PRICE에 위치합니다.
호환 가능한 JavaScript 소스 코드를 작성하는 방법에 대한 자세한 설명은 "JavaScript code" 섹션을 참조하세요. 이 JavaScript 소스 코드는 Functions.makeHttpRequest를 사용하여 HTTP 요청을 보냅니다. ETH/USD 가격을 요청하기 위해 소스 코드는 https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD URL을 호출합니다. Functions.makeHttpRequest 문서를 읽으면 다음 매개변수를 제공해야 함을 알 수 있습니다:
{
fsyms: fromSymbol,
tsyms: toSymbol
}
fromSymbol과 toSymbol 값은 args에서 가져옵니다. 자세한 내용은 "request config" 섹션을 참조하세요.
코드는 주석이 달려 있어 각 단계를 이해하는 데 도움이 되며, 자체 설명 가능합니다. 주요 단계는 다음과 같습니다:
https://docs.chain.link/chainlink-functions/tutorials/api-query-parameters#sourcejs