本文介绍了如何在Solidity智能合约中使用Flare的FTSOv2,并解释了其特性,以及如何在dApp中高效集成FTSOv2。此外,文章通过一个众筹dApp的实例,展示了如何利用FTSOv2的实时价格数据将FLR捐款动态转换为美元,从而实现以美元为目标的捐款筹集。
本文将指导你了解在 Solidity 智能合约中使用 Flare 的 FTSOv2 的技术细节,解释其功能,并为在 dApp 中进行高效集成提供参考。
智能合约是在区块链 VM 上运行的独立的代码片段。 它们无法知道任何动态的现实世界信息,例如 - “谁是美国现任总统?” 或 “现在 BTC 的价格是多少?” - 除非提供手动输入。
预言机使这成为可能,它以“去中心化”的方式向智能合约提供外部数据。 但是这些预言机是区块链的外部提供商,这意味着你的合约现在并非完全封闭,它们有一条来自外部世界的管道,并且该管道可能会被切断,或者有奇怪的东西流入。 明白了吗? 这意味着使用预言机将你的应用程序的有效控制权从你手中转移出去,并与预言机提供商共享。
Flare Network 的构建旨在解决这个问题。 它是一个具有 FTSO 的区块链,FTSO 是一种嵌入式预言机:一种内置于网络中的数据系统,嵌入在网络本身中。 这意味着你对预言机的信任程度与对区块链的信任程度相同,这使得 Flare 成为数据区块链。 公平吗?
现在问问自己,对于构建数据驱动的 dApp(或 3dApp,这是我刚才自己创造的一个术语)来说,这难道不是最好的解决方案吗? 我的意思是,你完全在链上工作,并在链中工作,并以最可靠的方式获得实时数据。
那么让我们在 Flare 上构建吧!
Flare 时间序列预言机(FTSO)v2 是 Flare Network 上的一个去中心化预言机系统,它为各种资产提供实时、可靠和防篡改的价格信息。 将 FTSOv2 集成到你的智能合约中,使你能够构建高级 DeFi、预测市场和其他需要准确链上价格数据的 dApp。
了解更多 - https://dev.flare.network/ftso/overview
你可以记住的是,FTSO 协议在将外部数据引入链上时不会损害安全性——它嵌入在 Flare 的核心共识和网络架构中。 这与依赖于单独的链下节点网络来收集、聚合并将数据发布到智能合约的其他预言机系统从根本上不同。
这确保了数据是原生验证的、透明的,并且由保护 Flare 链本身的相同机制保护,从而减少了外部信任假设并提高了链上应用程序的可组合性。
FTSO 提供:
它是 Flare 上 DeFi 协议的核心构建块,支持价格保护的众筹、合成资产等用例。
示例 Feed ID
所有 Feed ID 可在此处获得 - https://dev.flare.network/ftso/scaling/anchor-feeds。
你需要 FtsoV2Interface 和 ContractRegistry 的 ABI 或接口定义。 这些可在 Flare periphery contracts 包中找到。
import {FtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/FtsoV2Interface.sol";
import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
bytes21 public constant FLR_USD = 0x01464c522f55534400000000000000000000000000;
function getFlrUsdPrice() public returns (uint256 price, int8 decimals, uint64 timestamp) {
FtsoV2Interface ftsoV2 = ContractRegistry.getFtsoV2();
return ftsoV2.getFeedById(FLR_USD_ID);
}
ftsoV2.getFeedById(FLR_USD_ID) 返回你 -
FTSO 价格返回时带有一个小数位数 值。 始终相应地缩放你的计算:
(uint256 price, int8 decimals, ) = getFlrUsdPrice();
uint256 usdValue = (amountInFlr * price) / (10 ** uint8(decimals));
我已经准备了一个示例实现供你参考—
Github 链接 — 存储库包含一个完整的 CrowdFunding dApp,可帮助你筹集以美元为单位的目标捐款,但以 FLR 为单位付款。 使用 FTSOv2 通过实时价格信息动态地将 FLR 捐款转换为美元。
Youtube 教程— 视频中,我帮助解释和开发该应用程序。
Faucet-获取 Coston2 测试网的测试代币
你可以在 README 文件和 Youtube 视频中找到你需要的一切。
免费加入 Medium 以获取来自此作者的更新。
有两个合约在
backend/contracts/—
//在存储库中查找整个合约
....
....
function createCampaign(
address _beneficiary,
uint256 _fundingGoalInUsd,
uint256 _durationInDays,
string memory _title
) external returns (address) {
CrowdfundingCampaign newCampaign = new CrowdfundingCampaign(
msg.sender,
_beneficiary,
_fundingGoalInUsd,
_durationInDays,
_title
);
....
....
function getCampaignCount() external view returns (uint256 count) {
return campaigns.length;
}
function getCampaigns() external view returns (address[] memory) {
return campaigns;
}
function getCreatorCampaignCount(address creator) external view returns (uint256 count) {
return creatorCampaigns[creator].length;
}
function getCreatorCampaigns(address creator) external view returns (address[] memory) {
return creatorCampaigns[creator];
}
2. CrowdFundingCampaign.sol — 从 Factory 合约创建,处理从接收捐款到从 FTSOv2 获取数据再到处理 campaign 的最终确定以及在截止日期前未达到目标时申请退款的所有事情。
....
....
function getFlrUsdPrice() public returns (uint256 price, int8 decimals, uint64 timestamp) {
FtsoV2Interface ftsov2 = ContractRegistry.getFtsoV2();
return ftsov2.getFeedById(FLR_USD_ID);
}
function contribute() external payable nonReentrant {
require(!campaignClosed, "Campaign Closed");
require(block.timestamp <= deadline, "Deadline passed");
require(msg.value > 0, "Zero contribution");
contributions[msg.sender] += msg.value;
totalFundsRaised += msg.value;
emit FundingReceived(msg.sender, msg.value, totalFundsRaised);
checkGoalReached();
}
function checkGoalReached() public {
if (campaignClosed) return;
(uint256 currentPrice, int8 currentDecimals, ) = getFlrUsdPrice();
uint256 raisedValueInUsd = (totalFundsRaised * currentPrice) / (10 ** uint8(currentDecimals));
if (raisedValueInUsd >= fundingGoalInUsd) {
fundingGoalReached = true;
}
}
....
function claimRefund() external nonReentrant {...}
function withdrawFunds() external nonReentrant {...}
function finalizeCampaign() external onlyOwner nonReentrant {...}
function getCampaignInfo() external view returns (...}
backend/scripts/deploy.ts —
部署和测试脚本(需要五个帐户进行测试,因此请将 5 个私钥粘贴到 .env 中)
PRIVATE_KEY_1=""
PRIVATE_KEY_2=""
PRIVATE_KEY_3=""
PRIVATE_KEY_4=""
PRIVATE_KEY_5=""
进入 /backend 文件夹并运行(按顺序)-
npx hardhat compile
npx hardhat run scripts/deploy.ts --network coston2
你应该看到类似以下的输出 —
浏览 deploy.ts 并尝试匹配合约中的函数,然后注意此输出如何显示 dApp 的真实场景
这很重要。 Factory 合约是你需要在前端中使用它来与合约交互并创建 campaign,以及各自的 ABI。
--- 部署 FACTORY ---
CrowdfundingFactory deployed to: 0x1300d4F7181316E25E9E060F20257c41c7Fd51a8
尝试从临时 campaign 获取实时 FLR/USD 价格...
成功获取 FLR/USD 价格:0.02474(原始值:247400,FTSO 小数位数:7)
好的,你的 CrowdFundingFactory 合约已部署。
现在 /frontend/ 中的前端
是使用 NextJs、用于钱包连接的 RainbowKit 以及用于交互的 Wagmi 和 Viem 构建的。
但在我们继续之前,请回到
/backend/artifacts/contracts
并找到合约的 JSON ABI。
复制它们,并替换
/frontend/src/abis
中的现有 ABI
现在转到
frontend/src/hooks/useCrowdfunding.ts —
它包含 React 组件中使用的所有函数,以简化与合约的交互、处理价格等。
你可以在第一行看到—
// src/hooks/useCrowdfunding.ts
import { useMemo } from 'react';
import { useReadContract, useWriteContract, useWaitForTransactionReceipt, useAccount } from 'wagmi';
import { parseEther, formatUnits, type Address } from 'viem'; // 从此处删除 parseUnits,因为它不用于 createCampaign
import type { Abi } from 'viem';
//abi import
import CrowdfundingFactoryJSON from '../abis/CrowdfundingFactory.json';
import CrowdfundingCampaignJSON from '../abis/CrowdfundingCampaign.json';
// 替换为你实际部署的 factory 地址
const FACTORY_ADDRESS = '' as const;
在这里粘贴我们之前谈到的 Factory 地址:
// 替换为你实际部署的 factory 地址
const FACTORY_ADDRESS = '' as const;
现在浏览此文件中的所有 hook 及其函数,例如:
useCrowdfundingFactory, useCrowdfundingCampaign
handleCreateCampaign, handleContribute, handleFinalizeCampaign, handleWithdrawFunds, handleClaimRefund.
这些是处理程序,可以简化从前端的按钮与实际部署的合约进行交互的过程。
现在,你有一个可供使用的 dApp。
只需转到 /frontend 并运行(按顺序)—
npm i
npm run dev
在你的浏览器上转到 http://localhost:3000/,你应该看到类似以下内容:
继续,连接你的钱包并尝试一下。 当你看到 FTSOv2 价格 feed 对 FLR/USD 的动态定价时,之前的所有步骤现在都应该有意义了。
希望本文能帮助你使用 FTSOv2 构建,并为你提供灵感和指导,以构建一些使用价格 feed 的炫酷 dApp。
在 Twitter 上与我联系,或在下方发表评论——欢迎提供反馈、问题和构建!
- 原文链接: blog.blockmagnates.com/h...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!