본문으로 건너뛰기
이 페이지는 영문에서 기계 번역되었으므로 오역이나 어색한 표현이 있을 수 있습니다. 따라서 정확한 정보는 영어 원문을 참조하시기 바랍니다. 또한 잦은 업데이트로 인해 일부 콘텐츠는 영문이 그대로 남아있을 수 있습니다. Crowdin에서 이 페이지의 번역을 개선하는 데 동참하여 도움을 주세요. (Crowdin translation page, Contributing guide)

Pyth를 사용하여 Kaia에서 실시간 가격 가져오기 방법

소개​

Pyth는 주로 푸시 기반 오라클로 구동되는 생태계에서 독특한 접근 방식을 취하는 탈중앙화 오라클 네트워크입니다. 고정된 간격으로 데이터를 계약에 푸시하는 대신 Pyth를 사용하면 필요에 따라 실제 데이터를 가져올 수 있습니다. 이 모델은 개발자에게 더 많은 제어권을 부여하고 불필요한 온체인 업데이트를 방지하는 데 도움이 됩니다. 이 통합을 통해 개발자는 실시간 데이터를 가져오고 업데이트가 요청된 경우에만 요금이 적용되는 사용량 기반 유료 모델을 사용할 수 있습니다.

이 가이드에서는 Pyth의 실시간 가격 피드를 사용하여 법정 화폐인 IDR의 가치를 읽는 방법을 알아보세요. 솔리디티 스마트 컨트랙트는 pyth-sdk-solidity를 사용하여 Pyth에서 USD/IDR 가격을 검색하고, hermes-client를 사용하여 최신 가격을 업데이트하고 가져옵니다.

빠르게 시작하려면 이 튜토리얼의 전체 코드를 GitHub에서 확인할 수 있습니다. 이는 바로 사용할 수 있는 참조를 제공하며 프로젝트와 설치를 더 빠르게 설정하는 데 도움이 됩니다.

전제 조건​

