← Developer Forum

Entropy·help question

Understanding Entropy after a long hack

Open on dev-forum →Back to forum

Hello Pyth Team, it’s Krisztian from team TrustGiveAway . I was working a lot with Pyth Entropy, but unfortunately I was not able to understand it 100%. If it’s possible could you please review our entropy code? Sometimes it gave me the randomNumber as requested, but most of the time I did not receive back the callback. You can check my code here, here is the smart contract link: TrustGiveaway/contracts/contracts/Contest.sol at master · RegisGraptin/TrustGiveaway · GitHub

The two main functions which uses Pyth is EndContest and the entropyCallback.

Furthermore I have tried to make a simplified pyth contract code in Remix, attaching code here:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

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

contract Pyth is IEntropyConsumer {
    IEntropy public entropy;
    address public entropyProvider;

    // Mapping from user address to their last random number (1-10)
    mapping(address => uint8) public lastRandomNumber;
    mapping(uint64 => address) public requesters;

    event RandomNumberGenerated(address user, uint8 number);

    constructor(address entropyAddress) {
        entropy = IEntropy(entropyAddress);
        entropyProvider = entropy.getDefaultProvider();
    }

    function generateSeed() public view returns (bytes32) {
        // For example: hash of block.timestamp + msg.sender
        return keccak256(abi.encodePacked(block.timestamp, msg.sender));
    }

    function requestRandomNumber(bytes32 userRandomNumber) external payable {
        uint256 fee = entropy.getFee(entropyProvider);
        require(msg.value >= fee, "Insufficient fee");

        uint64 requestId = entropy.requestWithCallback{value: fee}(
            entropyProvider,
            userRandomNumber
        );
        requesters[requestId] = msg.sender;
    }

    function entropyCallback(
        uint64 sequenceNumber,
        address provider,
        bytes32 randomNumber
    ) internal override {
        // Convert bytes32 randomNumber to uint256
        uint256 randNum = uint256(randomNumber);

        // Map the number to 1-10
        uint8 numberBetween1and10 = uint8((randNum % 10) + 1);

        // Store it for the caller — this example stores for the tx.origin since callback has no user param
        // WARNING: This is a simplification, in reality you need to link the callback to the original requester.
        // For demo, assume tx.origin is the user who requested.
        lastRandomNumber[tx.origin] = numberBetween1and10;
        emit RandomNumberGenerated(msg.sender, numberBetween1and10);
    }

    // Optional: get the last random number for the caller
    function getMyLastRandomNumber() external view returns (uint8) {
        return lastRandomNumber[msg.sender];
    }

    // Required by IEntropyConsumer interface - returns entropy contract address
    function getEntropy() internal view override returns (address) {
        return address(entropy);
    }
}

I have tried this code actually in 3 chains (AbstractSepolia, OptimismSepolia and BaseSepolia) but unfortunately when I called getMyLastRandomNumber I always got back 0. I am generating a bytes32 seed for random Number generation, then I am saving it in the lastRandomNumber value. I was thinking your site wDoes the tx.origin also incorrect in this case? Can you please help out?

Showing the original post only. Read the full thread on dev-forum.pyth.network ↗

Replies: 1
Views: 505
Likes: 0
Posted: 6/1/2025

Source: https://dev-forum.pyth.network/t/understanding-entropy-after-a-long-hack/186 · external id 186