Skip to content

Update Oracles.md #487

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

Closed
wants to merge 1 commit into from
Closed
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
97 changes: 95 additions & 2 deletions docs/infrastructure/Oracles.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ The DIA oracle on Alephium is free of use. dApps built on Alephium can leverage

The main oracle contracts on Group 0 are deployed at the following addresses:

- **Testnet**: 216wgM3Xi5uBFYwwiw2T7iZoCy9vozPJ4XjToW74nQjbV
- **Mainnet:** 285zrkZTPpUCpjKg9E3z238VmpUBQEAbESGsJT6yX7Rod
Network | Address
-----------|--------------------------------------------------------------
Mainnet | 285zrkZTPpUCpjKg9E3z238VmpUBQEAbESGsJT6yX7Rod
Testnet | 216wgM3Xi5uBFYwwiw2T7iZoCy9vozPJ4XjToW74nQjbV


(New groups will be added in the near future).

Expand Down Expand Up @@ -63,6 +66,96 @@ The final price point for each asset is calculated by computing the assets' trad

Each asset is updated every two minutes if the new price deviates from the old one by more than 0.2%. Additionally, a heartbeat of 10 minutes is applied, which means that each price is updated at least once per day even if it moves by less than 0.2%.

---

## Randomness Oracles

### Deployed contracts

The Randomness oracle contracts on Group 0 are deployed at the following addresses:

Network | Address
-----------|--------------------------------------------------------------
Mainnet | v1v4cBXP9L7M9ryZZCx7tuXuNb9pnDLGb3JJkPBpbR1Z
Testnet | 217k7FMPgahEQWCfSA1BN5TaxPsFovjPagpujkyxKDvS3

### How the Randomness Oracle Works

DIA leverages [drand](https://drand.love/)’s distributed randomness beacon, enabling verifiable, unpredictable, and unbiased random numbers.

![image2](https://github.com/user-attachments/assets/85485b42-4216-41c4-baf9-bc8ad43b8425)

The drand network's nodes collaborate every 30 seconds to produce a verifiable random number, which DIA's oracle system then captures and publishes to its smart contract, making this randomness readily available for on-chain applications.

You can learn more about the full publishing process [here](https://docs.diadata.org/use-nexus-product/readme/randomness-oracle/data-source#on-chain-publishing-process).

### How to Access Data

#### Accessing the oracle on-chain

To consume randomness data, you’ll need to invoke the **`getLastRound`** method on the oracle contract. It will return the round ID of the latest update.

Using this round ID, you can call **`getRandomValue`** and will receive a return value of that randomness, the round ID, and the BLS signature from the drand API.

Please note that round IDs are used round-robin and will repeat after **1000 iterations**.

Below is the **DIARandomOracle** contract implementation in Ralph:

```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use rust colorization here.

Contract DIARandomOracle(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the implementation of the DIARandomOracle. For developers to use it in the smart contract and fetch the randomness, do you think example like this is more useful?

mut admin: Address,
mut lastRound: U256
) extends DIAOracleBase(admin) implements IDIARandomOracle {

mapping[U256, DIARandomValue] randomValues

event OracleUpdate(
round: U256,
randomness: ByteVec,
signature: ByteVec
)

const MaxSlot = 1000

enum ErrorCodes {
InvalidRound = 1
RoundKeyNotExist = 2
RoundIsExpired = 3
}

pub fn getLastRound() -> U256 {
return lastRound
}

pub fn getRandomValue(realRound: U256) -> DIARandomValue {
let roundKey = realRound % MaxSlot
assert!(randomValues.contains!(roundKey), ErrorCodes.RoundKeyNotExist)

let randomValue = randomValues[roundKey]
assert!(randomValue.round == realRound, ErrorCodes.RoundIsExpired)
return randomValue
}

@using(preapprovedAssets = true, updateFields = true)
pub fn setRandomValue(value: DIARandomValue) -> () {
checkAdmin(callerAddress!())
assert!(value.round > lastRound, ErrorCodes.InvalidRound)

let roundKey = value.round % MaxSlot
lastRound = value.round

if (randomValues.contains!(roundKey)) {
randomValues[roundKey] = value
} else {
randomValues.insert!(admin, roundKey, value)
}

emit OracleUpdate(value.round, value.randomness, value.signature)
}
}
```


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Nit] Extra space

## Example

You can find a deployment example [here](https://github.com/alephium/ralph-example/tree/master/call-oracle/contracts).
Expand Down