pip install web3
目前以太坊全節點數據量高達數TB,自建本地全節點不太現實,因此一般通過Infura等的網關來實現數據查詢。在 Infura 新建一個項目獲取API KEY
from web3 import Web3
chainApi = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/6efdb....(替換為你的API KEY)'))
# 獲取最新區塊數據
block = chainApi.eth.getBlock("latest")
print(block)
# 獲取某地址的余額
balance = chainApi.eth.getBalance("0x7A6381...(替換為你要查詢的地址)")
print(balance)
需求:識別當前用戶地址持有的 token 資產的美元價格,統計資產總淨值
實現思路:1. 首先要掃描錢包地址,查看持有哪些代幣(需要與各ERC20合約交互)。2. 計算代幣的美元價值來計算總淨值。
第一步
符合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)
與合約交互需要通過 ABI:application binary interface。ABI用來定義數據在EVM中應該如何編碼/解碼。
這裡以Synthetix(SNX)合約為例,示例代碼如下:
import json
ABI = json.loads('[{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]')
wallet_address = '0x7A638...(換成你的地址)'
wallet_address = Web3.toChecksumAddress(wallet_address)
token_contract_address = '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f' # SNX合約地址
token_contract_address = Web3.toChecksumAddress(token_contract_address)
# define contract
contract = chainApi.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')
print(synthetix_value)
要遍歷所有 token 資產可以通過建立一個 ERC-20 合約地址的主列表,並通過迭代來找到特定錢包所持有的代幣。
第二步
使用 The Graph 獲取行情數據(美元價格)
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
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
print(snx_dai_value)
通過 DEX 的數據來計算 SNX 與錨定美元的穩定幣的匯率,這裡以 ETH 為中間幣種做了兩次計算(DAI 穩定幣錨定美元)。
對 The Graph 進行查詢,以獲得 SNX 的 DAI 價值。我們首先得到每一個 SNX 的 ETH 價值,然後乘以與一個 ETH 等值的 DAI 數量,得到一個 SNX 的 DAI 價值。將最終的 DAI 值乘以我們錢包持有的 SNX 數量,找到頭寸的總美元價值。
[1]用Web3.py、Infura和Graph查詢以太坊數據