• python 基于 Web3.py 和 Infura 网关采集链上数据


    • Web3.py是与Ethereum交互的Python库。功能包括连接到以太坊网络节点、检索数据和向以太坊网络广播数据。
    pip install web3
    
    • 1

    目前以太坊全节点数据量高达数TB,自建本地全节点不太现实,因此一般通过Infura等的网关来实现数据查询。在 Infura 新建一个项目获取API KEY

    from web3 import Web3
    chainApi = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/6efdb....(替换为你的API KEY)'))
    
    • 1
    • 2
    # 获取最新区块数据
    block = chainApi.eth.getBlock("latest")
    print(block)
    # 获取某地址的余额
    balance = chainApi.eth.getBalance("0x7A6381...(替换为你要查询的地址)")
    print(balance)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    与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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • ​​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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • ​​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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    通过 DEX 的数据来计算 SNX 与锚定美元的稳定币的汇率,这里以 ETH 为中间币种做了两次计算(DAI 稳定币锚定美元)。
    对 The Graph 进行查询,以获得 SNX 的 DAI 价值。我们首先得到每一个 SNX 的 ETH 价值,然后乘以与一个 ETH 等值的 DAI 数量,得到一个 SNX 的 DAI 价值。将最终的 DAI 值乘以我们钱包持有的 SNX 数量,找到头寸的总美元价值。

    Reference

    [1]用Web3.py、Infura和Graph查询以太坊数据

  • 相关阅读:
    21天打卡挑战学习MySQL——《Docker容器安装》第三周 第七篇
    OpenMLDB 线上引擎资源需求预估模型,助你快速预估资源消耗
    Codeforces Round #823 (Div. 2) A-D
    【LEACH协议】最佳簇半径的无线传感器网络分簇路由算法【含Matlab源码 2087期】
    ios 运行ipa包 日志查看方式
    java mybatisplus generator 修改字段类型
    springboot 上传文件/图片到本地文件夹,利用nginx可以采用地址打开该文件
    数据采集实战:如何自动化运营微博?
    【Tools】如何在VSCode上使用C++ 保姆教程
    SLAM静态编译中动态链接库问题
  • 原文地址:https://blog.csdn.net/qq_33583069/article/details/126146725