From 4948ad7985c3b45306755994f496f27e5fb0a40c Mon Sep 17 00:00:00 2001 From: Simeon Date: Wed, 22 Feb 2023 17:07:50 +0100 Subject: [PATCH 1/2] added SupraOracles price feeds and VRFs docs --- .../supraoracles/VRF.md | 171 ++++++++++++++++++ .../supraoracles/price-feeds.md | 154 ++++++++++++++++ 2 files changed, 325 insertions(+) create mode 100644 for-dapp-developers/useful-projects-on-cronos/supraoracles/VRF.md create mode 100644 for-dapp-developers/useful-projects-on-cronos/supraoracles/price-feeds.md diff --git a/for-dapp-developers/useful-projects-on-cronos/supraoracles/VRF.md b/for-dapp-developers/useful-projects-on-cronos/supraoracles/VRF.md new file mode 100644 index 00000000..dda5862a --- /dev/null +++ b/for-dapp-developers/useful-projects-on-cronos/supraoracles/VRF.md @@ -0,0 +1,171 @@ +--- +title: Supra VRF +description: Supra VRF provides smart contracts with a secure and decentralized source of randomness that is unbiasable, unpredictable, and publicly verifiable. +keywords: [SupraOracles, verifiable random function, random number generation] +--- + +## What is a Verifiable Random Function (VRF)? + +Blockchain-based verifiable random functions (VRFs) enable the generation of numbers that are as good as random (pseudorandom), and can be (publicly) verified cryptographically. Pseudorandomness guarantees both unpredictability and fairness, whereas tamper-proofness is guaranteed by their public verifiability. + +Using a VRF for random number generation (RNG) is the gold standard for on-chain applications that require these properties, such as gaming operations, NFT-minting, lotteries, and randomized processes. More information about [Supra](https://supraoracles.com/) VRF can be found [here](https://supraoracles.com/docs/vrf1). + + +## How to use SupraOracles' VRF + +Integrating with SupraOracles' VRF is quick and easy. SupraOracles currently supports many Solidity/EVM-based networks, like Cronos TestNet, and non-EVM networks such as Sui and Aptos. + +To see all of the networks SupraOracles supports, please visit [SupraOracles' Networks](https://supraoracles.com/docs/vrf1/network-addresses)! + +To get started, you will want to visit [SupraOracles' docs site](https://supraoracles.com/docs/vrf1) and review the documentation or continue to follow this guide for a quick start. + + +### Step 1: Create The Supra Router Contract Interface + +Add the following code to the requester contract i.e, the contract which uses VRF as a service. You can also add the code in a separate Interface and inherit the interface in the requester contract. + + + +```solidity +interface ISupraRouter { + function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations) external returns(uint256); + function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations, uint256 _clientSeed) external returns(uint256); +} +``` + + + +This interface will help the requester contract interact with the Supra Router contract and through which the requester contract can use the VRF service. + + +### Step 2: Configure the Supra Router Contract Address + +Contracts that need random numbers should utilize the Supra Router Contract. In order to do that, they need to create an interface and bind it to the on-chain address of the Supra Router contract. + +For Cronos TestNet, the address is: 0xb2667190b753720188a4039dd2b6014f01e07fea + +We’ll store the set the address within the constructor and use it later to interact with the interface. + + + + + +```solidity +contract ExampleContract { + + address supraAddr; + + constructor() { + supraAddr = 0xb2667190b753720188a4039dd2b6014f01e07fea; + } +} +``` + + + +### Step 3: Use the VRF service and request a Random Number + +In this step, we'll use the “generateRequest” function of the Supra Router Contract to create a request for random numbers. There are two modes for the "generateRequest" function. The only difference between them is that you can optionally provide a client-side input, which will also be part of the payload being threshold signed to provide randomness. +* **_functionSig** - a string parameter, here the requester contract will have to pass the function signature which will receive the callback i.e., a random number from the Supra Router Contract. The function signature should be in the form of the function name following the parameters it accepts. We'll see an example later in the document. +* **_rngCount** - an integer parameter, it is for the number of random numbers a particular requester wants to generate. Currently, we can generate a maximum of 255 random numbers per request. +* **numConfirmations** - an integer parameter that specifies the number of block confirmations needed before supra VRF can generate the random number. +* **_clientSeed** (optional) - an optional integer parameter that could be provided by the client (defaults to 0). This is for additional unpredictability. The source of the seed can be a UUID of 256 bits. This can also be from a centralized source. +Supra's VRF process requires splitting the contract logic into two functions. +* The request function - the signature of this function is up to the developer +* The callback function - the signature must be of the form **“uint256 nonce, uint256[] calldata rngList”** + + + +```solidity +function exampleRNG() external { + //Function validation and logic + // requesting 10 random numbers + uint8 rngCount = 10; + + // we want to wait for 1 confirmation before the request is considered complete/final + uint256 numConfirmations = 1; + uint256 generated_nonce = ISupraRouter(supraAddr).generateRequest(“exampleCallback(uint256,uint256[])”, rngCount, numConfirmations); + + // store generated_nonce if necessary (eg: in a hashmap) + // this can be used to track parameters related to the request, such as user address, nft address etc in a lookup table + // these can be accessed inside the callback since the response from supra will include the nonce +} +``` + + + +### Step 4 - Add the validation in the callback function of requester contract + +Inside the callback function where the requester contract wants the random number (in this example the callback function is exampleCallback), the requester contract will have to add the validation such that only the Supra router contract can call the function. The validation is necessary to protect against malicious contracts/users executing the callback with fake data. + + +```solidity +function exampleCallback(uint256 _nonce ,uint256[] _rngList) external { + require(msg.sender == supraAddr); + // Following the required logic of the function + } + ``` + + + +### Example Implementation + +In the example below, +* The function getRNGForUser is using the VRF service by calling the generateRequest function of the Supra Router Contract. +* Then we store the username of the user requesting the random number mapped to the nonce returned by generateRequest. +* Then the callback function prints the random numbers requested by a specific user and it has the signature: myCallbackUsername(uint256 nonce, uint256[] calldata rngList) +Once Supra generates the random number and it is verified by the on-chain logic to be authentic, myCallbackUsername is executed by the Supra Router, which completes the second half of the process. The nonce from the first argument is used to look up the username that originated the request. + + + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +interface ISupraRouter { + function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations, uint256 _clientSeed) external returns(uint256); + function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations) external returns(uint256); +} + +contract Interaction { + address supraAddr; + constructor() { + supraAddr = 0xb2667190b753720188a4039dd2b6014f01e07fea; + } + + mapping (uint256 => string ) result; + mapping (string => uint256[] ) rngForUser; + function getRNGForUser(uint8 rngCount, string memory username) external { + uint256 nonce = ISupraRouter(supraAddr).generateRequest("myCallbackUsername(uint256,uint256[])", rngCount, 1, 123); + result[nonce] = username; + } + + function myCallbackUsername(uint256 nonce, uint256[] calldata rngList) external { + require(msg.sender == supraAddr, "only supra router can call this function"); + uint8 i = 0; + uint256[] memory x = new uint256[](rngList.length); + rngForUser[result[nonce]] = x; + for(i=0; i :bulb: **Note:** SupraOracles is only available on Cronos Testnet at the moment. + + +[SupraOracles](https://supraoracles.com/) is a novel, high-throughput Oracle & IntraLayer: a vertically integrated toolkit of cross-chain solutions (data oracles, asset bridges, automation network, and more) that interlink all blockchains, public (L1s and L2s) or private (enterprises). SupraOracles provides smart contracts with a next-generation cross-chain solutions that has superior data accuracy, speed, scalability and security. + + +## How to use SupraOracles' Price Feeds + +Integrating with SupraOracles' Price Feeds is quick and easy. SupraOracles currently supports many Solidity/EVM-based networks, like **Cronos TestNet**, and non-EVM networks such as Sui and Aptos. + +To see all of the networks SupraOracles supports, please visit [SupraOracles' Networks](https://supraoracles.com/docs/get-started/networks)! + +To get started, you should follow this guide for a quick start or visit [SupraOracles' docs site](https://supraoracles.com/docs/get-started/) and review the documentation. + + +### Step 1: Create The S-Value Interface + +Add the following code to the Solidity smart contract that you wish to retrieve an S-Value. + + +```solidity +interface ISupraSValueFeed { + function checkPrice(string memory marketPair) external view returns (int256 price, uint256 timestamp); +} +``` + + + +The above codes provides the interface that you will use apply in next steps in order to fetch a price data from SupraOracles. + + +### Step 2: Configure The S-Value Feed Address + +To fetch the S-Value from a SupraOracles smart contract, you must first find the S-Value Feed Address for the chain of your choice. + +For Cronos TestNet, the address is: **0x700a89Ba8F908af38834B9Aba238b362CFfB665F** + +Now you have the proper address, let's create an instance of the S-Value Feed using the interface we previously defined for Cronos TestNet: + + +```solidity +contract ISupraSValueFeedExample { + ISupraSValueFeed internal sValueFeed; + + constructor() { + sValueFeed = ISupraSValueFeed(0x700a89Ba8F908af38834B9Aba238b362CFfB665F); + } +} +``` + + + + +### Step 3: Get The S-Value Crypto Price + +Now you can simply access the S-Value Crypto Price of our supported market pairs. In this step, we'll get the price of ETH/USDT (eth_usdt) by applying the following code to our Smart Contract. + + +```solidity +function getEthUsdtPrice() external view returns (int) { + ( + int price, + /* uint timestamp */ + ) = sValueFeed.checkPrice("eth_usdt"); + + return price; +} +``` + + + +Here's an example of what your implementation should look like + + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + + +interface ISupraSValueFeed { + function checkPrice(string memory marketPair) external view returns (int256 price, uint256 timestamp); +} + +contract ISupraSValueFeedExample { + ISupraSValueFeed internal sValueFeed; + + constructor() { + sValueFeed = ISupraSValueFeed(0x700a89Ba8F908af38834B9Aba238b362CFfB665F); + } + + function getEthUsdtPrice() external view returns (int) { + ( + int price, + /* uint timestamp */ + ) = sValueFeed.checkPrice("eth_usdt"); + + return price; + } +} +``` + + +Tada! You now have a method in your Smart Contract that you can call at any time to retrieve the price of ETH in USDT! + +### BONUS: Get S-Value Feeds with ethers.js + + +```js +// example assumes that the ethers library has been imported and is accessible within your scope + + +const getEthUsdtPrice = async () => { + ////for ethers version 6.0 + const provider = new ethers.JsonRpcProvider('https://data-seed-prebsc-1-s1.binance.org:8545/') + ////for ethers version <= 5.7.2 + //const provider = new ethers.providers.JsonRpcProvider('https://data-seed-prebsc-1-s1.binance.org:8545/') + + const abi = [{ "inputs": [ { "internalType": "string", "name": "marketPair", "type": "string" } ], "name": "checkPrice", "outputs": [ { "internalType": "int256", "name": "price", "type": "int256" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "stateMutability": "view", "type": "function" } ] + + // Cronos address to retrieve price feeds + const address = '0x700a89Ba8F908af38834B9Aba238b362CFfB665F' + const sValueFeed = new ethers.Contract(address, abi, provider) + const price = (await sValueFeed.checkPrice('eth_usdt')).price + + console.log(`The price is: ${price.toString()}`); +} + +getEthUsdtPrice() +``` + + + + + +## Going Further with SupraOracles + +If you want to take the next step, consider using our [Verifiable Random Functions (VRFs) product.](https://supraoracles.com/docs/vrf1/a-deeper-dive-into-supra-vrf) or refer to the [Supra docs](https://supraoracles.com/docs/additional-guides) for additional tutorials and guides based on example use-cases, etc. + + +## Connect with us! + +Still looking for answers? We got them! Check out all the ways you can reach us: + +* Visit us at [supraoracles.com](https://supraoracles.com) +* Read our [Docs](https://supraoracles.com/docs/overview) +* Follow us on [Twitter](https://twitter.com/SupraOracles) \ No newline at end of file From 8ed4f963106b1b3edee0f0dbdc0accb156858cc8 Mon Sep 17 00:00:00 2001 From: Simeon Date: Wed, 22 Feb 2023 17:08:18 +0100 Subject: [PATCH 2/2] added Supra Oracles to the table --- .../overview-of-dev-tools-and-integrations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/for-dapp-developers/useful-projects-on-cronos/overview-of-dev-tools-and-integrations.md b/for-dapp-developers/useful-projects-on-cronos/overview-of-dev-tools-and-integrations.md index 9cd3711c..e9d060ff 100644 --- a/for-dapp-developers/useful-projects-on-cronos/overview-of-dev-tools-and-integrations.md +++ b/for-dapp-developers/useful-projects-on-cronos/overview-of-dev-tools-and-integrations.md @@ -59,5 +59,5 @@ Scroll right/left to see full contents. | Web3js / Ethersjs / Web3py, etc | A collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC or WebSocket. | dapp-development | Open page to view; Open page to view | Javascript: Recommended: https://docs.ethers.io/v5/; Alernative: https://web3js.readthedocs.io/en/v1.7.4/; Python: https://web3py.readthedocs.io/en/stable/ | | Witnet | Witnet enables your smart contracts to react to real world events with strong crypto-economic guarantees. | oracle | https://witnet.io/; https://docs.witnet.io/smart-contracts/supported-chains | See tutorials here: https://medium.com/cronos-chain/random-number-generation-on-cronos-with-witnet-8b871beef59b; https://medium.com/@benjaminrokowski/46ec979aee3c; https://medium.com/witnet/how-to-deploy-a-price-feed-on-cronos-cro-ccf56438313; https://www.notion.so/0e6bc5ddbe4a4bf8a22c262dedfe268f | | Zapper | Manage your entire web3 portfolio from DeFi to NFTs and whatever comes next. Invest in the latest opportunities from one convenient place. | wallet | https://zapper.fi/ | | -| | | | | | - +| SupraOracles | SupraOracles provides smart contracts with a next-generation cross-chain solutions (data oracles, asset bridges, automation network, and more) that has superior data accuracy, speed, scalability and security. | Cross-chain oracles, VRFs, automation network. | https://supraoracles.com/docs/overview https://supraoracles.com/ | Available on only Cronos Testnet right now. + | |