시작하기 전에 다음 사항이 준비되어 있는지 확인하세요:

  • Node.js 및 npm

    종속성을 설치하고 개발 도구를 실행하는 데 필요합니다.

  • KAIA 테스트넷 토큰으로 자금을 조달한 지갑입니다.

    카이로스 테스트넷의 배포 및 트랜잭션 가스 수수료를 지불하려면 KAIA가 필요합니다. 카이아 수도꼭지](https://faucet.kaia.io/)에서 무료 테스트넷 KAIA를 신청할 수 있습니다.

개발 환경 설정​

이 섹션에서는 개발 환경을 설정하고, 오라클 컨트랙트를 컴파일하고, Hardhat을 사용하여 배포할 수 있도록 준비합니다.

1. 하드햇 프로젝트 만들기

프로젝트의 새 디렉터리를 만들고 하드햇을 초기화합니다:


mkdir pyth-kaia-hardhat-example && cd pyth-kaia-hardhat-example
npm init -y
npx hardhat@next --init

메시지가 표시되면 기본 응답을 수락합니다. 이 가이드에서는 모카 및 이더 템플릿을 사용합니다.

하드햇 버전을 확인하여 설치를 확인합니다:


npx hardhat --version

2. 암호화된 비밀 설정

이제 하드햇의 암호화된 키 저장소를 사용하여 RPC URL과 개인 키를 저장합니다.

다음 명령을 실행합니다:


npx hardhat keystore set KAIROS_RPC_URL
npx hardhat keystore set PRIVATE_KEY

각 변수에 대한 비밀번호와 값을 입력하여 암호화된 상태로 유지하세요.

3. 구성 파일의 참조 비밀

hardhat.config.ts`를 열고 네트워크 섹션을 업데이트하여 암호화된 비밀번호를 참조하세요. 다른 비밀 이름을 사용했다면 그에 따라 키를 업데이트하세요.


import { configVariable } from "hardhat/config";
module.exports = {
networks: {
kairos: {
url: configVariable("KAIROS_RPC_URL"),
accounts: [configVariable("PRIVATE_KEY")],
},
},
};

계약 생성 및 파이썬 오라클에서 가격 가져오기​

이 섹션에서는 파이스 솔리디티 SDK를 설치하고, PriceConsumer 컨트랙트를 생성한 후, 하드햇을 사용하여 배포합니다. 계약은 나중에 Hermes에서 가져온 가격 데이터를 사용하여 업데이트할 Pyth 가격 피드를 읽습니다.

Pyth SDK 설치​

파이스는 온체인 파이스 가격 피드 콘트랙트와 상호작용할 수 있는 솔리디티 SDK를 제공합니다. SDK는 IPyth 인터페이스와 관련 구조를 노출합니다.

npm으로 SDK를 설치합니다:


npm install --save-dev @pythnetwork/pyth-sdk-solidity

PriceConsumer 컨트랙트 생성​

계약/가격소비자.sol`에 새 파일을 만들고 다음 코드를 추가합니다:


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol";
contract PriceConsumer {
IPyth public pyth;
constructor(address pythContract) {
pyth = IPyth(pythContract);
}
function updatePrice(bytes[] calldata priceUpdateData)
external
payable
{
// Pay the Pyth fee for receiving price updates
uint fee = pyth.getUpdateFee(priceUpdateData);
require(msg.value >= fee, "Not enough fee sent");
// Update the Pyth price state
pyth.updatePriceFeeds{value: fee}(priceUpdateData);
// Can fetch the price and use it as well
//PythStructs.Price memory currentBasePrice = pyth.getPriceNoOlderThan(priceFeedId, 60);
}
function getLatestPrice(bytes32 priceFeedId) public view returns (int64, int32) {
// Read the current price from a price feed if it is less than 60 seconds old.
// Each price feed (e.g., USD/IDR) is identified by a price feed ID.
// The complete list of feed IDs is available at https://docs.pyth.network/price-feeds/price-feeds
PythStructs.Price memory currentBasePrice = pyth.getPriceNoOlderThan(priceFeedId, 60);
// uint256 basePrice = PythUtils.convertToUint(
// currentBasePrice.price,
// currentBasePrice.expo,
// 18
// );
return (currentBasePrice.price, currentBasePrice.expo);
}
}

워크스루

PriceConsumer 계약:

  • Pyth 인터페이스와 구조체를 @pythnetwork/pyth-sdk-solidity에서 가져옵니다.
  • 스토어:
    • 파이스 컨트랙트 인스턴스(pyth)입니다.
    • USD/IDR의 가격 피드 ID(usdIdrPriceId)입니다.
  • updateAndGetUsdIdrPrice`를 노출합니다:
    • IPyth.getUpdateFee를 사용하여 업데이트 수수료를 계산합니다.
    • 필요한 수수료와 함께 IPyth.updatePriceFeeds를 호출합니다.
    • 새로운 USD/IDR 가격을 확인하려면 IPyth.getPriceNoOlderThan을 호출하세요.
    • 원시 가격, 지수, 게시 시간을 반환합니다.

나중에 오프체인 헤르메스 클라이언트는 가격 업데이트 바이트 배열을 생성하고 새로운 가격이 필요할 때 이 함수에 전달합니다.

계약서 컴파일​

다음 명령을 실행하여 컨트랙트를 컴파일합니다:


npx hardhat compile

컨트랙트 배포​

PriceConsumer 컨트랙트를 배포하려면 Ignition 모듈을 생성한 다음 배포 명령을 실행합니다.

이그니션 모듈 만들기

'ignition/modules/PriceConsumer.ts'에 새 파일을 생성합니다:


import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
const pythContractAddress = "0x2880ab155794e7179c9ee2e38200202908c17b43";
export default buildModule("PriceConsumerModule", (m) => {
const priceConsumer = m.contract("PriceConsumer", [pythContractAddress]);
return { priceConsumer };
});

계약 배포

이그니션 모듈을 사용하여 PriceConsumer 컨트랙트를 카이로스 테스트넷에 배포합니다:


npx hardhat ignition deploy --network kairos ignition/modules/PriceConsumer.ts

메시지가 표시되면 앞서 암호화된 비밀에 대해 구성한 키 저장소 비밀번호를 입력합니다.

이 작업이 완료되면 PriceConsumer.sol 컨트랙트가 카이로스 테스트넷에 배포되고 파이스로부터 실시간 USD/IDR 가격을 사용할 준비가 된 것입니다.

타입스크립트에서 상호 작용​

이 마지막 단계에서는 TypeScript를 사용하여 배포된 PriceConsumer 컨트랙트와 상호 작용합니다. 이 스크립트는 헤르메스 클라이언트를 통해 파이스 가격 업데이트 데이터를 요청하고 이를 온체인으로 전송하여 최신 USD/IDR 가격을 가져옵니다.

종속성 설치

필요한 패키지를 설치합니다:


npm install --save-dev tsx @pythnetwork/hermes-client @dotenv

.env 설정

프로젝트의 루트 디렉터리에 .env 파일을 만들고 개인 키를 추가합니다:


PRIVATE_KEY="0xDEAD....." // REPLACE WITH YOUR PRIVATE KEY

인터랙션 스크립트 만들기

스크립트/인터랙트.ts**에 새 파일을 만들고 다음을 추가합니다:


import { HermesClient } from "@pythnetwork/hermes-client";
import { ethers } from "ethers";
import 'dotenv/config'
// 1. Setup
const hermes = new HermesClient("https://hermes.pyth.network");
const provider = new ethers.JsonRpcProvider(
"https://public-en-kairos.node.kaia.io"
);
const PK = process.env.PRIVATE_KEY;
const wallet = new ethers.Wallet(PK, provider);
// 2. Your deployed contract
const priceConsumerAddress = "0x91e89aa32224dEd5dA483a83a4de45bF4bE57caA"; // REPLACE WITH DEPLOYED PRICE CONSUMER CONTRACT
const priceConsumerAbi = [
"function updatePrice(bytes[] priceUpdateData) external payable",
"function getLatestPrice(bytes32 priceId) public view returns(int64, int32)",
];
const priceConsumer = new ethers.Contract(
priceConsumerAddress,
priceConsumerAbi,
wallet
);
// 3. Price feed IDs
const priceId =
"0x6693afcd49878bbd622e46bd805e7177932cf6ab0b1c91b135d71151b9207433"; // FX.USD/IDR Beta Price Feed ID
async function run() {
// Fetch Hermes price update binary
const update = await hermes.getLatestPriceUpdates([priceId], {
encoding: "hex",
});
console.log(update);
const priceUpdateData = ["0x" + update.binary.data]; // must be array of bytes
console.log(priceUpdateData);
// Estimate fee required by Pyth contract
// EVM Network Price Feed Contract Addresses: https://docs.pyth.network/price-feeds/core/contract-addresses/evm
const pythContractAddress = "0x2880ab155794e7179c9ee2e38200202908c17b43";
const pythAbi = [
"function getUpdateFee(bytes[] calldata data) external view returns(uint)",
];
console.log("Pyth contract address:", pythContractAddress);
const pyth = new ethers.Contract(pythContractAddress, pythAbi, wallet);
const fee = await pyth.getUpdateFee(priceUpdateData);
console.log("Pyth fee:", fee.toString());
// Call your contract
const tx = await priceConsumer.updatePrice(priceUpdateData, {
value: fee, // pay the pyth update fee
gasLimit: 500000,
});
console.log("Tx sent:", tx.hash);
const receipt = await tx.wait();
console.log("Tx confirmed");
console.log(receipt);
// 4. Get latest price from contract
try {
console.log("=== Latest Price from Contract ===");
const [price, expo] = await priceConsumer.getLatestPrice(priceId);
console.log("Price Value : " + price.toString());
console.log("Exponent Value : " + expo.toString());
} catch (error) {
console.log(error);
// @ts-ignore
console.error("\nError calling getLatestPrice:", error.message);
console.log(
"This usually means the price is older than 60 seconds or hasn't been updated yet."
);
console.log("Make sure updatePrice() was called successfully first.");
}
}
run();

스크립트 실행

스크립트를 실행합니다:


npx tsx scripts/interact.ts

출력 예시


Tx sent: 0x79c5dcb7abd9605b070bf9062ba2e2382272d23d58f7b50446c3107b7784fc8e
Tx confirmed
=== Latest Price from Contract ===
Price Value : 1669784988
Exponent Value : -5
======== —— =========

거래 해시를 검색창에 붙여넣어 카이로스 탐색기에서 거래를 확인할 수 있습니다. 이렇게 하면 업데이트 및 읽기 작업이 성공했음을 확인할 수 있습니다.

결론​

이 튜토리얼에서는 파이스에서 실시간 가격을 읽는 솔리디티 컨트랙트를 생성하고, 이를 카이로스 테스트넷에 배포한 다음, 헤르메스 클라이언트를 사용해 상호작용했습니다. 또한 Pyth의 풀 기반 설계를 통해 가격 업데이트 시기와 방법을 제어하는 방법도 배웠습니다.

자세한 내용은 탐색하기에서 확인하세요:

페이지를 개선해 주세요