5/5
## Integrating Chainlink Price Feeds in Vyper This lesson demonstrates how to integrate Chainlink Price Feeds into your Vyper smart contracts. We'll use a practical example: enhancing a "Buy Me A Coffee" style contract to accept a minimum funding amount specified in USD, even though users pay with the blockchain's native currency (like ETH). This requires fetching a real-time exchange rate, a task perfectly suited for Chainlink Price Feeds. ### The Challenge: On-Chain Currency Conversion Let's consider a simple Vyper contract designed to receive funds, similar to a "Buy Me A Coffee" platform. ```vyper # buy_me_a_coffee.vy (Illustrative Example) minimum_usd: public(uint256) @deploy def __init__(): # We want users to send at least $5 USD self.minimum_usd = 5 @external @payable def fund(): """Allows users to send funds to this contract. Enforces a minimum USD value for funding. """ # Problem: How do we compare msg.value (in Wei) with self.minimum_usd (representing dollars)? # This comparison is conceptually correct but technically flawed due to differing units. assert msg.value >= self.minimum_usd, "You must send ETH equivalent to at least $5 USD!" # ... rest of funding logic ``` In this contract, `self.minimum_usd` is intended to represent $5 USD. The `fund` function is marked `@payable`, allowing it to receive the blockchain's native currency (e.g., ETH, often measured in its smallest unit, Wei). The core problem arises in the `fund` function. We need to ensure the value sent by the user (`msg.value`, in Wei) is greater than or equal to our target `$5 USD` (`self.minimum_usd`). Directly comparing `msg.value` and `self.minimum_usd` is incorrect because they represent different units – Wei and USD. We need a reliable way to determine the current ETH-to-USD exchange rate within the smart contract to perform a valid comparison. ### The Solution: Chainlink Price Feeds Chainlink Price Feeds solve this problem by providing accurate, decentralized, and readily available price data on-chain. They are essentially smart contracts deployed on the blockchain that store and update real-world asset prices, like the ETH/USD exchange rate. To use a Price Feed, our `buy_me_a_coffee.vy` contract needs to interact with the Chainlink Price Feed contract. ### Interacting with External Contracts in Vyper Calling functions on another smart contract from within your Vyper contract requires two essential pieces of information: 1. **Contract Address:** The unique blockchain address where the target contract (the Chainlink Price Feed contract) is deployed. 2. **ABI (Application Binary Interface):** A specification detailing the external contract's functions, their parameters, return types, and how to encode/decode calls. It acts as the blueprint for interaction. Let's start by finding the Address for the ETH/USD Price Feed. ### Finding the Price Feed Address Chainlink maintains comprehensive documentation listing the addresses for various data feeds across different blockchain networks. 1. Navigate to the official Chainlink Documentation (`docs.chain.link`). 2. Find the section on "Data Feeds" or "Price Feeds". 3. Locate the "Contract Addresses" or "Feed Addresses" page. 4. Select the blockchain network you are deploying to (e.g., Ethereum Mainnet, or a testnet like Sepolia). 5. Find the specific feed you need, such as `ETH / USD`. 6. Copy the address provided for your chosen network. For example, the ETH/USD Price Feed address on the Sepolia testnet might be `0x694AA1769357215DE4FAC081bf1f309aDC325306`. We can create a helper function within our contract to encapsulate the price-fetching logic. It's good practice in Vyper (and Python) to use an underscore prefix and the `@internal` decorator for functions intended only for internal use within the contract. ```vyper # buy_me_a_coffee.vy (Adding helper function structure) minimum_usd: public(uint256) price_feed_address: public(address) # Store the feed address ETH_USD_FEED_SEPOLIA: constant(address) = 0x694AA1769357215DE4FAC081bf1f309aDC325306 @deploy def __init__(): self.minimum_usd = 5 # Set the address during deployment (adjust based on network) self.price_feed_address = ETH_USD_FEED_SEPOLIA @internal def _get_latest_eth_usd_price() -> uint256: """ Gets the latest ETH/USD price from the Chainlink Price Feed. Requires the Price Feed address and ABI knowledge. """ # Implementation using the address and ABI will go here # We need the ABI to know *how* to call the Price Feed contract pass @external @payable def fund(): # 1. Get the latest ETH/USD price # latest_price: uint256 = self._get_latest_eth_usd_price() # Placeholder # 2. Convert msg.value (Wei) to its USD value using the price # ... conversion logic ... # 3. Compare the calculated USD value with self.minimum_usd # assert calculated_usd_value >= (self.minimum_usd * 10**?) # Careful with decimals! pass ``` ### Understanding Price Feed Data and EVM Decimals Before implementing the call, it's crucial to understand how Price Feeds return data. You can inspect the Price Feed contract directly using a block explorer like Etherscan. Navigate to the Price Feed address on Etherscan (for the correct network), go to the "Contract" tab, and then the "Read Contract" sub-tab. You'll find several useful functions: * `latestAnswer()`: Returns the latest price as a single integer. * `latestRoundData()`: Returns more detailed information about the latest update, including the price (`answer`), round ID, timestamp, etc. * `decimals()`: Returns the number of decimal places used by the price value returned by `latestAnswer` or `latestRoundData`. If you call `latestAnswer()` for the ETH/USD feed on Sepolia via Etherscan, you might get a large number like `325311000000`. **This is not $325 billion!** The Ethereum Virtual Machine (EVM) does not natively support floating-point numbers. To represent values with fractional parts, smart contracts use fixed-point arithmetic. Chainlink Price Feeds return prices as large integers, and you need to know the number of decimals to interpret them correctly. Most Chainlink ETH/USD feeds use **8 decimals**. This means you must divide the raw integer value by 10 raised to the power of the `decimals` value (10⁸) to get the actual price in USD. * Raw `latestAnswer`: `325311000000` * Decimals: `8` * Actual Price: `325311000000 / (10**8)` = `3253.11000000` USD Understanding decimals is critical for performing accurate calculations when converting between the native currency (like ETH in Wei, which has 18 decimals) and the USD value derived from the Price Feed (which has 8 decimals in this case). ### Next Steps: Using the ABI We've identified the need for Chainlink Price Feeds, located the necessary contract address, and understood how the price data is formatted (including the importance of decimals). The remaining piece required to interact with the Price Feed contract from our Vyper code is its **ABI**. The next step is to learn how to obtain the Price Feed ABI and use it within our `_get_latest_eth_usd_price` function to make the actual external call and retrieve the price.
A practical guide to Integrating Chainlink Price Feeds in Vyper - Learn how to fetch real-time asset prices like ETH/USD within your Vyper smart contracts using Chainlink. Understand the process of finding feed addresses and correctly interpreting price data with decimals.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
The basics of blockchain transactions, how to send and receive money on a blockchain network.
How to write Python based smart contracts using Vyper.
How to read and understand Vyper smart contracts.
Vyper data structures, arrays, structs, hash maps.
How to build a smart contract application and deploy on ZKsync with Moccasin.
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
On-chain Data Analyst
$59,000 - $139,000 (avg. salary)
DeFi Developer
$75,000 - $200,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Last updated on June 11, 2025
Duration: 2h 08min
Duration: 2h 32min
Duration: 24min
Course Overview
About the course
The basics of blockchain transactions, how to send and receive money on a blockchain network.
How to write Python based smart contracts using Vyper.
How to read and understand Vyper smart contracts.
Vyper data structures, arrays, structs, hash maps.
How to build a smart contract application and deploy on ZKsync with Moccasin.
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
On-chain Data Analyst
$59,000 - $139,000 (avg. salary)
DeFi Developer
$75,000 - $200,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Last updated on June 11, 2025