Skip to content

Add Oracle Bridges docs #68

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

Draft
wants to merge 42 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
86f6cc7
Create rng-oracle-bridge
tomtomcrypto Oct 4, 2022
54f3cbf
Rename rng-oracle-bridge to rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
dd3351f
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
5adcd6f
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
a56706a
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
1b0349e
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
1d8771b
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
af1b59e
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
e98e066
Create delphi-oracle-bridge.md
tomtomcrypto Oct 4, 2022
39eeb1a
Create gas-oracle-bridge.md
tomtomcrypto Oct 4, 2022
7166ddc
Update delphi-oracle-bridge.md
tomtomcrypto Oct 4, 2022
33265a2
Update rng-oracle-bridge.md
tomtomcrypto Oct 4, 2022
793f63d
Update delphi-oracle-bridge.md
tomtomcrypto Oct 4, 2022
ac9789b
Update delphi-oracle-bridge.md
tomtomcrypto Oct 4, 2022
5c69ba1
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
203e404
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
03d0879
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
9a62ff4
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
b3129ef
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
6522c22
Update gas-oracle-bridge.md
tomtomcrypto Oct 5, 2022
6984490
Update gas-oracle-bridge.md
tomtomcrypto Oct 5, 2022
b947397
Update gas-oracle-bridge.md
tomtomcrypto Oct 5, 2022
eb221ee
Update gas-oracle-bridge.md
tomtomcrypto Oct 5, 2022
a73ed55
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
c2ae579
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
0641a5a
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
f8f36c1
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
8166fac
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
4e24919
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
f92488b
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
df328e0
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
1de4fdb
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
b8150d5
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
ee33068
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
59ee9a9
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
a10493a
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
6daa2d1
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
780b186
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
84ba680
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
f395277
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
7a9b571
Update rng-oracle-bridge.md
tomtomcrypto Oct 5, 2022
666c83b
Update delphi-oracle-bridge.md
tomtomcrypto Oct 5, 2022
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
118 changes: 118 additions & 0 deletions docs/learn/crosschain_guide/delphi-oracle-bridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# DELPHI ORACLE BRIDGE

## REPOSITORY

