当前位置: 首页 > 科技观察

使用Web3.py、Infura和Graph查询以太坊数据

时间:2023-03-19 18:54:54 科技观察

Web3.py是一个为与以太坊区块链交互而构建的Python库。有了它,我们就可以构建去中心化应用的各种核心功能。我们可以直接与智能合约交互,收集区块链数据,发送交易。让我们从安装Web3.py开始。pipinstallweb3Web3.py的作用是连接到以太坊网络的节点,获取数据并向网络广播数据。节点存储区块链数据,因此我们可以查询以太坊区块链的状态以收集我们需要的数据。数据检索对我们来说实际上是一项免费操作,因为唯一的成本是节点的持续存储和计算。有了这个库,我们就可以连接到我们自己的节点或网络上现有的节点来构建我们想要的东西。我们可以在我们自己的机器上设置一个本地节点,但这样做的成本非常高;截至4月21日,一个全节点大约有7TB的数据。我们可以通过使用像Infura这样的服务来访问数据,而不是在我们想要访问数据时操作我们自己的节点。Infura是Consensys的产品,我们将使用它作为我们的节点,连接到以太坊区块链。许多顶级项目都是Infura的用户。首先在Infura网站上注册并创建一个新项目。在那里你会找到一个项目ID。项目ID将放在Web3.py中此代码的末尾,它将定义您要连接的节点。fromweb3importWeb3w3=Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_PROJECT_ID'))与以太坊网络的连接现在已准备好进行一些基本查询。#获取最新区块的信息w3.eth.getBlock('latest')#获取某个地址的ETH余额w3.eth.getBalance('YOUR_ADDRESS_HERE')这段代码非常简洁,大家可以尝试深入挖掘。就像模仿Zapper(https://zapper.fi/dashboard)这样的产品功能一样,跟踪我们代币的美元价值怎么样?首先,我们需要扫描我们的地址以查看持有哪些硬币。为此,我们将与相应代币的智能合约进行交互。这些合约的地址看起来像我们的钱包地址,除了这些是合约地址。该地址有智能合约代码。代币将遵守ERC-20标准,使我们更容易与这些合约进行交互。一个ERC-20合约默认有以下函数:uint256)functionbalanceOf(address_owner)publicviewreturns(uint256balance)functiontransfer(address_to,uint256_value)publicreturns(boolsuccess)函数transferFrom(address_from,address_to,uint256_value)publicreturns(booladdresssuccess)_spender,uint256_value)publicreturns(boolsuccess)functionallowance(address_owner,address_spender)publicviewreturns(uint256remaining)balanceOf是一个函数,可以让我们看到我们查询的钱包地址持有多少代币。importjsonABI=json.loads('[{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs"":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]')我们定义了一个ABI开始。ABI(应用程序二进制接口)是我们定义的用于与合约交互的格式。我们用它来定义数据在EVM中应该如何编码/解码。撇开技术细节不谈,重要的是要理解这是我们定义我们将如何与我们想要的智能合约交互的格式。wallet_address='YOUR_ADDRESS_HERE'wallet_address=Web3.toChecksumAddress(wallet_address)token_contract_address='0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f'token_contract_address=Web3.toChecksumAddress(token_contract_address)#definecontractcontract=w3.eth.contract(token_contract_address,abi=ABI)#callcontractandgetdatafrombalanceOfforargumentwallet_addressraw_balance=contract.functions.balanceOf(wallet_address).call()#convertthevaluefromWeitoEthersynthetix_value=Web3.fromWei(raw_balance,'ether')接下来我们进行一系列的步骤,输入地址并返回值我们选择了钱包地址持有的代币数量。我们的示例地址是Synthetix(SNX),您可以输入您喜欢的任何合约地址。你可以想象你可以构建一个ERC-20合约地址的主列表并遍历它以找到特定钱包持有的代币。我们使用Web3函数toChecksumAddress()来确保我们的地址采用校验和格式。我们使用fromWei()将我们的Wei价格转换为以太币。1ETH就是1E18微。最后,我们将使用TheGraph获取一些市场数据。由于我们希望一切都在链上,因此我们需要在DAI中获得我们想要的代币的价值,这是一种与美元挂钩的稳定币。fromgqlimportgql,Clientfromgql.transport.requestsimportRequestsHTTPTransportsample_transport=RequestsHTTPTransport(url='https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2',verify=True,retries=5,)客户端=Client(transport=sample_transport)#获取SNX/ETH的值'pair']eth_value=float(snx_eth_pair['reserve1'])/float(snx_eth_pair['reserve0'])#获取ETH/DAI的值query=gql('''query{pair(id:"0xa478c2975ab1ea89e8196811f51a7b7ade33eb11"){reserve0reserve1}}''')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我们查询TheGraph以获得SNX的DAI值。我们先得到每个SNX的ETH值,然后乘以一个ETH等值的DAI的数量,就得到一个SNX的DAI值。然后,我们可以将最终的DAI值乘以我们钱包持有的SNX数量,得出头寸的总美元价值。我们必须执行所有这些额外的步骤,因为Uniswap中没有一个活跃的矿池可以直接将DAI换成SNX。所以我们从SNX到ETH再到DAI。下一步解释了我们如何查询实时区块链数据以获取最新的链上活动。