Skip to content

Commit 98b3213

Browse files
committed
chore(dev-hub) Entropy remaining page Improvements
1 parent a4148c6 commit 98b3213

File tree

16 files changed

+689
-188
lines changed

16 files changed

+689
-188
lines changed

apps/developer-hub/content/docs/entropy/best-practices.mdx

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,6 @@ title: Best Practices
33
description: Best practices for using Pyth Entropy in your applications
44
---
55

6-
# Best Practices
7-
8-
## Limit gas usage on the callback
9-
10-
Keeping the callback function simple is crucial because the entropy providers limit gas usage.
11-
This ensures gas usage is predictable and consistent, avoiding potential issues with the callback.
12-
13-
For example, if you want to use entropy to generate a random number for each player in a round of game,
14-
you need to make sure that the callback function works for the maximum number of players that can be in each round.
15-
Otherwise, the callbacks will work for some rounds with fewer players, but will fail for rounds with more players.
16-
17-
Multiple solutions are possible to address this problem. You can store the random number received from the callback and
18-
either ask users to submit more transactions after the callback to continue the flow or run a background crank service
19-
to submit the necessary transactions.
20-
21-
The gas limit for each chain is listed on the [contract addresses](contract-addresses) page.
22-
23-
## Handling callback failures
24-
25-
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:
26-
27-
1. The callback function is using more gas than the allowed limit
28-
2. The callback function contains logic that throws an error
29-
30-
If you're not receiving a callback, you can manually invoke it to identify the specific issue. This allows you to:
31-
32-
- See if the transaction fails and why
33-
- Check the gas usage against the chain's callback gas limit
34-
- Debug your callback implementation
35-
36-
For detailed instructions on how to manually invoke and debug callbacks, refer to the [Debug Callback Failures](debug-callback-failures) guide.
37-
386
## Generating random values within a specific range
397

