微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Web3py 和 Uniswap 配对智能合约计算价格:如何处理定点数?

如何解决使用 Web3py 和 Uniswap 配对智能合约计算价格:如何处理定点数?

我正在尝试使用 web3.py 和 Uniswap 配对合约在 Uniswap 中计算代币的价格,但我一定在数学上做错了。示例:我想计算一个以 USDC 计价的 ETH 的价格。我首先连接到配对合约 USDC/ETH (0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc) 以通过 web3.py 访问智能合约功能

如此处所述 (https://uniswap.org/docs/v2/smart-contract-integration/building-an-oracle/),我将 price1CumulativeLast() 的结果和关联的时间戳存储在两个不同的时间点(每次函数调用间的一分钟)。然后我使用公式

(price0CumulativeLATEST — price0CumulativeFirsT) / (timestampOfLATEST — timestampOfFirsT)

(参见:https://medium.com/@epheph/using-uniswap-v2-oracle-with-storage-proofs-3530e699e1d3)计算以 token0 (USDC) 计价的 token1 (ETH) 的价格。

Uniswap 文档说 price1CumulativeLast() 返回一个 Q112Q112 定点数,这就是为什么我认为我无法理解这些数字。

我已经尝试搜索 Python 函数来轻松地将定点 Q112Q112 转换为浮点数,但还没有找到可行的解决方案,所以我想我必须在以太坊智能合约或 Uniswap 中使用的数学或单位出现根本性错误.

def calculate_price():
'''
Call price1CumulativeLast() three times with one minute interval between each call.
'''
results = []
for x in range(3):
    try:
        temp_dict = {}
        start_ts = w3.eth.getBlock(w3.eth.block_number).timestamp
        token1_price_start = contract.functions.price1CumulativeLast().call()
        time.sleep(60*1)
        end_ts = w3.eth.getBlock(w3.eth.block_number).timestamp
        token1_price_end = contract.functions.price1CumulativeLast().call()
        temp_dict['start_ts'] = start_ts
        temp_dict['token1_price_start'] = token1_price_start
        temp_dict['end_ts'] = end_ts
        temp_dict['token1_price_end'] = token1_price_end
        results.append(temp_dict)
    except:
        continue
return results

这给了我:

    results = [{'start_ts': 1623002172,'token1_price_start': 183015811459414492033193017518027,'end_ts': 1623002242,'token1_price_end': 183016664977333417354464783721666},{'start_ts': 1623002242,'token1_price_start': 183016664977333417354464783721666,'end_ts': 1623002250,{'start_ts': 1623002250,'end_ts': 1623002355,'token1_price_end': 183018525945544514538790080485913}]

我现在在公式中插入两个时间戳和两个价格,以在一分钟的时间间隔内重新计算以 token0 计价的 token1 的价格:

   price = (results[0]['token1_price_end'] - results[0]['token1_price_start']) / (results[0]['end_ts'] - results[0]['start_ts'])
format(price,'.10f')

这将返回以下字符串:

'12193113127504589866663936.0000000000'

在撰写本文时,这应该约为 2800(1 ETH = 2800 USDC),但我不知道如何从这里获得该数字。我做错了什么?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。