Cross-chain & Oracles
A blockchain can only see itself. To know "what's ETH/USD" or "did something happen on Solana", you need bridges (move value) or oracles (import data). Both are trust-minimized, not trust-free.
1. Oracles — why they're hard
A smart contract has no HTTP client. You can't fetch("https://coinbase.com/btc"). Instead, off-chain nodes ("oracles") push signed data on-chain. The contract trusts them.
2. Chainlink price feeds — 80% of what you need
import "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
contract PriceConsumer {
AggregatorV3Interface feed;
constructor(address _feed) { feed = AggregatorV3Interface(_feed); }
function priceUSD() external view returns (int256) {
(, int256 answer, , uint256 updatedAt,) = feed.latestRoundData();
require(block.timestamp - updatedAt < 1 hours, "stale");
return answer; // 8 decimals
}
}
- Aggregator = many independent node operators signing the same value; on-chain median.
- Always check
updatedAt(staleness) and thatanswer > 0. - Different feeds update at different cadences (heartbeat + deviation threshold).
3. Oracle design taxonomy
| Type | How it works | Example |
|---|---|---|
| Push | Operators proactively update on-chain | Chainlink data feeds |
| Pull | User fetches signed data off-chain, submits with tx | Pyth, Redstone |
| Optimistic | Anyone posts; anyone can challenge with bond | UMA |
| VRF | Verifiable randomness | Chainlink VRF |
Pull oracles are often cheaper (users pay gas only when they need fresh data) but more UX complexity.
4. Cross-chain messaging — the shape of the problem
All bridges boil down to: a set of validators attests to "this message happened on chain A", and chain B trusts them up to some threshold.
5. Messaging protocol cheat sheet
| Protocol | Trust model | Latency |
|---|---|---|
| CCIP (Chainlink) | DON + anti-fraud monitoring | Minutes |
| LayerZero | Oracle + Relayer (configurable) | Minutes |
| Axelar | Own PoS validator set | ~1 min |
| Wormhole | 19 guardians | ~15 min |
| Hyperlane | ISM (modular, app-picks) | Varies |
| Canonical rollup bridge | L1 inherits via proof | 7d optimistic / hours zk |
6. A LayerZero-style send/receive contract
// on Chain A
function send(uint32 dstEid, bytes calldata payload) external payable {
endpoint.send{value: msg.value}(
MessagingParams(dstEid, peerOnB, payload, "", false), payable(msg.sender));
}
// on Chain B (callback)
function lzReceive(Origin calldata o, bytes32, bytes calldata payload, address, bytes calldata) external {
require(msg.sender == address(endpoint), "only endpoint");
require(peers[o.srcEid] == o.sender, "untrusted sender");
(address to, uint256 amount) = abi.decode(payload, (address, uint256));
token.mint(to, amount); // e.g., burn-on-A + mint-on-B pattern
}
msg.sender == endpoint and the source chain/sender. Otherwise anyone can call lzReceive with a forged payload and mint infinity.7. The bridge trilemma (Vitalik, 2022)
You can't have all three: (a) trust-minimized, (b) generalized (arbitrary messages), (c) works across independent chains. Pick two. This is why every bridge design is a different compromise.
8. VRF — on-chain randomness
block.timestamp, blockhash and block.prevrandao are manipulable. For fair NFT reveals, lotteries, matchmaking — use Chainlink VRF.
function requestRandom() external {
uint256 reqId = vrf.requestRandomWords(...);
pending[reqId] = msg.sender;
}
function fulfillRandomWords(uint256 reqId, uint256[] memory words) internal override {
// use words[0] deterministically
}
9. Patterns that actually ship
- Burn-and-mint bridged tokens (supply conserved).
- Lock-and-mint (L1 lock, L2 mint; most rollups).
- Atomic swaps via hashed-timelock contracts (mostly historical).
- Liquidity-based bridges (Stargate, Hop, Across) — instant UX, uses LP pools on each chain.
10. Project
Quiz
feed.latestRoundData() but doesn't check updatedAt. In a sequencer outage, the price was stale for 3 hours at $100 while the real price dropped to $50. A user borrowed against an asset at the stale price. What just happened?- Nothing; Chainlink is always live
- Stale oracle → under-collateralized loan → bad debt for the protocol
- Reentrancy
- Front-running