是否有任何方法来获得任何密码货币的web3JS或稳健。我想做一些令人惊奇的事情:)
USDT和USDC也不是常数,除了将其值与常量符号(如USDT )进行比较之外,还有其他方法吗?
发布于 2022-08-08 03:11:59
根据埃瑟姆(氏)文献,您应该使用Oracle来完成此任务。
由于区块链是确定性的,所以首先需要将数据添加到区块链中。这是甲骨文智能合同的工作。他们从外部源接收数据,并通过事务保存到块链上。
我建议研究一下像链链数据馈送这样的东西,在本文撰写之时,它已经在9条链中有了数百个常见的配对。它们可以在智能合同中或在客户端使用。
如果创建自己的令牌,甚至可以使用Uniswap V3流动性池作为预言。
发布于 2022-08-08 03:19:48
如果它位于Dex上,则获取带有路由器契约的对地址,然后调用getReserves()。这将是Weth (包裹的以太)和池上的令牌之间的速率。
对于美元价格,抓住一个稳定的价格,然后仔细考虑之间的令牌和韦特之间的利率。
发布于 2022-08-08 05:44:11
我们使用Oracle类似的chianlink从离链获取数据。
在项目中包括以下代码。
在部署代码之后,
在PriceFeed.sol中,请调用setAddress函数,并为来自这里的链、网络和货币对提供所需的_priceAggregatorAddress参数。
也就是说,对于rinkeby /美元价格I包含0x8A753747A1Fa494EC906cE90E9f37563A8AF630e。
要获得价格,您需要调用fetchPrice()函数。
注:处理小数,将价格除以所需小数。
这里是您需要的完整的代码。
下面是setAddress()的一个事务
下面是来自rinkeby扫描的相同代码,您可以参考
// PriceFeed.sol file
// SPDX-License-Identifier:MIT
pragma solidity >=0.8.0;
import "./Ownable.sol";
import "./IPriceFeed.sol";
import "./AggregatorV3Interface.sol";
/*
* PriceFeed for mainnet deployment, to be connected to Chainlink's live ETH:USD aggregator reference
* contract, and a wrapper contract TellorCaller, which connects to TellorMaster contract.
*
* The PriceFeed uses Chainlink as primary oracle, and Tellor as fallback. It contains logic for
* switching oracles based on oracle failures, timeouts, and conditions for returning to the primary
* Chainlink oracle.
*/
contract PriceFeed is Ownable, IPriceFeed {
string constant public NAME = "PriceFeed";
AggregatorV3Interface public priceAggregator; // Mainnet Chainlink aggregator
uint constant public DECIMAL_PRECISION = 1e18;
// Use to convert a price answer to an 18-digit precision uint
uint constant public TARGET_DIGITS = 18;
// Maximum time period allowed since Chainlink's latest round data timestamp, beyond which Chainlink is considered frozen.
uint constant public TIMEOUT = 14400; // 4 hours: 60 * 60 * 4
// Maximum deviation allowed between two consecutive Chainlink oracle prices. 18-digit precision.
uint constant public MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND = 5e17; // 50%
/*
* The maximum relative price difference between two oracle responses allowed in order for the PriceFeed
* to return to using the Chainlink oracle. 18-digit precision.
*/
uint constant public MAX_PRICE_DIFFERENCE_BETWEEN_ORACLES = 5e16; // 5%
// The last good price seen from an oracle by ourProject
uint public lastGoodPrice;
struct ChainlinkResponse {
uint80 roundId;
int256 answer;
uint256 timestamp;
bool success;
uint8 decimals;
}
enum Status {
chainlinkWorking,
usingTellorChainlinkUntrusted,
bothOraclesUntrusted,
usingTellorChainlinkFrozen,
usingChainlinkTellorUntrusted
}
// The current status of the PricFeed, which determines the conditions for the next price fetch attempt
Status public status;
// --- Dependency setters ---
function setAddress(
address _priceAggregatorAddress
)
external
onlyOwner
{
priceAggregator = AggregatorV3Interface(_priceAggregatorAddress);
emit PriceAggregatorAddressChanged(_priceAggregatorAddress);
// Explicitly set initial system status
status = Status.chainlinkWorking;
// Get an initial price from Chainlink to serve as first reference for lastGoodPrice
ChainlinkResponse memory chainlinkResponse = _getCurrentChainlinkResponse();
_storeChainlinkPrice(chainlinkResponse);
}
// --- Functions ---
/*
* fetchPrice():
* Returns the latest price obtained from the Oracle. Called by ourProject functions that require a current price.
*
* Also callable by anyone externally.
*
* Non-view function - it stores the last good price seen by ourProject.
*
* Uses a main oracle (Chainlink) and a fallback oracle (Tellor) in case Chainlink fails. If both fail,
* it uses the last good price seen by ourProject.
*
*/
function fetchPrice() external view override returns (uint) {
// Get current and previous price data from Chainlink, and current price data from Tellor
ChainlinkResponse memory _chainlinkResponse = _getCurrentChainlinkResponse();
uint scaledChainlinkPrice = _scaleChainlinkPriceByDigits(uint256(_chainlinkResponse.answer), _chainlinkResponse.decimals);
return scaledChainlinkPrice;
}
function _storePrice(uint _currentPrice) internal {
lastGoodPrice = _currentPrice;
emit LastGoodPriceUpdated(_currentPrice);
}
function _scaleChainlinkPriceByDigits(uint _price, uint _answerDigits) internal pure returns (uint) {
/*
* Convert the price returned by the Chainlink oracle to an 18-digit decimal for use by ourProject.
* At date of ourProject launch, Chainlink uses an 8-digit price, but we also handle the possibility of
* future changes.
*
*/
uint price;
if (_answerDigits >= TARGET_DIGITS) {
// Scale the returned price value down to ourProject's target precision
price = _price / (10 ** (_answerDigits - TARGET_DIGITS));
}
else if (_answerDigits < TARGET_DIGITS) {
// Scale the returned price value up to ourProject's target precision
price = _price * (10 ** (TARGET_DIGITS - _answerDigits));
}
return price;
}
function _storeChainlinkPrice(ChainlinkResponse memory _chainlinkResponse) internal returns (uint) {
uint scaledChainlinkPrice = _scaleChainlinkPriceByDigits(uint256(_chainlinkResponse.answer), _chainlinkResponse.decimals);
_storePrice(scaledChainlinkPrice);
return scaledChainlinkPrice;
}
function _getCurrentChainlinkResponse() internal view returns (ChainlinkResponse memory chainlinkResponse) {
// First, try to get current decimal precision:
try priceAggregator.decimals() returns (uint8 decimals) {
// If call to Chainlink succeeds, record the current decimal precision
chainlinkResponse.decimals = decimals;
} catch {
// If call to Chainlink aggregator reverts, return a zero response with success = false
return chainlinkResponse;
}
// Secondly, try to get latest price data:
try priceAggregator.latestRoundData() returns
(
uint80 roundId,
int256 answer,
uint256 /* startedAt */,
uint256 timestamp,
uint80 /* answeredInRound */
)
{
// If call to Chainlink succeeds, return the response and success = true
chainlinkResponse.roundId = roundId;
chainlinkResponse.answer = answer;
chainlinkResponse.timestamp = timestamp;
chainlinkResponse.success = true;
return chainlinkResponse;
} catch {
// If call to Chainlink aggregator reverts, return a zero response with success = false
return chainlinkResponse;
}
}
}// AggregatorV3Interface.sol file
// SPDX-License-Identifier: MIT
// Code from https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol
pragma solidity >=0.8.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}//Context.sol file
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}//IPriceFeed.sol file
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IPriceFeed {
// -- Events ---
event LastGoodPriceUpdated(uint _lastGoodPrice);
event PriceAggregatorAddressChanged(address _priceAggregatorAddress);
// ---Function---
function fetchPrice() external view returns (uint);
}//Ownable.sol file
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "./Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}注:如出现许可证警告,请删除每一项合同的第一行。
https://ethereum.stackexchange.com/questions/127603
复制相似问题