Skip to content

Update docs for Entropy v2 #748

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

Merged
merged 9 commits into from
Jul 23, 2025
Merged
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
Binary file removed images/entropy-1.png
Binary file not shown.
Binary file removed images/entropy-2.png
Binary file not shown.
35 changes: 13 additions & 22 deletions pages/entropy/create-your-first-entropy-app.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,17 @@ Create a new file `CoinFlip.sol` in `contracts/src` directory and add the follow
```solidity copy
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
import "@pythnetwork/entropy-sdk-solidity/IEntropyV2.sol";
import "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";

contract CoinFlip is IEntropyConsumer {
event FlipRequested(uint64 sequenceNumber);
event FlipResult(uint64 sequenceNumber, bool isHeads);

IEntropy entropy;
address provider;

constructor(address _entropy, address _provider) {
constructor(address _entropy) {
entropy = IEntropy(_entropy);
provider = _provider;
}

// This method is required by the IEntropyConsumer interface
Expand All @@ -63,7 +61,7 @@ contract CoinFlip is IEntropyConsumer {

```

The code implements a`CoinFlip` contract which inherits the `IEntropyConsumer` interface. We have also defined some events, properties and a constructor to instantiate the contract. One of the properties is of type `IEntropy` which is an interface imported from the Entropy SDK. The constructor also takes a `provider` argument. We will see how to populate these later.
The code implements a`CoinFlip` contract which inherits the `IEntropyConsumer` interface. We have also defined some events, properties and a constructor to instantiate the contract. One of the properties is of type `IEntropy` which is an interface imported from the Entropy SDK.

### Request a coin flip

