如何使用JavaScript或Solidity在前端展示加密通证和法币价格

本文主要是介绍如何使用JavaScript或Solidity在前端展示加密通证和法币价格,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
原文链接:https://blog.chain.link/how-to-display-crypto-and-fiat-prices-on-a-frontend/

Web3开发者经常选择在前端显示平台或协议的原生加密通证,而不是显示与法币的转换结果。虽然这样做容易让用户聚焦原生通证,但显示法币转换结果可能是一个更好的选择。为加密通证定价要求对通证当前价值有了解,而通证的价值往往是波动的,而且还为新用户创造了一个不太受欢迎的体验,许多人对参考美元或他们的本地货币感到更舒服。

幸运的是,通过Chainlink Data Feeds,ETH和美元等货币之间的转换非常简单,这意味着开发者只需几个简单的步骤就能为用户提供更好的体验。本技术教程阐述了如何使用ETH/USD Chainlink Price Feed在前端显示加密通证和法币价格。

什么是Chainlink Data Feeds?

Chainlink Data Feeds是一套提供安全和可靠的真实世界数据源的智能合约。它们由独立的、高信誉的和地理上分布的节点运营商提供支持,这有助于确保返回数据的可靠性。例如,ETH/USD,目前利用31个独立的预言机,或者说信息来源,用于确定当前ETH对美元的价格的可信答案。

为什么我们需要31个信息源来获取相同的信息?使用多个来源来汇总一个有效的响应,意味着不可能有单点故障问题,并防止数据被篡改。

关于提供者(Provider)的说明

当与智能合约互动时,必须有一个Web3连接的提供者。通常,这可以通过用户的钱包连接获得。如果没有,或者你不需要连接用户的钱包,你可以通过以下方式完成同样的功能:

const provider = new ethers.providers.JsonRpcProvider('RPC_URL_HERE');

RPC_URL_HERE可以从一个节点提供商那里获得,如Alchemy, Infura, Moralis或QuickNode。提供者(provider)是我们通往区块链的 “网关”。

本教程的另一个要求是一个以太坊JavaScript库。在这个例子中,我使用的是ethers库。你需要安装它,才能让本文案例工作。

npm install --save ethers

使用JavaScript部署ETH/USD转换

现在是需要在前端显示ETH/USD价格的代码。

如果你想跟着做,这个例子的代码可以在例子库中找到。按照README.md中的说明,在本地运行这个例子。这个例子使用Svelte,但同样的概念应该适用于任何前端JavaScript框架,如React或Vue。在SmartContract的GitHub仓库中,你还可以使用其他几个入门套件。

这段代码可以通过导入语句在前端使用:

import { getETHPrice } from '../utils/getETHPrice';

然后,将结果存储为以美元计算的ETH价格:

value = await getETHPrice();

假设ethAmount是要转换的ETH数额,则使用此值从ETH转为美元。

usdValue = Number(ethAmount * value).toFixed(2);

这里是完整的文件:

~/utils/getEthPrice.jsimport { ethers } from 'ethers';export async function getETHPrice() {const provider = new ethers.providers.JsonRpcProvider('RPC_URL_HERE');// This constant describes the ABI interface of the contract, which will provide the price of ETH// It looks like a lot, and it is, but this information is generated when we compile the contract// We need to let ethers know how to interact with this contract.const aggregatorV3InterfaceABI = [{inputs: [],name: 'decimals',outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }],stateMutability: 'view',type: 'function'},{inputs: [],name: 'description',outputs: [{ internalType: 'string', name: '', type: 'string' }],stateMutability: 'view',type: 'function'},{inputs: [{ internalType: 'uint80', name: '_roundId', type: 'uint80' }],name: 'getRoundData',outputs: [{ internalType: 'uint80', name: 'roundId', type: 'uint80' },{ internalType: 'int256', name: 'answer', type: 'int256' },{ internalType: 'uint256', name: 'startedAt', type: 'uint256' },{ internalType: 'uint256', name: 'updatedAt', type: 'uint256' },{ internalType: 'uint80', name: 'answeredInRound', type: 'uint80' }],stateMutability: 'view',type: 'function'},{inputs: [],name: 'latestRoundData',outputs: [{ internalType: 'uint80', name: 'roundId', type: 'uint80' },{ internalType: 'int256', name: 'answer', type: 'int256' },{ internalType: 'uint256', name: 'startedAt', type: 'uint256' },{ internalType: 'uint256', name: 'updatedAt', type: 'uint256' },{ internalType: 'uint80', name: 'answeredInRound', type: 'uint80' }],stateMutability: 'view',type: 'function'},{inputs: [],name: 'version',outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],stateMutability: 'view',type: 'function'}];// The address of the contract which will provide the price of ETHconst addr = '0x8A753747A1Fa494EC906cE90E9f37563A8AF630e';// We create an instance of the contract which we can interact withconst priceFeed = new ethers.Contract(addr, aggregatorV3InterfaceABI, provider);// We get the data from the last round of the contract let roundData = await priceFeed.latestRoundData();// Determine how many decimals the price feed has (10**decimals)let decimals = await priceFeed.decimals();// We convert the price to a number and return itreturn Number((roundData.answer.toString() / Math.pow(10, decimals)).toFixed(2));
}

