Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
87 changes: 54 additions & 33 deletions apps/developer-hub/content/docs/entropy/best-practices.mdx
Original file line number Diff line number Diff line change
@@ -1,46 +1,17 @@
---
title: Best Practices
description: Best practices for using Pyth Entropy in your applications
icon: Book
---

# Best Practices

## Limit gas usage on the callback

Keeping the callback function simple is crucial because the entropy providers limit gas usage.
This ensures gas usage is predictable and consistent, avoiding potential issues with the callback.

For example, if you want to use entropy to generate a random number for each player in a round of game,
you need to make sure that the callback function works for the maximum number of players that can be in each round.
Otherwise, the callbacks will work for some rounds with fewer players, but will fail for rounds with more players.

Multiple solutions are possible to address this problem. You can store the random number received from the callback and
either ask users to submit more transactions after the callback to continue the flow or run a background crank service
to submit the necessary transactions.

The gas limit for each chain is listed on the [contract addresses](contract-addresses) page.

## Handling callback failures

While the default entropy provider is highly reliable, in rare cases a callback might not be received. This typically happens when there's an issue with your contract's callback implementation rather than with the provider itself. The most common causes are:

1. The callback function is using more gas than the allowed limit
2. The callback function contains logic that throws an error

If you're not receiving a callback, you can manually invoke it to identify the specific issue. This allows you to:

- See if the transaction fails and why
- Check the gas usage against the chain's callback gas limit
- Debug your callback implementation

For detailed instructions on how to manually invoke and debug callbacks, refer to the [Debug Callback Failures](debug-callback-failures) guide.
import { DynamicCodeBlock } from "fumadocs-ui/components/dynamic-codeblock";

## Generating random values within a specific range

You can map the random number provided by Entropy into a smaller range using the solidity [modulo operator](https://docs.soliditylang.org/en/latest/types.html#modulo).
Here is a simple example of how to map a random number provided by Entropy into a range between `minRange` and `maxRange` (inclusive).

```solidity
<DynamicCodeBlock lang="solidity" code={`\
// Maps a random number into a range between minRange and maxRange (inclusive)
function mapRandomNumber(
bytes32 randomNumber,
Expand All @@ -53,5 +24,55 @@ function mapRandomNumber(
uint256 randomUint = uint256(randomNumber);

return minRange + int256(randomUint % range);

}
`} />

Notice that using the modulo operator can distort the distribution of random numbers if it's not a power of 2. This is
negligible for small and medium ranges, but it can be noticeable for large ranges.
For example, if you want to generate a random number between 1 and 52, the probability of having value 5 is approximately
`10^-77` higher than the probability of having value 50 which is infinitesimal.

## Generating multiple random values in a single transaction

If you need to generate multiple random values in a single transaction, you can hash the random input provided by Entropy with a unique identifier for each random number.

In the following example, `mapRandomNumber` is used to generate 6 random attributes for a character.

<DynamicCodeBlock
lang="solidity"
code={`\
function generateAttributes(bytes32 randomNumber) internal {
int256 strength = mapRandomNumber(
keccak256(abi.encodePacked(randomNumber, "strength")),
15,
20
Copy link
Contributor

Choose a reason for hiding this comment

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

feel free to ignore but I'm curious if this would work with just doing the triple quotes like ```solidity ....

Feels a bit cumbersome to have to use <DynamicCodeBlock .../> every time we write code

Copy link
Contributor

Choose a reason for hiding this comment

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

this is the same thing that we were discussing yesterday @aditya520 as in don't see any difference in the look and feel of these two methods.

Copy link
Member Author

Choose a reason for hiding this comment

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

This component support shiki styles. I want to experiment with them in future.

);
int256 stamina = mapRandomNumber(
keccak256(abi.encodePacked(randomNumber, "stamina")),
10,
15
);
int256 agility = mapRandomNumber(
keccak256(abi.encodePacked(randomNumber, "agility")),
5,
15
);
int256 stealth = mapRandomNumber(
keccak256(abi.encodePacked(randomNumber, "stealth")),
0,
5
);
int256 positionX = mapRandomNumber(
keccak256(abi.encodePacked(randomNumber, "positionX")),
-100,
100
);
int256 positionY = mapRandomNumber(
keccak256(abi.encodePacked(randomNumber, "positionY")),
-100,
100
);
}
```
`}
/>
15 changes: 13 additions & 2 deletions apps/developer-hub/content/docs/entropy/contract-addresses.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
---
title: Contract Addresses
title: Contract & Provider Addresses
description: Pyth Entropy contract addresses on EVM networks
icon: FileText
---

import { EntropyTable } from "../../../src/components/EntropyTable";

## Mainnets

> ⚠️ **Warning**
> The fees for mainnet are dynamically set. Always use the on-chain method `entropy.getFeeV2()` to get the current fee.

The following tables shows the total fees payable when using the **default provider**.
Note that the fees shown below will vary over time with prevailing gas prices on each chain.

The Entropy contract is deployed on the following mainnet chains:

<EntropyTable isMainnet={true} />
Expand All @@ -16,10 +23,14 @@ The Entropy contract is deployed on the following mainnet chains:
The default provider on mainnet has a reveal delay to avoid changes on the outcome of the Entropy request because of block reorgs.
The reveal delay shows how many blocks should be produced after the block including the request transaction in order to reveal and submit a callback transaction.

The default provider fulfills the request by sending a transaction with a gas limit as mentioned in above table. Entropy callbacks the consumer as part of this transaction.
The default provider fulfills the request by sending a transaction with a gas limit as mentioned in above table or as set by the user in the request.
Entropy callbacks the consumer as part of this transaction.

## Testnets

> ℹ️ **Note**
> The fees for testnets kept deliberately low and different from the mainnet fees.

The Entropy contract is deployed on the following testnet chains:

<EntropyTable isMainnet={false} />
Expand Down
Loading
Loading