当前位置: 首页 > news >正文

solidity 中 Eth 和 Usd 到底如何转换

在Solidity中通过预言机(Oracle)实现ETH与USD的换算,核心是利用预言机提供的实时ETH/USD价格数据,结合整数运算处理精度问题。以下是详细步骤和代码示例,带你从零实现。<理解预言机的同学可以先看第五点>

一、核心原理回顾

  1. 预言机的作用:提供ETH与USD的实时汇率(如1 ETH = 2000.12345678 USD),但返回的是放大后的整数(如200012345678,放大了1e8倍,保留8位小数)。
  2. 单位转换:ETH在链上以wei为最小单位(1 ETH = 1e18 wei),USD通常以“美元分”或“美元单位”计算(需明确精度,如1 USD = 1e18单位,避免小数)。
  3. 运算逻辑:利用整数乘法和除法处理换算,避免小数运算(Solidity不直接支持小数)。

二、准备工作:选择预言机

最常用的是Chainlink预言机,它提供标准化的价格接口AggregatorV3Interface。不同网络的预言机地址不同(如以太坊主网、Sepolia测试网等),需提前查询(Chainlink地址列表)。

Sepolia测试网的ETH/USD价格预言机为例,地址为:0x694AA1769357215DE4FAC081bf1f309aDC325306

三、完整实现步骤

1. 引入预言机接口

Chainlink的AggregatorV3Interface定义了获取价格的方法,需导入或直接定义接口。

2. 初始化预言机

在合约构造函数中,传入预言机地址,初始化接口实例。

3. 获取实时ETH/USD价格

调用预言机的latestRoundData()方法,获取放大后的价格(整数),并检查数据新鲜度(避免使用过时价格)。

4. 实现ETH转USD的函数

已知ETH数量(以wei为单位),计算对应的USD金额。

5. 实现USD转ETH的函数

已知USD金额,计算对应的ETH数量(以wei为单位)。

四、代码示例(附详细注释)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;// 引入Chainlink预言机接口(或直接定义)
interface AggregatorV3Interface {function latestRoundData()externalviewreturns (uint80 roundId,    // 轮次IDint256 answer,     // 价格(放大后的整数)uint256 startedAt, // 开始时间uint256 updatedAt, // 更新时间uint80 answeredInRound // 回答轮次);
}contract EthUsdConverter {// 预言机实例(ETH/USD价格源)AggregatorV3Interface public priceFeed;// 常量定义(精度控制)uint256 public constant ETH_DECIMALS = 1e18; // 1 ETH = 1e18 weiuint256 public constant PRICE_DECIMALS = 1e8; // 预言机价格放大倍数(8位小数)uint256 public constant USD_DECIMALS = 1e18; // 假设USD以1e18为单位(可根据需求调整)// 构造函数:初始化预言机(Sepolia测试网ETH/USD地址)constructor() {priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);}/*** 内部函数:获取最新ETH/USD价格(放大后的整数,如200012345678)* 并检查价格是否新鲜(1小时内更新)*/function getLatestEthUsdPrice() internal view returns (uint256) {(, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();// 检查价格是否过时(超过1小时)require(updatedAt > block.timestamp - 3600, "Price is stale");// 确保价格为正数require(price > 0, "Invalid price");return uint256(price);}/*** 功能1:ETH转USD(输入wei,返回USD单位)* 公式:USD = (ETH_wei × 预言机价格) ÷ (ETH_DECIMALS × PRICE_DECIMALS)*/function ethToUsd(uint256 ethWei) external view returns (uint256) {uint256 ethUsdPrice = getLatestEthUsdPrice(); // 预言机价格(放大1e8后)// 计算:(ethWei * 价格) / (1e18 * 1e8) → 转换为USDuint256 usd = (ethWei * ethUsdPrice) / (ETH_DECIMALS * PRICE_DECIMALS);return usd * USD_DECIMALS; // 按USD精度返回(可选)}/*** 功能2:USD转ETH(输入USD单位,返回wei)* 公式:ETH_wei = (USD × ETH_DECIMALS × PRICE_DECIMALS) ÷ (预言机价格 × USD_DECIMALS)*/function usdToEth(uint256 usd) external view returns (uint256) {uint256 ethUsdPrice = getLatestEthUsdPrice(); // 预言机价格(放大1e8后)// 计算:(usd * 1e18 * 1e8) / (价格 * 1e18) → 简化为 (usd * 1e8) / 价格uint256 ethWei = (usd * PRICE_DECIMALS) / ethUsdPrice;return ethWei;}
}

五、关键公式解析

1. ETH转USD(已知ETH数量,求USD)
  • 现实公式:USD金额 = ETH数量(ETH) × ETH/USD价格(USD/ETH)
  • 链上转换(ETH以wei为单位):
    • ETH数量(ETH)= ethWei ÷ 1e18(将wei转为ETH)
    • ETH/USD价格 = 预言机价格 ÷ 1e8(将放大后的整数转为实际价格)
    • 合并得:USD = (ethWei × 预言机价格) ÷ (1e18 × 1e8)
2. USD转ETH(已知USD金额,求ETH)
  • 现实公式:ETH数量(ETH)= USD金额 ÷ ETH/USD价格(USD/ETH)
  • 链上转换(ETH以wei为单位):
    • ETH数量(wei)= ETH数量(ETH) × 1e18
    • 合并得:ETH_wei = (USD金额 × 1e18 × 1e8) ÷ 预言机价格

六、测试与验证

假设预言机返回的ETH/USD价格为200012345678(即2000.12345678 USD/ETH):

