关于以太坊链上ETH转USD的转换逻辑
在编写合约中,觉得ETH转USD的金额转换很绕,因此记录一下。
这是一份合约代码:
pragma solidity ^0.8.0;
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
//1、创建一个收款函数
//2、记录投资人并且查看
//3、在锁定期内,达到目标值,生产商可以提款
//4、在锁定期内,没有达到目标值,投资人在锁定期以后退款
contract FundMe{
AggregatorV3Interface internal dataFeed;
//投资人
mapping(address =>uint256) public fundersToAmount;
event EthToUsdEvent(string message ,uint256 money);
event MoneySumEvent(string message, uint256 money);
//最小额度
uint256 MININUM_VALUE = 100 * 10 **18; //usd
//关于TARGET为什么是1000 * 10 ** 18,因为合约中默认的金额但是为wei,此处的TARGET是wei的USD
uint256 constant TARGET = 1000 * 10 ** 18; //目标值是1000
function fund() external payable {
//fundersToAmount[msg.sender] = fundersToAmount[msg.sender]+msg.value;
//限定最小额度
uint256 money = convertEthToUsd(msg.value);
emit EthToUsdEvent("convert monry is:",money);
/**
* 下面这一行代码等同于
*uint256 convertToRealMoney = money/(10 **18);
*require(money >= 100,"send more ETH");
*/
require(money >= MININUM_VALUE,"send more ETH");
fundersToAmount[msg.sender] = msg.value;
}
constructor(){
//Sepolia Testnet的USD-ETH的地址
dataFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
}
function getBalanceOf() public view returns (uint){
return address(this).balance;
}
function getChainLinkDataFeedLatestAnswer() public view returns (int){
//prettier-ignore
(
/*uint80 roundID */,
int answer,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = dataFeed.latestRoundData();
return answer;
}
//返回wei对应的usd
function convertEthToUsd(uint256 ethAmount) internal view returns(uint256){
//此处的ethAmount单位是wei,这块不能用ethAmount/(10 **18),有可能是小数
uint256 ethPrice = uint256(getChainLinkDataFeedLatestAnswer());
return ethAmount * ethPrice / (10 **8);
}
/**
* @dev 提款功能,关于
*/
function getFund() external{
uint256 moneySum = convertEthToUsd(address(this).balance);
emit MoneySumEvent("The money sum is:",moneySum);
require( moneySum>= TARGET,"Target is not reached");
}
}
疑问:开始始终搞不明白100 * 10 **18为什么要这么写:uint256 MININUM_VALUE = 100 * 10 **18;
- 首先以fund()函数为例,在remix中输入eth金额,
- 点击fund,fund()函数内部调用convertEthToUsd(msg.value),
- 注意,在return ethAmount * ethPrice / (10 8)中除以(108)是因为Chainlink返回的汇率单位是 “美元价格 ×
1e8”,而ethAmount的单位是wei,所以想要得到真是wei对应usd的价格需要除以(10 **8)。 - 这行代码中require(money >= MININUM_VALUE,"send more ETH");money是wei对应的usd价格,所以需要用
MININUM_VALUE要用100 * 10 **18表示。 - 当然,这行代码也可以这样写,更容易理解:
function fund() external payable {
//fundersToAmount[msg.sender] = fundersToAmount[msg.sender]+msg.value;
//限定最小额度
uint256 money = convertEthToUsd(msg.value);
emit EthToUsdEvent("convert monry is:",money);
uint256 convertRealMoney = money/(10 **18);
require(convertRealMoney >= 100,"send more ETH");
fundersToAmount[msg.sender] = msg.value;
}
- 在这行代码中,uint256 convertRealMoney = money/(10 **18);先除以10 **18,再和100比较。

浙公网安备 33010602011771号