程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python 基於 Web3.py 和 Infura 網關采集鏈上數據

編輯:Python
  • Web3.py是與Ethereum交互的Python庫。功能包括連接到以太坊網絡節點、檢索數據和向以太坊網絡廣播數據。
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)

與ERC-20合約交互

需求:識別當前用戶地址持有的 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)
  • ​​balanceOf​ ​是用於查詢錢包地址持有多少代幣的函數。

與合約交互需要通過 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)
  • ​​toChecksumAddress()​​來確保我們的地址是校驗格式的
  • fromWei()​​將我們的Wei價格轉換為 ether 1ETH是 1 0 18 10^{18} 1018 Wei

要遍歷所有 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 數量,找到頭寸的總美元價值。

Reference

[1]用Web3.py、Infura和Graph查詢以太坊數據


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved