与以太坊预言机交互

区块链 2026-03-28

深入探索使用 Remix IDE 的以太坊预言机世界。本文会教你怎么把区块链上的智能合约和区块链外的数据连接在一起。从基础知识到实际部署,这门课一应俱全。

以太坊预言机(Ethereum Oracles)介绍

预言机就像是一座桥梁,它连接了智能合约的确定性和现实世界的不断变化。本课程的目标是解读预言机背后的复杂性,让它们变得更易于理解和接近。

预言机(Oracles)的意义何在?

以太坊的去中心化网络和其智能合约与现实世界是完全隔绝的。这种隔绝确保了一致性、安全性和完整性。然而,这也带来了一个局限性:这些智能合约不能自行访问或验证外部数据。那么,如果一个合约的执行依赖于当前的黄金价格、特定城市的天气状况,或者选举结果呢?

预言机填补了这个鸿沟。作为信使,它们收集、验证并将现实世界的信息传递给智能合约,从而扩大了去中心化应用的可能性范围。

试想以下的情况:

Solidity
contract GoldPriceBet {
    Oracle oracleInstance;  // An oracle instance providing real-time gold prices
    address bettor;
    uint256 wagerAmount;
    function placeGoldPriceBet(uint predictedPrice) external payable {
        bettor = msg.sender;
        wagerAmount = msg.value;
        // Here, we would typically invoke the oracle to fetch the current gold price
    }
}
// A mock smart contract requiring external data

代码注释:

Oracle oracleInstance; 这是一个占位符,用于我们的 GoldPriceBet 合约与之交互以获取当前黄金价格的预言机(Oracle)合约。

placeGoldPriceBet 函数允许用户下注预测黄金价格。理想情况下,在下注后,预言机将被调用以获取实时的黄金价格并确定结果。

多样化的预言机生态

大致上来说,预言机分为两大类:

中心化预言机

由单一实体或组织运营,中心化预言机效率高,能快速获取数据。然而,它们的致命弱点是信任。智能合约的执行依赖于这个中心化实体的诚信。被操纵或错误的数据可能导致意外的结果。

去中心化预言机

为了减轻中心化系统的缺点,去中心化预言机应运而生。在这里,多个预言机组成的网络提供数据。智能合约可能采用聚合方法,如平均值或中位数,以得出一个值。通过分散数据来源,这些预言机减小了与人为操纵或单点故障相关的风险。

Solidity
// An illustrative smart contract leveraging a decentralized oracle framework
contract CommodityPriceFeed {
    DecentralizedOracle[] oracleArray;  // An array of decentralized oracles
    function deriveAveragePrice() external view returns (uint256) {
        uint256 cumulativeValue = 0;
        for (uint i = 0; i < oracleArray.length; i++) {
            cumulativeValue += oracleArray[i].fetchPrice();
        }
        return cumulativeValue / oracleArray.length;
    }
}

代码注释:

DecentralizedOracle[] oracleArray;这是一个数组,用于存储多个去中心化预言机的实例。

deriveAveragePrice 函数计算从oracleArray中所有预言机获取的平均价格。它遍历每一个预言机,获取价格,然后除以预言机的数量以得到平均值。

现实世界中的预言机应用

预言机的潜在应用非常广泛和多元:

金融衍生品:像期权这样的金融工具需要访问现实世界资产价格来执行合约。

智能保险:想象一下,一个旅行保险智能合约能够自动地在航班延误时补偿用户,这些数据来自于一个航空预言机。

供应链验证:通过将外部数据输入到区块链中,可以实现产品从制造到客户交付的实时跟踪。

去中心化游戏:基于区块链的在线游戏可以利用预言机根据现实世界事件(如体育比赛结果)来影响游戏结果。

阅读更多关于预言机的文章: What Is an Oracle in Blockchain?

金融衍生品与交易平台

金融平台需要实时的资产价格、利率或其他经济指标信息。去中心化衍生品平台使用预言机来确保合约,如期货和期权,基于准确、防篡改的市场数据进行结算。

Solidity
solidityCopy code
// An example smart contract for a decentralized option
contract DecentralizedOption {
    Oracle priceOracle;
    uint256 strikePrice = 1000;  // Example value
    function exerciseOption() external {
        uint256 currentPrice = priceOracle.fetchCurrentPrice();
        if (currentPrice > strikePrice) {
            // Logic to exercise the option
        }
    }
}

代码注释:

DecentralizedOption 合约与预言机交互以获取当前价格。

当用户行使期权时,合约会根据预定义的执行价格检查当前价格以确定结果。

智能保险

预言机促进了去中心化保险平台的发展,提供诸如农作物保险所需的天气模式、旅行保险所需的航班状态,或地震保险所需的地震活动等数据。

Solidity
contract FlightDelayInsurance {
    Oracle flightStatusOracle;
    function claimInsurance(string flightNumber) external {
        string status = flightStatusOracle.getFlightStatus(flightNumber);
        if (strcmp(status, "Delayed") == 0) {
            // Logic to compensate the insured
        }
    }
}

代码注释:

FlightDelayInsurance 合约使用预言机获取航班状态。

根据航班的状态,如果航班延误,它会对被保险人进行赔偿。

供应链验证

对于去中心化的供应链解决方案,预言机可以在每个阶段提供可验证的数据,从原材料采购到产品交付,以确保产品的真实性和道德采购。

Solidity
contract SupplyChainTracker {
    Oracle locationOracle;
    address productOwner;
    function verifyProductLocation(address productID) external view returns (string memory) {
        return locationOracle.fetchProductLocation(productID);
    }
}

代码注释:

此合约使用预言机在供应链的任何阶段获取产品的位置。

它可以用于跟踪产品并验证其来源和路线。

去中心化游戏

集成现实世界事件(如体育赛事结果或股市走势)的游戏可以通过使用预言机获取必要的数据以去中心化的方式构建。

Solidity
contract SportsBet {
    Oracle sportsResultOracle;
    function placeBet(string teamName) external payable {
        // Logic for placing a bet
    }
    function resolveBet() external {
        string winningTeam = sportsResultOracle.getMatchResult();
        // Logic to reward winners based on the outcome
    }
}

代码注释:

SportsBet 允许用户对体育赛事结果进行下注。

然后它与预言机交互以获取比赛结果,并相应地解决下注。

现在我们已经初步探索了以太坊预言机的世界。在后续的课程中,我们将深入探讨预言机与智能合约集成的复杂性。如果内容让你感觉很兴奋,请继续保持你的学习热情。因为去中心化数据的世界正在向我们招手!

为预言机交互设置Remix

对于许多以太坊开发者来说,Remix 是一个一站式的解决方案。它是一个强大的工具,可以处理从智能合约开发到部署的一切。在这一课中,我们将设置 Remix 以与预言机交互,为我们的合约获取现实世界的数据。

配置Remix:环境准备

在开始之前,请确保您已在浏览器中打开了 Remix IDE。为了获得最佳的体验和兼容性,请使用该工具的最新版本。

Solidity 版本: 请确保您正在使用 v0.8.21 版本的Solidity。您可以在智能合约的开头指定这一点,如下:

Solidity
pragma solidity ^0.8.21;

环境选择: 在左侧面板中,点击“部署 & 运行交易”选项卡,在那里确保选择 Injected provider 环境。这样可以将 Remix 连接到您的 MetaMask,方便您在后续课程中轻松地部署到 Goerli 测试网。

导入预言机库: 利用现有的工具和代码库

Chainlink 作为一个主要的预言机提供商,提供了为各种版本的 Solidity 语言量身定制的合约。要在 Remix 中使用它们:

在您的 Solidity 文件的顶部,导入必要的 Chainlink 合约。对于 0.8.x,您的导入可能看起来像这样:

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

如果 Remix 提示您从 GitHub 导入文件,请接受并继续。这将自动从 Chainlink 的 GitHub 代码库中获取必要的合约文件。

连接外部数据源:如何获取外部信息

有了必要的代码库设置,我们就可以将我们的合约连接到一个外部数据源。Chainlink 使用一个预言机节点网络来为智能合约提供数据。

价格提要:Chainlink 的价格提要合约是链上参考数据点。要使用它们,请在您的合约中使用适当的合约地址(例如,ETH/USD 价格提要)实例化价格提要。以下是一个示例:

Solidity
AggregatorV3Interface internal priceFeed = AggregatorV3Interface(0xYourContractAddressHere);

自定义数据请求:Chainlink 也允许向任何外部 API 发送自定义数据请求。这需要更复杂的设置,我们将在后续课程中进行探讨。

到这里,您的 Remix 环境应该已经为集成预言机的智能合约开发做好了准备。完成这些步骤后,我们下一课将引导您编写一个能够获取和处理现实世界数据的合约。

构建一个简单的集成了预言机的合约

现在我们已经设置好了 Remix IDE,并导入了必要的 Chainlink 库,我们将编写一个基础的智能合约,该合约将与预言机集成。这将使我们能够获取和处理外部数据。

草拟智能合约:预言机集成的基础

从基础开始:

让我们首先定义我们的合约,指定 Solidity 版本,并导入我们将使用的 Chainlink 代码库:

```
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import “@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol”;
contract OracleIntegratedContract {
AggregatorV3Interface internal priceFeed;
// Visibility for constructor removed
constructor(address _priceFeed) {
    priceFeed = AggregatorV3Interface(_priceFeed);
}

1. 

在这个部分,我们已经指定我们的合约将使用 Chainlink 价格预言机。构造函数接受以太坊网络上价格预言机合约的地址。

1. 

从预言机获取数据

1. 

让我们扩展我们的合约以获取最新的以太坊价格:

Solidity
function getLatestEthPrice() public view returns (int) {
(,int price,,,) = priceFeed.latestRoundData();
return price;
}

1. 

Chainlink聚合接口的 `latestRoundData()` 函数为我们提供了各种数据,包括最新的价格。


## 处理预言机响应:收到数据后管理数据


从预言机获取的数据通常以原始格式提供,可能不立即适用于我们的需求。在我们的智能合约中正确处理这些数据至关重要:

1. 

格式化数据

1. 

假设预言机以美元为单位返回以太坊的价格,但乘以 10^8 以确保没有小数位(这在预言机设置中很常见)。要获得实际价格,您需要格式化数据:

Solidity
function getFormattedEthPrice() public view returns (int) {
int rawPrice = getLatestEthPrice();
return rawPrice / 10**8;
}

1. 

这个函数获取原始价格数据,然后除以 10^8 以获得现实世界的价值。

1. 

错误处理


1. 

总是要考虑预言机获取数据失败的可能性:

Solidity
function safeGetLatestEthPrice() public view returns (int) {
(,int price,,uint256 timestamp,) = priceFeed.latestRoundData();
require(timestamp > 0, “Failed to fetch data from the oracle”);
return price;
}

1. 

在这里, `latestRoundData()` 函数还提供了一个时间戳。如果时间戳是 0,那很可能意味着预言机未能获取数据,我们通过一个`require` 语句来处理这种情况。

你的完整代码应显示如下:

Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import “@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol”;
contract OracleIntegratedContract {
AggregatorV3Interface internal priceFeed;
// Visibility for constructor removed
constructor(address _priceFeed) {
    priceFeed = AggregatorV3Interface(_priceFeed);
}
function getLatestEthPrice() public view returns (int) {
    (,int price,,,) = priceFeed.latestRoundData();
    return price;
}
function getFormattedEthPrice() public view returns (int) {
    int rawPrice = getLatestEthPrice();
    return rawPrice / 10**8;
}
function safeGetLatestEthPrice() public view returns (int) {
    (,int price,,uint256 timestamp,) = priceFeed.latestRoundData();
    require(timestamp > 0, "Failed to fetch data from the oracle");
    return price;
}
    }
```

270

您应该能够在 Remix 中编写一个简单的智能合约,该合约可以使用预言机来获取最新的以太坊价格并处理返回的数据。 在下一节课中,我们将学习如何部署该合约,使用预言机的最佳实践和其中的细微差别。

在 Goerli 测试网上部署和测试

在我们探索以太坊预言机的过程中,我们已经达到了一个阶段,我们希望在本地开发环境以外看到我们的合约运作。部署到测试网允许我们与我们的合约互动,就好像它在主要以太坊网络上一样,但不涉及相关的费用。在这堂课中,我们将逐步介绍如何将我们的预言机集成合约部署到Goerli测试网,并测试其功能。

准备工作:获取测试网以太币并且设定环境

获取测试网以太币

要在Goerli测试网上部署合同,您需要测试币 Goerli ETH(GoerliETH)。虽然它不具有任何实际价值,但它对于支付测试网络上的交易费用至关重要。

Metamask:确保您的Metamask已切换到Goerli测试网络。

前往 Goerli faucet (Goerli水龙头)请求一些GoerliETH。只需粘贴您的Goerli测试网络以太坊地址,您应该会很快就能收到测试币。

在 Remix 中配置 Goerli 测试网部署

在Remix中, 找到 Deploy & Run Transactions 选项。

在 Environment 选项中,选择 Injected Provider。此选项允许 Remix 连接到您的 Metamask 当前设置的任何网络,该网络应该是 Goerli 测试网。

确保在Contract 的下拉列表中选择了您的合约OracleIntegratedContract。

在 Account 下拉列表中,您应该看到您的 Goerli 测试网以太坊地址。

部署:将您的预言机集成合约上线到 Goerli

准备合约部署

在部署之前,您需要一个 Goerli 网络上的 Chainlink 价格预言机的地址。在本例中,我们将使用 ETH/USD 价格预言机。您通常可以在 Chainlink 文档中或通过在 Etherscan 等网站上浏览 Chainlink 合约来找到这些地址。关于测试网预言机地址,请查看此处: Testnet Oracles | Chainlink Documentation

复制您要使用的 Chainlink 价格预言机的 Goerli 测试网地址。在本例中的地址是:0xCC79157eb46F5624204f47AB42b3906cAA40eaB7

回到 Remix 在 Deploy & Run Transactions 选项中,确保您的合约 OracleIntegratedContract在Contract 的下拉列表中被选中。

将复制的地址粘贴到 Deploy 按钮下方的字段中(这是您提供构造函数参数的地方)。

启动部署

填写价格预言机地址后,单击 Deploy 按钮。

Metamask 将提示您确认交易。检查燃气(Gas)价格和燃气上限(Max fee),确保一切内容正确,然后确认交易。

270

交易被添加到区块链中并得到确认后,您将在 Remix 中看到一个日志,其中包含部署的详细信息。您可以单击合约地址在 Goerli Etherscan 上查看合约。

测试预言机器响应:验证合约与预言机的交互

现在合约已经部署,可以测试它的功能了

在Remix的 Deployed Contracts 部分,你应该能看到你的 OracleIntegratedContract。

270

展开已部署合约的详细信息,以查看可用的功能。

在进行任何调用之前,你需要在你的 Goerli 测试网地址上获取一些 LINK 代币,你可以在这里请求一些:https://faucets.chain.link/goerli

270

一旦收到,要检查余额,你可以在 Goerli 上将 LINK 添加到你的 Metamask。你可以在这里找到相关信息: https://docs.chain.link/resources/link-token-contracts

或者,您也可以手动添加合约地址,如下所示:

270

通过点击它来调用 getLatestEthPrice 函数。它应该以原始格式返回最新的 ETH 价格。

现在,调用 getFormattedEthPrice 函数。此功能以更易读的格式返回价格。

最后,调用 safeGetLatestEthPrice 函数以确保存在数据获取安全检查。

恭喜!你已成功在 Goerli 测试网上部署并测试了一个与 Oracle 预言机集成的合约。这种实际经验是无价之宝,因为它让你离在 Ethereum 主网上部署更近了一步。在我们的下一课中,我们将深入探讨最佳实践和需要注意的常见陷阱。

最佳实践和常见陷阱

在使用预言机并将其集成到您的以太坊智能合约中时,遵循最佳实践至关重要。这不仅确保了合约的功能性,也确保了合约的安全性和成本效益。本课将介绍使用预言机时的关键注意事项。

安全性考虑

数据完整性和信任

数据来源的可信度:始终确保你访问的预言机从可靠的来源获取数据。

中间人攻击:数据在传输过程中可能被篡改。确保有像 SSL/TLS 这样的机制来保护数据。

去中心化预言机

使用多个预言机或像 Chainlink 这样的去中心化预言机网络有助于降低接收错误数据的风险。

数据验证

在使用预言机返回的数据进行业务逻辑处理之前,请务必验证从预言机接收到的数据。

优化燃气费用

在进行外部调用,尤其是到预言机时,燃气费用可能会迅速上升。这里有一些策略:

限制预言机调用

只有在必要时才请求数据。不必要的调用会浪费 Gas 和预言机的查询费用。

批量请求

如果可能,将多个数据请求一起批量处理,而不是进行单独的调用。

优化数据存储

存储更少的数据可以节省燃气费。在将其存储在合约中之前,请考虑解析度和减少数据。

常见问题排查

预言机无响应:这通常可能是由于合约中缺少 LINK 代币或预言机地址或 Job ID 不正确。始终验证这些详细信息。

燃料限制错误:在调用发出预言机请求的函数时,Gas 估算有时可能不准。您可能需要手动设置更高的 Gas 限制。

数据格式不正确:确保你期望的数据格式与预言机发送的匹配。使用适当的解析函数来处理数据。

部署问题:尤其在公共测试网上,始终确保你使用的是正确的网络详细信息,如预言机地址、代币地址和网络 RPC URL。

预言机为智能合约开辟了一系列新机会,使它们能够与外部世界的数据进行交互。然而,这些增强的功能也带来了额外的复杂性。对开发者来说,深入了解预言机的细微差别并对常见陷阱保持警惕,对于构建更具弹性和多功能的去中心化应用至关重要。持续学习并保持对以太坊和 Chainlink 生态系统中最新进展的了解是必不可少的。

免责声明:本网站、超链接、相关应用程序、论坛、博客等媒体账户以及其他平台和用户发布的所有内容均来源于第三方平台及平台用户。网站及其内容不作任何类型的保证,网站所有区块链相关数据以及其他内容资料仅供用户学习及研究之用,不构成任何投资、法律等其他领域的建议和依据。用户以及其他第三方平台在本网站发布的任何内容均由其个人负责,与本网无关。

相关文章