Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added content for SupraOracles price feeds and VRFs for cronos #305

Open
wants to merge 2 commits into
base: gitbook
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
| |
171 changes: 171 additions & 0 deletions for-dapp-developers/useful-projects-on-cronos/supraoracles/VRF.md
Original file line number Diff line number Diff line change
@@ -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.


<Tabs>
<TabItem value="solidity" label="Solidity" default>

```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<rngList.length;i++){
rngForUser[result[nonce]][i] = rngList[i] % 100;
}
}

function viewUserName(string memory username) external view returns (uint256[] memory) {
return rngForUser[username];
}
}
```


For additional tutorials and guides based on example use-cases, please refer to the [Supra Docs](https://supraoracles.com/docs/additional-guides).


## 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)
* Chat with us on [Telegram](https://t.me/SupraOracles)
* Follow us on [Twitter](https://twitter.com/SupraOracles)
* Join our [Discord](https://discord.gg/supraoracles)
* Check us out on [Youtube](https://www.youtube.com/SupraOfficial)
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
title: SupraOracles
description: SupraOracles provides smart contracts with a next-generation cross-chain oracle solution that has superior data accuracy, speed, scalability and security.
keywords: [supraoracles, oracle, data feeds, price feeds]
---

## What is SupraOracles?

> :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)