You can find the repository for the Delphi Oracle Bridge [here](https://github.com/telosnetwork/delphi-oracle-bridge)

## DEPLOYMENTS

**MAINNET:** TBD

**TESTNET:** TBD

## HOW IT WORKS

Your contract will need to make a call to the `request(uint callId, string calldata pair, uint limit, uint callback_gas, address callback_address)` function of the `DelphiOracleBridge` contract and you will need to implement a `receiveDatapoints(uint callId, Datapoint[] calldata datapoints)` callback function in the same or in another contract (see the **callback_address** parameter). Refer to the **Make a request** section below.

The method we use is similar to Chainlink's Direct funding method. You must directly fund consuming contracts with TLOS tokens before they request datapoints.

The `callback_gas` parameter contains the maximum gas units you estimate will be needed to call your `receiveDatapoints(uint callId, Datapoint[] calldata datapoints)` callback function in your own smart contract (ie: 50000). This is the maximum amount of gas that will be spent by the bridge when calling your contract.

### Note on transaction costs.

Because the consuming contract directly pays the TLOS for the request, the cost is calculated during the request and not during the callback when the request is fulfilled. Test your callback function to learn how to correctly estimate the callback gas limit.

You can query the TLOS value to pass in your `request(uint callId, string calldata pair, uint limit, uint callback_gas, address callback_address)` function call by calling the `calculateRequestPrice(uint callback_gas)` public function beforehand.

You can alternatively calculate that price by taking the gas price from the `GasOracleBridge` with `getPrice()`, multiply that price with your estimate gas units (ie: 50000) and add the fee from the `DelphiOracleBridge` that you can query with `fee()`:

`Price = (Gas Units * Gas Price) + Bridge Fee`

If the gas limit is underestimated, the callback fails and the consuming contract is still charged for the work done to generate the requested random values.
If the gas limit is overestimated, the callback function will be executed but your contract is not refunded for the excess gas amount that you paid.
Make sure that your consuming contracts are funded with enough TLOS tokens to cover the transaction costs.

## DIAGRAM

![DelphiOracleBridge](https://user-images.githubusercontent.com/5913758/193951928-58a946c3-622e-4b96-8873-d02b7bedea33.jpg)


## MAKE A REQUEST !

Deploy a contract that calls the `DelphiOracleBridge` contract's `request(uint callId, string calldata pair, uint limit, uint callback_gas, address callback_address)` function, passing a value to cover fee and callback gas cost (refer to the **Note on transaction costs** section above).

```
interface IDelphiOracleBridge {
function request(uint callId, string calldata pair, uint limit, uint callback_gas, address callback_address) external payable;
function calculateRequestPrice(uint callback_gas) external view returns(uint);
}

contract MyContract {
IDelphiOracleBridge bridge;

constructor(address _bridge) {
bridge = IRNGOracleBridge(_bridge);
}

function makeRequest(string calldata pair, uint limit, uint callback_gas) external payable {

... YOUR LOGIC TO SETUP THE CALLID, ETC...

uint price = bridge.calculateRequestPrice(callback_gas);
require(price > 0, "Could not calculate price");
require(address(this).balance >= price, "Contract balance is too low");

bridge.request{value: msg.value }(callId, pair, limit, callback_gas, address(this));
}
}
```

The request function takes in a **callId**, for you to keep track of the requests & handle answers later, the **pair** you are requesting, the **limit** of the datapoints to receive, the **callback_gas** unit (see below) and the **callback_address** where to call your implementation of the callback function.

On the same contract, or in a new one, implement a `receiveDatapoints(uint callId, Datapoint[] calldata datapoints) external` callback function in order to receive the oracle's answer, like so:


```
interface IDelphiOracleBridge {
function request(uint callId, string calldata pair, uint limit, uint callback_gas, address callback_address) external payable;
function calculateRequestPrice(uint callback_gas) external view returns(uint);
}

contract MyContract {
IDelphiOracleBridge bridge;

struct Datapoint {
string pair;
string owner;
uint timestamp;
uint median;
uint value;
}

constructor(address _bridge) {
bridge = IDelphiOracleBridge(_bridge);
}

function receiveDatapoints(uint callId, Datapoint[] calldata datapoints) external {
require(msg.sender == address(bridge), "Only the bridge contract can call this function");

// Handle whatever logic you need with the datapoints received here

}
}
```

You can refer to the [`DelphiOracleConsumer`](https://github.com/telosnetwork/delphi-oracle-bridge/blob/main/evm/contracts/DelphiOracleConsumer.sol) EVM contract for a complete example.

## IMPORTANT CONSIDERATIONS

Your implementation of the `receiveDatapoints()` callback function must not revert, we will not handle it.

Requesting a non existant pair, or a pair that has no data will return an empty Datapoint array.

## LIMITS

There is a max request per consumer contract, set at 25 for now, if you reach it wait for an answer or use the `deleteRequestorRequest(address requestor, uint callId)` method from the smart contract that made that request to delete one.

The maximum limit of datapoints you can request for a pair is 10. Note that there may be less datapoints received depending on the pair and the data available.

18 changes: 18 additions & 0 deletions docs/learn/crosschain_guide/gas-oracle-bridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# GAS ORACLE BRIDGE

## REPOSITORY
You can find the repository for the Gas Oracle Bridge [here](https://github.com/telosnetwork/gas-oracle-bridge)

## DEPLOYMENTS

**MAINNET:** TBD

**TESTNET:** TBD

## HOW IT WORKS

A listener compares the gas price stored on the `GasOracleBridge` EVM contract to the one stored and the `eosio.evm` Antelope contract. If they are different they notify the bridge's antelope contract to query the new price from `eosio.evm` and update the bridge's EVM contract accordingly.

You can query the current gas price by calling the `getPrice()` public function of the `GasOracleBridge` contract on EVM.

![GasOracleBridge](https://user-images.githubusercontent.com/5913758/193957976-e97593b9-9154-4dd3-9f4c-a6ba7eec78b3.jpg)
107 changes: 107 additions & 0 deletions docs/learn/crosschain_guide/rng-oracle-bridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# RNG ORACLE BRIDGE

## REPOSITORY

You can find the repository for the RNG Oracle Bridge [here](https://github.com/telosnetwork/rng-oracle-bridge)

## DEPLOYMENTS

**MAINNET:** TBD

**TESTNET:** TBD

## HOW IT WORKS

Your contract will need to make a call to the `request(uint callId, uint64 seed, uint callback_gas, address callback_address, uint number_count)` function of the `RNGOracleBridge` contract and you will need to implement a `receiveRandom(uint callId, uint[] numbers)` callback function in the same or in another contract (see the **callback_address** parameter). Refer to the **Make a request** section below.

The method we use is similar to Chainlink's Direct funding method. You must directly fund consuming contracts with TLOS tokens before they request randomness.

The `callback_gas` parameter contains the gas units you estimate will be needed to call your `receiveRandom(uint callId, uint[] numbers)` callback function in your own smart contract (ie: 50000). This is the maximum amount of gas that will be spent by the bridge when calling your contract.

### Note on transaction costs.

Because the consuming contract directly pays the TLOS for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Test your callback function to learn how to correctly estimate the callback gas limit.

You can query the TLOS value to pass in your `request()` function call by calling the `calculateRequestPrice(uint callback_gas)` public function.

You can alternatively calculate that price by taking the gas price from the `GasOracleBridge` with `getPrice()`, multiply that price with your estimate gas units (ie: 50000) and add the fee from the `RNGOracleBridge` that you can query with `fee()`:

`Price = Gas Units * Gas Price + Bridge Fee`

If the gas limit is underestimated, the callback fails and the consuming contract is still charged for the work done to generate the requested random values.
If the gas limit is overestimated, the callback function will be executed but your contract is not refunded for the excess gas amount that you paid.
Make sure that your consuming contracts are funded with enough TLOS tokens to cover the transaction costs. If the consuming contract doesn't have enough TLOS tokens, your request will revert.

## DIAGRAM

![RNGOracleBridge](https://user-images.githubusercontent.com/5913758/193971791-6e4ceda4-c55f-45d6-81ef-2122d80e5963.jpg)

## MAKE A REQUEST !

Deploy a contract that calls the `RNGOracleBridge` contract's `request()` function, passing a value to cover fee and callback gas cost (refer to the **callback gas** section further ahead).

```
interface IRNGOracleBridge {
function request(uint callId, uint64 seed, uint callback_gas, address callback_address, uint number_count) external payable;
function calculateRequestPrice(uint callback_gas) external view returns(uint);
}

contract MyContract {
IRNGOracleBridge bridge;

constructor(address _bridge) {
bridge = IRNGOracleBridge(_bridge);
}

function makeRequest(uint64 seed, uint callback_gas, uint count) external payable {
... YOUR LOGIC TO SETUP THE CALLID, ETC...

uint price = bridge.calculateRequestPrice(callback_gas);
require(price > 0, "Could not calculate price");
require(address(this).balance >= price, "Contract balance is too low");

bridge.request{value: price }(callId, seed, callback_gas, address(this), count);
}
}
```

The `request()` function takes in a **callId**, for you to keep track of the requests & handle answers later, a **seed** for the random generation that you can generate however you like as long as it fits into 64 bytes, the **callback_gas** unit (see below), the **callback_address** where to call your implementation of the callback function and the **number_count** of requested numbers.

On the same contract, or in a new one, implement a `receiveRandom(uint callId, uint[] numbers) external` callback function in order to receive the oracle's answer, like so:


```
interface IRNGOracleBridge {
function request(uint callId, uint64 seed, uint callback_gas, address callback_address, uint number_count) external payable;
function calculateRequestPrice(uint callback_gas) external view returns(uint);
}

contract MyContract {
IRNGOracleBridge bridge;

constructor(address _bridge) {
bridge = IRNGOracleBridge(_bridge);
}

function receiveRandom(callId, numbers){
require(msg.sender == address(bridge), "Only the bridge contract can call this function");

// Handle whatever logic you need with the random numbers received here

}
}
```

You can refer to the [`RNGOracleConsumer`](https://github.com/telosnetwork/rng-oracle-bridge/blob/main/evm/contracts/RNGOracleConsumer.sol) EVM contract for a complete example.

## IMPORTANT CONSIDERATIONS

Your implementation of the `receiveRandom()` callback function must not revert

## LIMITS

There is a max request per consumer contract, set at 25 for now, if you reach it wait for an answer or use the `deleteRequestorRequest(address requestor, uint callId)` method from your the smart contract that made that request to delete one.

There is a max number count per request, set at 25 for now.

The maximum callback gas is: