Access Ethereum Data Using Web3.py, Infura, and The Graph | by Posey | Towards Data Science

Note: full code to this article can be found on GitHub.
Previously I shared how to access blockchain data for DeFi projects using various centralized APIs like DeFi Llama and decentralized APIs like The Graph. This time around we’re going to query the blockchain directly using the Web3.py Python library.
Why?
Web3.py is a Python library built for interacting with the Ethereum blockchain. With it we can build all sorts of core functionality for decentralized applications. We can interact with smart contracts directly, gather blockchain data, and send transactions. If you’re not a Python user, there are libraries for other languages, like the popular web3.js libraries.
In our terminal let’s get started by installing our Python library.
pip install web3
Web3.py functions by connecting to nodes in the Ethereum network to both retrieve data and broadcast data to the network. Nodes store blockchain data so we can query the state of the Ethereum blockchain to gather the data we need. The data retrieval is an effectively free operation for us, as the only real cost is the storage and computation being performed by the nodes saving that data.
With this library we can connect to our own node or an existing node on the network to build what we want. We could spin up a local node on our machine, but the costs to do that are pretty steep; a full node as of 4/21 is about ~7TB of data. Instead of operating our own node any time we want to access data, we’ll cop out and go the sensible route by using a service like Infura.
Infura is a Consensys product we will use as our node to connect to the Ethereum blockchain. Many of the top projects are Infura users. Later down the road you can explore if operating your own node or using another service is the right option for your use-case.
To get started, find your way over to Infura and create a new project. There you will find a project ID.
That project ID will go at the end of your endpoint in this snippet of Web3.py code that will define what node you want to connect to.
Now that you’ve got your connection to the network ready to go, how about making some basic queries?
That was neat but very basic. How about digging deeper? How about trying to mimic the functionality of a product like Zapper that tracks the $ value of our tokens?
First, we’ll need to scan for what tokens our address holds. To do this, we’ll be interacting with smart contracts for the individual tokens. These contracts live at addresses that look like our wallet addresses (externally owned accounts), except these are instead contract addresses. At this address lives smart contract code. Tokens will adhere to the ERC-20 standard that makes our lives easier for interacting with these contracts.
An ERC-20 contract will by default have the following functions...
balanceOf is the function that allows us to see how many of the tokens are held by the wallet address we query for.
We start by defining an ABI. The ABI or application binary interface is a format we define to interact with contracts. It’s what we use to define how data should be encoded/decoded in the EVM. Technical details aside, what’s important is to understand it is the format we define for how we will interact with our desired smart contract.
Next we take a series of steps to input the address and return the # of tokens held by the wallet address of our choosing. Our sample address was for Synthetix (SNX), you can input any contract address you like. You can imagine that you could set up a master list of ERC-20 contract addresses and iterate through to find what tokens are held by a specific wallet.
We use the Web3 function toChecksumAddress() to make sure our address is in checksum format. We use fromWei() to convert our Wei value to ether. 1 ETH is 1E18 Wei.
Finally, we’ll use The Graph to grab some price data. Since we want everything to be on-chain for this use-case, we need to get the value of our desired token in DAI, a stablecoin that stays relatively pegged to USD.
We do a pair of queries to The Graph to get the DAI (stablecoin soft pegged to USD) value of SNX.
We start by getting the fraction of ETH per SNX and multiply by the number of DAI per ETH to get to a final DAI value per SNX.
We can then multiply our final DAI value times the number of SNX our wallet holds to find (roughly) the total USD value of the position. If that sounds confusing, try reading the code and it’ll make a lot more sense. We had to do all these extra steps because there isn’t an active pool in Uniswap for directly exchanging DAI for SNX. So we go from SNX to ETH to DAI.
Next time we’ll toss our data in a UI and see how we can query blockchain data in real-time to keep up-to-date with on-chain activity.
Let’s continue the conversation on Twitter.
Access the full code on GitHub.
To support my writing and get full access to all articles on Medium, visit https://posey.medium.com/membership