408
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).
@@ -55,3 +23,50 @@ function mapRandomNumber(
5523
return minRange + int256(randomUint % range);
5624
}
5725
```
26+
27+
Notice that using the modulo operator can distort the distribution of random numbers if it's not a power of 2. This is
28+
negligible for small and medium ranges, but it can be noticeable for large ranges.
29+
For example, if you want to generate a random number between 1 and 52, the probability of having value 5 is approximately
30+
`10^-77` higher than the probability of having value 50 which is infinitesimal.
31+
32+
## Generating multiple random values in a single transaction
33+
34+
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.
35+
36+
In the following example, `mapRandomNumber` is used to generate 6 random attributes for a character.
37+
38+
```solidity
39+
function generateAttributes(bytes32 randomNumber) internal {
40+
int256 strength = mapRandomNumber(
41+
keccak256(abi.encodePacked(randomNumber, "strength")),
42+
15,
43+
20
44+
);
45+
int256 stamina = mapRandomNumber(
46+
keccak256(abi.encodePacked(randomNumber, "stamina")),
47+
10,
48+
15
49+
);
50+
int256 agility = mapRandomNumber(
51+
keccak256(abi.encodePacked(randomNumber, "agility")),
52+
5,
53+
15
54+
);
55+
int256 stealth = mapRandomNumber(
56+
keccak256(abi.encodePacked(randomNumber, "stealth")),
57+
0,
58+
5
59+
);
60+
int256 positionX = mapRandomNumber(
61+
keccak256(abi.encodePacked(randomNumber, "positionX")),
62+
-100,
63+
100
64+
);
65+
int256 positionY = mapRandomNumber(
66+
keccak256(abi.encodePacked(randomNumber, "positionY")),
67+
-100,
68+
100
69+
);
70+
}
71+
72+
```

apps/developer-hub/content/docs/entropy/contract-addresses.mdx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import { EntropyTable } from "../../../src/components/EntropyTable";
77

88
## Mainnets
99

10+
> ⚠️ **Warning**
11+
> The fees for mainnet are dynamically set. Always use the on-chain method `entropy.getFeeV2()` to get the current fee.
12+
13+
The following tables shows the total fees payable when using the **default provider**.
14+
Note that the fees shown below will vary over time with prevailing gas prices on each chain.
15+
1016
The Entropy contract is deployed on the following mainnet chains:
1117

1218
<EntropyTable isMainnet={true} />
@@ -16,11 +22,14 @@ The Entropy contract is deployed on the following mainnet chains:
1622
The default provider on mainnet has a reveal delay to avoid changes on the outcome of the Entropy request because of block reorgs.
1723
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.
1824

19-
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.
25+
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.
2026
Entropy callbacks the consumer as part of this transaction.
2127

2228
## Testnets
2329

30+
> ℹ️ **Note**
31+
> The fees for testnets kept deliberately low and different from the mainnet fees.
32+
2433
The Entropy contract is deployed on the following testnet chains:
2534

2635
<EntropyTable isMainnet={false} />

apps/developer-hub/content/docs/entropy/current-fees.mdx

Lines changed: 0 additions & 37 deletions
This file was deleted.

apps/developer-hub/content/docs/entropy/error-codes.mdx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
---
22
title: Error Codes
3-
description: Error codes and their meanings for Pyth Entropy
3+
description: On chain error codes from the Pyth Entropy EVM contracts
44
---
55

6-
# Error Codes
7-
86
The following table contains the errors used in the Pyth Network's Entropy [EVM contracts](https://github.com/pyth-network/pyth-crosschain/blob/d290f4ec47a73636cf77711f5f68c3455bb8a8ca/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol).
97
This information is derived from [EntropyErrors.sol](https://github.com/pyth-network/pyth-crosschain/blob/d290f4ec47a73636cf77711f5f68c3455bb8a8ca/target_chains/ethereum/entropy_sdk/solidity/EntropyErrors.sol)
108
in the Pyth EntropySDK and can be used to decode error codes programmatically.

apps/developer-hub/content/docs/entropy/fees.mdx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ title: Fees
33
description: Understanding Pyth Entropy fee structure
44
---
55

6-
# Fees
7-
86
The Entropy protocol has been designed to charge fees on a per-request basis. The total fee is
97
the sum of the provider fee, which is determined by the individual provider on a per-blockchain
108
basis, and the protocol fee, which is subject to Pyth governance decisions also on a per-chain
@@ -18,4 +16,4 @@ Note that protocols integrating with Entropy can pass these fees along to their
1816
submits a transaction that requests a random number, the user can directly pay the entropy fees required
1917
with the native blockchain token. There are no fees for revealing the random numbers.
2018

21-
You can check the [current fees](current-fees) page to see the latest fees for each blockchain.
19+
You can check the current fees in the [contract addresses](contract-addresses) page for each blockchain.

apps/developer-hub/content/docs/entropy/generate-random-numbers-evm.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ import { IEntropyV2 } from "@pythnetwork/entropy-sdk-solidity/IEntropyV2.sol";
5151
5252
// @param entropyAddress The address of the entropy contract.
5353
contract YourContract is IEntropyConsumer {
54-
IEntropyV2 public entropy;
54+
IEntropyV2 public entropy;
5555
5656
constructor(address entropyAddress) {
5757
entropy = IEntropyV2(entropyAddress);
5858
}
59+
5960
}
6061
`} />
6162

@@ -81,6 +82,7 @@ code={`function requestRandomNumber() external payable {
8182
uint256 fee = entropy.getFeeV2();
8283
8384
uint64 sequenceNumber = entropy.requestV2{ value: fee }();
85+
8486
}
8587
`} />
8688

@@ -102,7 +104,7 @@ import { IEntropyConsumer } from "@pythnetwork/entropy-sdk-solidity/IEntropyCons
102104
import { IEntropyV2 } from "@pythnetwork/entropy-sdk-solidity/IEntropyV2.sol";
103105
104106
contract YourContract is IEntropyConsumer {
105-
IEntropyV2 entropy;
107+
IEntropyV2 entropy;
106108
107109
// @param entropyAddress The address of the entropy contract.
108110
constructor(address entropyAddress) {
@@ -140,6 +142,7 @@ contract YourContract is IEntropyConsumer {
140142
function getEntropy() internal view override returns (address) {
141143
return address(entropy);
142144
}
145+
143146
}
144147
`} />
145148

apps/developer-hub/content/docs/entropy/meta.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
"debug-callback-failures",
1414
"---Reference Material---",
1515
"contract-addresses",
16-
"current-fees",
1716
"best-practices",
18-
"fees",
19-
"protocol-design",
20-
"error-codes",
21-
"examples",
2217
"request-callback-variants",
18+
"error-codes",
19+
"[Example Applications](https://github.com/pyth-network/pyth-examples/tree/main/entropy)",
20+
"[Entropy Explorer](https://entropy-explorer.pyth.network/)",
21+
"[Fortuna API Reference](https://fortuna.dourolabs.app/docs/)",
22+
"---Understanding Entropy---",
23+
"protocol-design",
24+
"fees",
2325
"create-your-first-entropy-app"
2426
]
2527
}

apps/developer-hub/content/docs/entropy/protocol-design.mdx

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,50 @@ title: Protocol Design
33
description: Understanding how Pyth Entropy generates secure random numbers
44
---
55

6-
# Protocol Design
7-
86
The Entropy protocol implements a secure 2-party random number generation procedure. The protocol
97
is an extension of a simple commit/reveal protocol. The original version has the following steps:
108

11-
1. Two parties A and B each randomly sample secret contributions to the random number, $x_A$ and $x_B$.
12-
2. A commits to their number by sharing $h_A = \mathrm{hash}(x_A)$
9+
1. Two parties A and B each randomly sample secret contributions to the random number, $$(x_A)$$ and $$(x_B)$$.
10+
2. A commits to their number by sharing $$(h_A) = hash(x_A).$$
1311
3. B reveals $x_B$
1412
4. A reveals $x_A$
15-
5. B verifies that $\mathrm{hash}(x_{A}) == h_A$
16-
6. The random number $r = \mathrm{hash}(x_A, x_B)$
13+
5. B verifies that $$hash(x_{A}) == h_A$$
14+
6. The random number $$r = hash(x_A, x_B)$$
1715

1816
This protocol has the property that the result is random as long as either A or B are honest.
19-
Honesty means that (1) they draw their value at random, and (2) for A, they keep $x_A$ a secret until
17+
Honesty means that (1) they draw their value at random, and (2) for A, they keep $$(x_A)$$ a secret until
2018
step 4. Thus, neither party needs to trust the other -- as long as they are themselves honest, they can
21-
ensure that the result $r$ is random.
19+
ensure that the result $$(r)$$ is random.
2220

2321
Entropy implements a version of this protocol that is optimized for on-chain usage. The
2422
key difference is that one of the participants (the provider) commits to a sequence of random numbers
2523
up-front using a hash chain. Users of the protocol then simply grab the next random number in the sequence.
2624

27-
**Setup**: The provider P computes a sequence of $N$ random numbers, $x_i$ for $0 \leq i \leq N-1$:
25+
**Setup**: The provider $$P$$ computes a sequence of $$N$$ random numbers, $$x_i$$ for $$0 \leq i \leq N-1$$:
2826

29-
- $x_{N-1} = \mathrm{random}()$
30-
- $x_i = \mathrm{hash}(x_{i + 1})$
27+
- $$x_{N-1} = random()$$
28+
- $$x_i = hash(x_{i + 1})$$
3129

32-
The provider commits to $x_0$ by posting it to the Entropy contract.
33-
Each random number in the sequence can then be verified against the previous one in the sequence by hashing it, i.e., $\mathrm{hash}(x_i) = x_{i - 1}$
30+
The provider commits to $$x_0$$ by posting it to the Entropy contract.
31+
Each random number in the sequence can then be verified against the previous one in the sequence by hashing it, i.e., $$hash(x_i) = x_{i - 1}$$
3432

3533
**Request**: To produce a random number, the following steps occur.
3634

37-
1. The user randomly samples a secret value $x_u$ and sends a request to the Entropy contract containing $\mathrm{hash}(x_u)$.
38-
2. The Entropy contract stores the request and assigns it a sequence number corresponding to the provider's next random number $x_i$.
39-
3. The provider fulfills the request by revealing $x_i$ to the Entropy contract.
40-
4. The Entropy contract verifies that $\mathrm{hash}(x_i) = x_{i-1}$ (the previous commitment), then computes the random number $r = \mathrm{hash}(x_u, x_i)$ and delivers it to the user's callback function.
35+
1. The user randomly samples their contribution $$(x_U)$$ and submits it to the contract.
36+
(Users may also run this step using an on-chain PRNG if they trust the validator to not collude with the provider.)
37+
2. The contract remembers $$(x_U)$$ and assigns it an incrementing sequence number $$(i)$$, representing which
38+
of the provider's random numbers the user will receive.
39+
3. After sufficient block confirmations, the provider submits a transaction to the contract revealing their contribution $$(x_i)$$ to the contract.
40+
4. The contract verifies $$hash(x_i) == x_{i-1}$$ to prove that $$(x_i)$$ is the $$(i)$$'th random number.
41+
The contract stores $$(x_i)$$ as the $$(i)$$'th random number to reuse for future verifications.
42+
5. If the condition above is satisfied, the random number $$(r) = hash(x_i, x_U)$$.
43+
6. The contract submits a callback to the calling contract with the random number $$(r)$$.
44+
45+
This flow is secure as long as several trust assumptions hold:
46+
47+
- Providers are trusted to reveal their random number $$(x_i)$$ regardless of what the final result $$(r)$$ is. Providers can compute $$(r)$$ off-chain before they reveal $$(x_i)$$, which permits a censorship attack.
48+
- Providers are trusted not to front-run user transactions (via the mempool or colluding with the validator). Providers who observe user transactions can manipulate the result by inserting additional reuests or rotating their commitment.
49+
- Providers are trusted not to keep their hash chain a secret. Anyone with the hash chain can predict the result of a randomness request before it is requested,
50+
and therefore manipulate the result. This applies both to users of the protocol as well as blockchain validators who can use this information to manipulate the on-chain PRNG or reorder user transactions.
4151

42-
This approach ensures that the resulting random number is unpredictable as long as either the user or the provider is honest, while being efficiently verifiable on-chain.
52+
The code of default deployed provider can be found [here](https://github.com/pyth-network/pyth-crosschain/tree/7bccde484f01c19844b7105d63df207a24018957/apps/fortuna).

apps/developer-hub/content/docs/entropy/request-callback-variants.mdx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ title: Request Callback Variants
33
description: Different ways to request random numbers with Pyth Entropy
44
---
55

6-
# Request Callback Variants
7-
86
The [`IEntropyV2`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol) interface provides multiple variants of the `requestV2` function:
97

10-
## 1. Basic Request
8+
## 1. Basic request
119

1210
```solidity
1311
function requestV2() external payable returns (uint64 assignedSequenceNumber);
@@ -31,7 +29,7 @@ function requestBasicRandomNumber() external payable {
3129
}
3230
```
3331

34-
## 2. Request with Gas Limit
32+
## 2. Request with custom gas limit
3533

3634
```solidity
3735
function requestV2(
@@ -59,7 +57,7 @@ function requestWithCustomGas() external payable {
5957
}
6058
```
6159

62-
## 3. Request with Provider
60+
## 3. Request with custom provider
6361

6462
```solidity
6563
function requestV2(
@@ -69,7 +67,7 @@ function requestV2(
6967

7068
This variant allows you to specify a custom entropy provider instead of using the default one.
7169

72-
## 4. Full Custom Request
70+
## 4. Full custom request
7371

7472
```solidity
7573
function requestV2(
@@ -79,4 +77,4 @@ function requestV2(
7977
) external payable returns (uint64 assignedSequenceNumber);
8078
```
8179

82-
This is the most flexible variant that allows you to specify all parameters: custom provider, gas limit, and user random number.
80+
This is the most flexible variant that allows you to specify all parameters: custom provider, custom gas limit, and user random number.

apps/developer-hub/content/docs/entropy/set-custom-gas-limits.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ code={`function requestRandomNumberWithCustomGas(
4242
uint64 sequenceNumber = entropy.requestV2{ value: fee }(customGasLimit);
4343
4444
// Store the sequence number for tracking if needed
45+
4546
}
4647
`} />
4748

@@ -67,8 +68,8 @@ import { IEntropyConsumer } from "@pythnetwork/entropy-sdk-solidity/IEntropyCons
6768
import { IEntropyV2 } from "@pythnetwork/entropy-sdk-solidity/IEntropyV2.sol";
6869
6970
contract CustomGasLimitExample is IEntropyConsumer {
70-
IEntropyV2 public entropy;
71-
mapping(uint64 => bool) public processedRequests;
71+
IEntropyV2 public entropy;
72+
mapping(uint64 => bool) public processedRequests;
7273
7374
constructor(address entropyAddress) {
7475
entropy = IEntropyV2(entropyAddress);
@@ -119,6 +120,7 @@ contract CustomGasLimitExample is IEntropyConsumer {
119120
function getEntropy() internal view override returns (address) {
120121
return address(entropy);
121122
}
123+
122124
}
123125
`} />
124126

0 commit comments

Comments
 (0)