Ich speichere den USD-Wert eines Produkts im Vertrag.mapping (string => uint256) productUSD;
Wenn es zum Beispiel 52 $ kostet, würde ich es speichern alsproductUSD[_product] = 52;
Wenn Leute jetzt in ETH bezahlen, möchte ich sicherstellen, dass sie einen korrekten umgerechneten Betrag eingeschickt haben.
dh0.013 ETH
Chainlink getThePrice()
gibt den neuesten ETH/USD
Preis zurück und stellte fest, dass er so zurückkehrte.price = 348365740274
function getThePrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return price;
}
Einfache Mathematik, ich kann 8 Dezimalstellen weglassen 348365740274
und verwenden 3483
, um einen umgerechneten ETH-Betrag zu erhalten
dh52 / 3483 = 0.0149296583405111 ETH
348365740274
require(msg.value >= ...)
In Bezug auf Chainlink-Preisfeeds haben ETH-Paare (USD/ETH, AAVE/ETH, UNI/ETH usw.) 18 Dezimalstellen, während Nicht-ETH-Paare (ETH/USD usw.) 8 Dezimalstellen haben. Quelle
Solidity Integer Division rundet automatisch in Richtung 0 abprice/10**8
.
Um zu überprüfen, ob der mit der Transaktion gesendete Wert größer als ein bestimmter Schwellenwert ist, wenn ETH mit USD verglichen wird, würden Sie den erforderlichen Mindestwert in USD durch USD pro ETH teilen, zum Beispiel:
int min_required = 50; // minimum required in USD
int _price = getThePrice() / 10 ** 8; // price of 1 ether in USD
require(msg.value >= min_required / _price, "NOT ENOUGH ETHER");
Sie können die Verwendung von Variablen weglassen, um Gas zu sparen, und Werte direkt verwenden, dies dient nur einer klareren Erklärung.
Wenn Sie eine Solidity-Compiler-Version unter 0.8.x verwenden, verwenden Sie SafeMath, um sich um Ganzzahlüberlauf und -unterlauf zu kümmern
Nein, ich glaube nicht, dass die Lösung von hack3r_Om funktioniert. Betrachten Sie mein Beispiel:
require(msg.value >= min_required / _price, "NOT ENOUGH ETHER");
wird niemals scheitern, denn 50/2000 = 0 in Solidität.
Meine Lösung ist laut PatrickAlphas Tutorial , dass Sie Ihren min_required und den von pricefeed zurückgegebenen Wert vor dem Teilen mit einer Zahl multiplizieren müssen, damit er nicht gerundet wird. Das ist mein Mustervertrag:
contract Test{
uint256 minRequiredUSD;
uint256 etherPriceUSD;
uint256 public minRequiredEther;
constructor() {
minRequiredUSD = 50*10**18; // multiply your minRequired to 10**18
etherPriceUSD = 2000*10**18; // multiply your etherPrice to 10**18
// this means (50*10*18)/2000, it converts your minReqiredEther to wei first
// before divide. The result is 25*10**15 wei.
minRequiredEther = (minRequiredUSD*10**18)/etherPriceUSD;
}
event ReceivedEther(uint256 _amount);
function donate() public payable {
require(msg.value > minRequireEther);
emit ReceivedEther(msg.value);
}
}
Paul Razvan Berg