我们需要的代码中大部分是aggregatorV3InterfaceABI或ABI。这是我们将与之互动的合约的数据结构,我们需要让ethers知道这些。通常,你可能会在前端项目中把这些存储在单独的JSON文件中。在本例中,它被包含在utils文件中,这样是把所有内容都放在一起。

// The address of the contract which will provide the price of ETH
const addr = '0x8A753747A1Fa494EC906cE90E9f37563A8AF630e';

这个合约地址将根据网络或价格对的变化而变化;你可以使用这些Data Feed合约地址中的任何一个。

// We get the data from the last round of the contract 
let roundData = await priceFeed.latestRoundData();
// Determine how many decimals the price feed has (10**decimals)
let decimals = await priceFeed.decimals();
// We convert the price to a number and return it
return Number((roundData.answer.toString() / Math.pow(10, decimals)).toFixed(2));

与合约的交互是直接的。我们调用latestRoundData,它返回:
roundId:轮次ID。
answer: 价格。
startedAt:该轮次开始的时间戳。
updatedAt:这一轮更新的时间戳。
answeredInRound:计算结果的轮次ID。我们对answer感兴趣。这将是ETH的价格,有一个小的警告。我们需要知道答案中包含的小数点的数量。这就是decimals的作用。它返回要包含的小数位数。

我们使用answerdecimal来返回ETH的价格:

return Number((roundData.answer.toString() / Math.pow(10, decimals)).toFixed(2));

利用价格数据

一旦我们有了单个ETH的价格,我们可以用它来轻松地将ETH转换成美元价格。在下面的例子中,rawETH是一个合约的余额返回的字符串。

<!-- Display the raw ETH -->
{Number(rawETH).toFixed(8)} ETH
<!-- Display the ETH converted to USD -->
$ {(Number(rawETH) * value).toFixed(2)} USD

Chainlink Data Feeds提供了一个可靠的解决方案,它使用安全的方法将资产价值从ETH转换为美元。

使用Solidity

到目前为止,在一个前端应用程序中创建一个实用功能似乎很简单。但是,如果我们能够消除前端开发者对价格的担心,并为他们处理价格问题呢?

只要对你的合约做一些修改,你就可以向终端用户提供当前的价格数据–他们需要担心的是连接到你的合约。这就简化了所需的前端工作。让我们来看看一个合约的例子。

pragma solidity ^0.8.0;
// Import the chainlink Aggregator Interface
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";// Create the contract
contract YourAwesomeContract { 
// Declare the priceFeed as an Aggregator InterfaceAggregatorV3Interface internal priceFeed;constructor() {
/** Define the priceFeed
* Network: Rinkeby* Aggregator: ETH/USD* Address: 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e*/priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);} // OTHER CONTRACT LOGIC HERE/*** Returns the latest price and # of decimals to use*/function getLatestPrice() public view returns (int256, uint8) {
// Unused returned values are left out, hence lots of ","s(, int256 price, , , ) = priceFeed.latestRoundData();uint8 decimals = priceFeed.decimals();return (price, decimals);}
}

首先,我们导入我们在上述前端版本中使用的相同的聚合器接口。

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

然后,我们需要让聚合器知道我们感兴趣的Price Feed的合约地址。

priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);

在我们的getLatestPrice()函数中,我们调用priceFeed.latestRoundData()。priceFeed引用的是我们在上面的getETHPrice利用中使用的同一个合约。它返回:

roundId:轮次ID。
answer: 价格。
startedAt:该轮次开始的时间戳。
updatedAt:这一轮更新的时间戳。
answeredInRound:计算答案的那一轮的ID。

这里的代码可能看起来有点奇怪。我们唯一感兴趣的值是answer字段。因此,我们不把其他的值分配给变量。把它们跳过,可以防止储存未使用的数据。

(, int256 price, , , ) = priceFeed.latestRoundData();

对前端的改变

现在,价值数据已经包含在你的智能合约中,我们只需要从前端访问合约中该价值数据。

async function getETHPrice() {let [ethPrice, decimals] = await 
yourAwesomeContract.getLatestPrice();ethPrice = Number(ethPrice / Math.pow(10, 
decimals)).toFixed(2);return ethPrice;}

这将为我们合约的消费者创造一个更简单的界面,因为他们不需要了解预言机或导入一个单独的ABI。

总结

在这个技术教程中,我们展示了如何轻松地将Chainlink数据源集成到你的DApp中,使用户能够轻松使用USD/ETH价格转换。有大量适用于加密通证和法定货币的Chainlink Price Feeds,开发者们可以调整上面的使用步骤使用适用于他们的价格数据。
获取更多关于Chainlink的信息,请访问chain.link或在docs.chain.link阅读文档。要讨论集成问题,请联系专家。

这篇关于如何使用JavaScript或Solidity在前端展示加密通证和法币价格的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/417046

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程