用Web3.py、Infura和Graph查詢以太坊數(shù)據(jù)
Web3.py是一個為與Ethereum區(qū)塊鏈交互而建立的Python庫。有了它,我們可以為去中心化的應用程序建立各種核心功能。我們可以直接與智能合約互動,收集區(qū)塊鏈數(shù)據(jù),并發(fā)送交易。讓我們開始安裝Web3.py。
pip install web3
Web3.py的功能是連接到以太坊網(wǎng)絡的節(jié)點,以檢索數(shù)據(jù)和向網(wǎng)絡廣播數(shù)據(jù)。節(jié)點存儲區(qū)塊鏈數(shù)據(jù),所以我們可以查詢以太坊區(qū)塊鏈的狀態(tài)來收集我們需要的數(shù)據(jù)。數(shù)據(jù)檢索對我們來說是一個有效的免費操作,因為唯一的成本是節(jié)點正在進行的存儲和計算。有了這個庫,我們可以連接到自己的節(jié)點或網(wǎng)絡上的現(xiàn)有節(jié)點來建立我們想要的東西。我們可以在自己的機器上建立一個本地節(jié)點,但這樣做的成本是相當高的;截至4/21,一個完整的節(jié)點大約有7TB的數(shù)據(jù)。與其在我們想要訪問數(shù)據(jù)時操作自己的節(jié)點,不如通過使用像Infura這樣的服務來達到目的。Infura是Consensys的產(chǎn)品,我們將使用它作為我們的節(jié)點,連接到以太坊區(qū)塊鏈。許多頂級項目都是Infura的用戶。首先在Infura網(wǎng)站注冊并創(chuàng)建一個新項目。在那里你會發(fā)現(xiàn)一個項目ID。
該項目ID將被放在Web3.py的這段代碼中的末尾,它將定義你要連接到的節(jié)點。
from web3 importWeb3
w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_PROJECT_ID'))
現(xiàn)在已經(jīng)準備好了與以太坊網(wǎng)絡的連接,可以做一些基本的查詢。
# Get information about the latest block
w3.eth.getBlock('latest')
# Get the ETH balance of an address
w3.eth.getBalance('YOUR_ADDRESS_HERE')
這段代碼很簡潔,我們可以試著深入挖掘一下。比如模仿Zapper( ????https://zapper.fi/dashboard???
?)這樣的產(chǎn)品功能,跟蹤我們代幣的美元價值如何?首先,需要掃描我們的地址,看看持有哪些代幣。為了做到這一點,我們將與各個代幣的智能合約進行交互。這些合約的地址看起來像我們的錢包地址,只不過這些是合約地址。在這個地址上有智能合約代碼。代幣將遵守ERC-20標準,使我們更容易與這些合約進行交互。一個ERC-20合約默認具有以下功能:
function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
??balanceOf?
?是讓我們看到我們查詢的錢包地址持有多少代幣的函數(shù)。
import json
ABI = json.loads('[{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf",
"outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]')
我們從定義一個ABI開始。ABI( application binary interface)是我們定義的一種格式,用于與合約交互。它是我們用來定義數(shù)據(jù)在EVM中應該如何編碼/解碼的。拋開技術(shù)細節(jié),重要的是要理解它是我們定義的格式,我們將如何與我們想要的智能合約進行交互。
wallet_address = 'YOUR_ADDRESS_HERE'
wallet_address = Web3.toChecksumAddress(wallet_address)
token_contract_address = '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f'
token_contract_address = Web3.toChecksumAddress(token_contract_address)
# define contract
contract = w3.eth.contract(token_contract_address, abi=ABI)
# call contract and get data from balanceOf for argument wallet_address
raw_balance = contract.functions.balanceOf(wallet_address).call()
# convert the value from Wei to Ether
synthetix_value = Web3.fromWei(raw_balance, 'ether')
接下來我們采取一系列步驟,輸入地址并返回我們選擇的錢包地址所持有的代幣數(shù)量。我們的樣本地址是Synthetix(SNX),你可以輸入任何你喜歡的合約地址。你可以想象一下,你可以建立一個ERC-20合約地址的主列表,并通過迭代來找到特定錢包所持有的代幣。我們使用Web3函數(shù) ??toChecksumAddress()?
?來確保我們的地址是校驗格式的。我們使用 ??fromWei()?
?將我們的Wei價格轉(zhuǎn)換為 ether。1ETH是1E18 Wei。最后,我們將使用The Graph來獲取一些行情數(shù)據(jù)。由于我們希望所有的東西都在鏈上,所以我們需要得到我們想要的代幣在DAI中的價值,這是一個與美元相對掛鉤的穩(wěn)定幣。
from gql import gql, Client
from gql.transport.requests importRequestsHTTPTransport
sample_transport=RequestsHTTPTransport(
url='https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2',
verify=True,
retries=5,
)
client = Client(
transport=sample_transport
)
# Get the value of SNX/ETH
query = gql('''
query {
pair(id: "0x43ae24960e5534731fc831386c07755a2dc33d47"){
reserve0
reserve1
}
}
''')
response = client.execute(query)
snx_eth_pair = response['pair']
eth_value = float(snx_eth_pair['reserve1']) / float(snx_eth_pair['reserve0'])
# Get the value of ETH/DAI
query = gql('''
query {
pair(id: "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11"){
reserve0
reserve1
}
}
''')
response = client.execute(query)
eth_dai_pair = response['pair']
dai_value = float(eth_dai_pair['reserve0']) / float(eth_dai_pair['reserve1'])
snx_dai_value = eth_value * dai_value
我們對The Graph進行查詢,以獲得SNX的DAI價值。我們首先得到每一個SNX的ETH價值,然后乘以與一個ETH等值的DAI數(shù)量,得到一個SNX的DAI價值。然后,我們可以將最終的DAI值乘以我們錢包持有的SNX數(shù)量,找到頭寸的總美元價值。我們不得不做所有這些額外的步驟,因為在Uniswap中沒有一個活躍的池子來直接用DAI交換SNX。所以我們從SNX到ETH到DAI。下一步會講解我們?nèi)绾尾樵儗崟r區(qū)塊鏈數(shù)據(jù),以了解鏈上活動的最新情況。