사용자 지정 오라클 컨트랙트 구축
요청-응답 흐름, 신뢰할 수 있는 업데이트 주체, 온체인 데이터 최신성 검증을 포함해 Solidity로 자체 오라클 패턴을 설계하고 구현하는 방법을 배웁니다.
사용자 지정 오라클 컨트랙트 구축은(는) CoddyKit의 무료 Blockchain Smart Contracts with Solidity 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Blockchain Smart Contracts with Solidity 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Blockchain Smart Contracts with Solidity 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Beyond Third-Party Oracles
Chainlink and similar networks cover common feeds, but sometimes you need data nobody else provides, like a proprietary API result. In those cases you build a custom oracle: an off-chain updater plus an on-chain contract that stores and serves the data.
The Two-Party Design
A custom oracle has two sides:
- Off-chain updater: a server that reads the external source and sends transactions.
- On-chain contract: stores the latest value and exposes a read function for other contracts.
A Minimal Storage Oracle
The simplest oracle just lets a trusted address write a value that anyone can read.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SimpleOracle {
address public updater;
uint256 public value;
uint256 public lastUpdated;
constructor() {
updater = msg.sender;
}
function setValue(uint256 newValue) external {
require(msg.sender == updater, 'not updater');
value = newValue;
lastUpdated = block.timestamp;
}
}Guarding the Updater
The single point of trust is the updater address. Protect it with access control and allow it to be rotated safely if a key is compromised.
function transferUpdater(address newUpdater) external {
require(msg.sender == updater, 'not updater');
require(newUpdater != address(0), 'zero address');
updater = newUpdater;
}Checking Data Freshness
Stale data is dangerous. Consumers should reject values older than a threshold using the stored lastUpdated timestamp.
uint256 public constant MAX_AGE = 1 hours;
function getFreshValue() external view returns (uint256) {
require(block.timestamp - lastUpdated <= MAX_AGE, 'stale data');
return value;
}Request-Response Pattern
For on-demand data, a consumer emits a request event. The off-chain updater watches for it and replies with the answer in a callback.
event DataRequested(uint256 indexed requestId, string query);
uint256 private nextId;
function requestData(string calldata query) external returns (uint256) {
uint256 id = nextId++;
emit DataRequested(id, query);
return id;
}Fulfilling a Request
The updater calls back with the result for a given request id. Store it keyed by id so the consumer can read it later.
mapping(uint256 => uint256) public answers;
mapping(uint256 => bool) public fulfilled;
function fulfill(uint256 requestId, uint256 result) external {
require(msg.sender == updater, 'not updater');
answers[requestId] = result;
fulfilled[requestId] = true;
}Reducing Single-Source Risk
One updater is one point of failure. To harden the oracle you can require multiple updaters to agree (an aggregation or median of submissions) before a value is accepted.
mapping(address => bool) public isUpdater;
mapping(address => uint256) public submitted;
address[] public updaters;
function submit(uint256 v) external {
require(isUpdater[msg.sender], 'not updater');
submitted[msg.sender] = v;
}Computing a Median
A median resists a single malicious updater better than an average. Collect submissions, sort them off-chain or with a small on-chain helper, and take the middle value.
function median(uint256[] memory data) internal pure returns (uint256) {
// assume data already sorted
uint256 n = data.length;
if (n % 2 == 1) return data[n / 2];
return (data[n / 2 - 1] + data[n / 2]) / 2;
}Trust Tradeoffs
Custom oracles trade decentralization for flexibility. Document clearly who runs the updater, what data is sourced, and how consumers should react to staleness. For high-value DeFi, prefer established decentralized oracle networks.
Consumer Integration
A consumer contract simply imports the oracle interface and reads from it, applying its own freshness checks.
interface IOracle {
function getFreshValue() external view returns (uint256);
}
contract Consumer {
IOracle public oracle;
constructor(address o) { oracle = IOracle(o); }
function price() external view returns (uint256) {
return oracle.getFreshValue();
}
}Quick Check
Test your grasp of custom oracle design.
Recap
You built a custom oracle with an off-chain updater and an on-chain store. Key ideas:
- Trusted updater with rotatable access control
- Freshness checks via
lastUpdated - Request-response flow with events and callbacks
- Multiple updaters and medians to reduce single-source risk
Use custom oracles for niche data, but prefer decentralized networks for high-stakes feeds.
자주 묻는 질문
“사용자 지정 오라클 컨트랙트 구축” 강의는 무료인가요?
네 — “사용자 지정 오라클 컨트랙트 구축” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Blockchain Smart Contracts with Solidity 강의 전체를 잠금 해제할 수 있습니다. Blockchain Smart Contracts with Solidity 강의에는 총 4개의 강의가 포함되어 있습니다.
“사용자 지정 오라클 컨트랙트 구축”에서 뭘 배우나요?
요청-응답 흐름, 신뢰할 수 있는 업데이트 주체, 온체인 데이터 최신성 검증을 포함해 Solidity로 자체 오라클 패턴을 설계하고 구현하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 Blockchain Smart Contracts with Solidity을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Blockchain Smart Contracts with Solidity을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Blockchain Smart Contracts with Solidity은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“사용자 지정 오라클 컨트랙트 구축” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Blockchain Smart Contracts with Solidity 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Blockchain Smart Contracts with Solidity 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 오라클 문제 이해하기
- Chainlink 오라클 통합
- 오프체인 데이터 조회 처리
- 사용자 지정 오라클 컨트랙트 구축