  • 测试ethToUsd(1e18)(1 ETH):
    计算:(1e18 × 200012345678) ÷ (1e18 × 1e8) = 200012345678 ÷ 1e8 = 2000.12345678 → 返回2000.12345678 USD(按USD_DECIMALS转换后为对应整数)。

  • 测试usdToEth(200012345678)(2000.12345678 USD):
    计算:(200012345678 × 1e8) ÷ 200012345678 = 1e8 → 1e8 wei?不,这里需要注意USD的单位:如果USD_DECIMALS是1e18,实际输入的USD应为2000.12345678 × 1e18,计算后得到1e18 wei(1 ETH)。

七、注意事项

  1. 价格新鲜度:必须检查updatedAt,避免使用过时价格(如超过1小时)。
  2. 精度匹配:根据业务需求调整USD_DECIMALS(如1 USD = 1e6单位表示“分”)。
  3. 异常处理:确保预言机返回的价格为正数,避免计算错误。
  4. 网络适配:不同网络的预言机地址不同(如主网与测试网),需对应修改。

通过以上步骤,你可以在Solidity中利用预言机实现ETH与USD的精准换算,核心是理解“放大倍数”和“整数运算”的逻辑,避免小数误差。

http://www.dtcms.com/a/306819.html

相关文章:

  • 技术人生——第17集:京城首发,AI叩问
  • C++中sizeof运算符全面详解和代码示例
  • 15.网络编程:让程序学会上网
  • 【读书笔记】设计数据密集型应用 DDIA 第二章
  • RPA软件推荐:提升企业自动化效率
  • 无线土壤水分传感器的结构组成及工作特点
  • Vue 3 入门教程 3- 响应式系统
  • Qt知识点3『自定义属性的样式表失败问题』
  • 飞算JavaAI自动设计表结构:重塑数据库开发新范式
  • 土木工程相关优化的C++实践
  • 《Spring Security源码深度剖析:Filter链与权限控制模型》
  • GitHub 上 Star 数量前 8 的开源 MCP 项目
  • <RT1176系列13>LWIP概念介绍
  • CSS 常用属性汇总
  • Thales靶场通关攻略
  • 【25-cv-08323】Keith携Olha Moroz13张版权画发案!
  • JAVAEE--4.多线程案例
  • Kettle 开源ETL数据迁移工具从入门到实战
  • 【swoole Windows 开发(swoole-cli 开发 hyperf)】
  • SpringBoot升级2.5.3 2.6.8
  • 原生C++实现信号与槽机制:原理详解
  • 【案例教程】基于python多光谱遥感数据处理、图像分类、定量评估及机器学习方法应用
  • 自定义Linux登录前的欢迎信息
  • 无人机入门--个人笔记
  • Set集合
  • Windows管理用户脚本
  • 多元线性回归方程的原理解析与案例
  • 【硬件】Verilog相关
  • 高程DEM文件下载
  • 开发避坑短篇(9):解决升级Vue3后slot attributes废弃警告