Expand All @@ -73,17 +71,14 @@ Copy the following code into `CoinFlip.sol`.
contract CoinFlip {
// ... prior code omitted

function request(bytes32 userRandomNumber) external payable {
function request() external payable {
// get the required fee
uint128 requestFee = entropy.getFee(provider);
uint128 requestFee = entropy.getFeeV2();
// check if the user has sent enough fees
if (msg.value < requestFee) revert("not enough fees");

// pay the fees and request a random number from entropy
uint64 sequenceNumber = entropy.requestWithCallback{ value: requestFee }(
provider,
userRandomNumber
);
uint64 sequenceNumber = entropy.requestV2{ value: requestFee }();

// emit event
emit FlipRequested(sequenceNumber);
Expand All @@ -92,7 +87,7 @@ contract CoinFlip {

```

Users will invoke the `request` method to initiate a coin flip with a request fee and passes in a `userRandomNumber` argument — we’ll see how to generate this later. The method first retrieves the fee required to request a random number from Entropy. It then include the fee in the `requestWithCallback` method call to entropy. Finally, the method emits a `FlipRequested` event with a `sequenceNumber`. This event is also defined in the code snippet above.
Users will invoke the `request` method to initiate a coin flip, paying a fee in the process. The method first retrieves the fee required to request a random number from Entropy. It then includes the fee in the `requestV2` method call to Entropy. Finally, the method emits a `FlipRequested` event with a `sequenceNumber`. This event is also defined in the code snippet above.

### Handle the callback

Expand All @@ -119,7 +114,7 @@ contract CoinFlip {
```

Implement `entropyCallback` method which is required by the `IEntropyConsumer` Interface. Entropy calls back this method to fulfill a request. Entropy will call back this
method with the `sequenceNumber` of the request, the `providerAddress` from which the random number was requested and the generated `randomNumber`.
method with the `sequenceNumber` of the request, the `_providerAddress` from which the random number was requested and the generated `randomNumber`.
Finally, the method emits a `FlipResult` event with the result of the flip.

Yay! you have successfully implemented a coin flip contract.
Expand Down Expand Up @@ -158,7 +153,6 @@ The final step before deploying is to get the arguments for the contract's const

```bash copy
export ENTROPY_ADDRESS=0x4821932D0CDd71225A6d914706A621e0389D7061
export PROVIDER_ADDRESS=0x6CC14824Ea2918f5De5C2f75A9Da968ad4BD6344
```

Finally, let's deploy the contracts. Run the following command:
Expand All @@ -167,7 +161,7 @@ Finally, let's deploy the contracts. Run the following command:
forge create src/CoinFlip.sol:CoinFlip \
--private-key $PRIVATE_KEY \
--rpc-url $RPC_URL \
--constructor-args $ENTROPY_ADDRESS $PROVIDER_ADDRESS
--constructor-args $ENTROPY_ADDRESS
```

You should see an output similar to:
Expand Down Expand Up @@ -206,7 +200,7 @@ Create a `script.js` file in `app` and add the following code to the script.
```javascript copy
const { Web3 } = require("web3");
const CoinFlipAbi = require("../contracts/out/CoinFlip.sol/CoinFlip.json");
const EntropyAbi = require("@pythnetwork/entropy-sdk-solidity/abis/IEntropy.json");
const EntropyAbi = require("@pythnetwork/entropy-sdk-solidity/abis/IEntropyV2.json");

async function main() {
const web3 = new Web3(process.env["RPC_URL"]);
Expand Down Expand Up @@ -240,14 +234,11 @@ async main() {

// Request a random number

// Generate user random number
const userRandomNumber = web3.utils.randomHex(32);

const fee = await entropyContract.methods.getFee(process.env["PROVIDER_ADDRESS"]).call()
const fee = await entropyContract.methods.getFeeV2().call()
console.log(`fee : ${fee}`);

const requestReceipt = await coinFlipContract.methods
.request(userRandomNumber)
.request()
.send({
value: fee,
from: address,
Expand Down Expand Up @@ -309,7 +300,7 @@ sequence : 42
result : Tails
```

Note that: the script can fail due to some rpc issues. You can run the script again to get the expected result.
Note that: the script can fail due to transient RPC issues. You can run the script again to get the expected result.

## Next Steps

Expand Down
2 changes: 1 addition & 1 deletion pages/entropy/current-fees.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Note that the fees shown below will vary over time with prevailing gas prices on
## Mainnet

<Callout emoji="⚠️">
The fees for mainnet are dynamically set. Always use the onchain method `entropy.getFee(entropyProvider){:solidity}` to get the current fee.
The fees for mainnet are dynamically set. Always use the on-chain method `entropy.getFeeV2(){:solidity}` to get the current fee.
</Callout>

<EntropyFeeTable
Expand Down
103 changes: 39 additions & 64 deletions pages/entropy/generate-random-numbers/evm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,114 +36,77 @@ Then add the following line to your `remappings.txt` :
The Solidity SDK exports two interfaces:

- [`IEntropyConsumer`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropyConsumer.sol) - The interface that your contract should implement. It makes sure that your contract is compliant with the Entropy contract.
- [`IEntropy`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol) - The interface to interact with the Entropy contract.
- [`IEntropyV2`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol) - The interface to interact with the Entropy contract.
You will need the address of an Entropy contract on your blockchain.
Consult the current [Entropy contract addresses](../contract-addresses) to find the address on your chain.
Once you have a contract address, instantiate an `IEntropy` contract in your solidity contract:
Once you have a contract address, instantiate an `IEntropyV2` contract in your solidity contract:

```solidity copy
import { IEntropyConsumer } from "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
import { IEntropy } from "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
import { IEntropyV2 } from "@pythnetwork/entropy-sdk-solidity/IEntropyV2.sol";

// @param entropyAddress The address of the entropy contract.
contract YourContract is IEntropyConsumer {
IEntropy public entropy;
IEntropyV2 public entropy;

constructor(address entropyAddress) {
entropy = IEntropy(entropyAddress);
entropy = IEntropyV2(entropyAddress);
}
}

```

<Callout type="info">
Entropy also requires selecting a **randomness provider**. The randomness provider is a third-party
who participates in the generation process. Each provider is identified by an address and hosts
a keeper service for fullfilling requests.

The simplest way to choose a provider is to use the [default provider](../contract-addresses).
The default provider for each contract and their corresponding URI is also listed in the
[Entropy contract addresses](../contract-addresses).

</Callout>

You can also get the default provider's address by calling the [`getDefaultProvider`](https://github.com/pyth-network/pyth-crosschain/blob/f8ebeb6af31d98f94ce73edade6da2ebab7b2456/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol#L94) method:

```solidity copy
address provider = entropy.getDefaultProvider();
```

## Usage

To generate a random number, follow these steps.

### 1. Generate a random number

Generate a 32-byte random number on the client side.
### 1. Request a number from Entropy

<Tabs items={['web3.js', 'ethers.js']}>
<Tabs.Tab>
```javascript
const userRandomNumber = web3.utils.randomHex(32);
```
</Tabs.Tab>
Invoke the [`requestV2`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol#L83) method of the `IEntropyV2` contract.
The `requestV2` method requires paying a fee in native gas tokens which is configured per-provider.

<Tabs.Tab>
```javascript
const userRandomNumber = ethers.utils.randomBytes(32);
```
</Tabs.Tab>
</Tabs>
The fee differs for every chain and also varies over time depending on the chain's current gas price.
The current value for each chain can be found on the [Current Fees](../current-fees) page.
However, you should use the on-chain method [`getFeeV2`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol#L101) to compute the required fee and send it as the value of the `requestV2` call.

### 2. Request a number from Entropy

Invoke the [`requestWithCallback`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol#L83) method of the `IEntropy` contract.
The `requestWithCallback` method requires paying a fee in native gas tokens which is configured per-provider.

The fees differs for every chain and can be found at the [Current Fees](../current-fees) page. \
You can use the onchain method [`getFee`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol#L101) to calculate the fee for the default provider and send it as the value of the `requestWithCallback` call:
These methods use the default randomness provider ([see here](#randomness-providers) for more info on providers).

```solidity copy
function requestRandomNumber(bytes32 userRandomNumber) external payable {
uint256 fee = entropy.getFee(entropyProvider);
function requestRandomNumber() external payable {
uint256 fee = entropy.getFeeV2();
Copy link
Member

@aditya520 aditya520 Jul 17, 2025

Choose a reason for hiding this comment

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

Shouldn't we mention that getFeeV2() will use DefaultProvider?


uint64 sequenceNumber = entropy.requestWithCallback{ value: fee }(
entropyProvider,
userRandomNumber
);
uint64 sequenceNumber = entropy.requestV2{ value: fee }();
}

```

This method returns a sequence number and emits a [`RequestedWithCallback`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/EntropyEvents.sol#L10) event. You can store this sequence number to identify the request in next step.
This method returns a sequence number and emits a [`Requested`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/EntropyEventsV2.sol#L30) event. You can store this sequence number to identify the request in next step.

Note that there are several variants of `requestV2` that allow the caller to configure the provider fulfilling the request and the gas limit for the callback.
Please see the method documentation in the [IEntropyV2 interface](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol).

### 3. Implement callback for Entropy
### 2. Implement the Entropy callback

```solidity {28-42} copy
pragma solidity ^0.8.0;

import { IEntropyConsumer } from "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
import { IEntropy } from "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
import { IEntropyV2 } from "@pythnetwork/entropy-sdk-solidity/IEntropyV2.sol";

contract YourContract is IEntropyConsumer {
IEntropy entropy;
IEntropyV2 entropy;

// @param entropyAddress The address of the entropy contract.
constructor(address entropyAddress) {
entropy = IEntropy(entropyAddress);
entropy = IEntropyV2(entropyAddress);
}

// @param userRandomNumber The random number generated by the user.
function requestRandomNumber(bytes32 userRandomNumber) external payable {
// Get the default provider and the fee for the request
address entropyProvider = entropy.getDefaultProvider();
uint256 fee = entropy.getFee(entropyProvider);
function requestRandomNumber() external payable {
// Get the fee for the request
uint256 fee = entropy.getFeeV2();

// Request the random number with the callback
uint64 sequenceNumber = entropy.requestWithCallback{ value: fee }(
entropyProvider,
userRandomNumber
);
uint64 sequenceNumber = entropy.requestV2{ value: fee }();
// Store the sequence number to identify the callback request
}

Expand Down Expand Up @@ -200,3 +163,15 @@ Check the [Current Fees](../current-fees) to find the current fee for each provi
### Best Practices

Check out the [Best Practices](../best-practices) guide for tips to limit gas usage, or generate multiple random numbers in a single transaction.

### Randomness providers

Some methods on Entropy require selecting a **randomness provider**. The randomness provider is a third-party
who participates in the generation process. Each provider is identified by an address and hosts
a keeper service for fullfilling requests.

You can get the default provider's address by calling the [`getDefaultProvider`](https://github.com/pyth-network/pyth-crosschain/blob/f8ebeb6af31d98f94ce73edade6da2ebab7b2456/target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol#L94) method:

```solidity copy
address provider = entropy.getDefaultProvider();
```
Loading
Loading