Skip to content

Instantly share code, notes, and snippets.

@andelf
Last active February 22, 2021 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andelf/3f605596c19b1612cf7eaf8ed429e416 to your computer and use it in GitHub Desktop.
Save andelf/3f605596c19b1612cf7eaf8ed429e416 to your computer and use it in GitHub Desktop.
2-Step Random number for TRON(TVM)

Output

function currentRequestId() view returns (uint256 )
function fulfillRandomRequest(uint256 reqId) returns (uint256 )
function isRequestIdFulfilled(uint256 ) view returns (bool )
function randomResult(uint256 ) view returns (uint256 )
function requestRandom() returns (uint256 requestId)
Current reqId: 10
req_id: 11  rand: 2
req_id: 12  rand: 53
req_id: 13  rand: 37
req_id: 14  rand: 58
req_id: 15  rand: 68
req_id: 16  rand: 5
req_id: 17  rand: 48
req_id: 18  rand: 6
req_id: 19  rand: 77
req_id: 20  rand: 60
req_id: 21  rand: 39
....
pragma solidity >0.7.0;
contract Random {
// 2-step random
struct RandomRequest {
address user;
uint256 blockNumber;
}
uint256 public currentRequestId = 0;
mapping(uint256 => RandomRequest) private randomRequests;
mapping(uint256 => bool) public isRequestIdFulfilled;
mapping(uint256 => uint256) public randomResult;
uint256 private _salt = 0x233333;
function random(
address account,
uint256 seed,
uint256 mod
) internal view returns (uint256) {
return
uint256(
keccak256(
abi.encodePacked(
seed,
account,
block.coinbase,
block.number,
block.timestamp
// blockhash(block.number - 1) can be used here to further strenth its randomness.
)
)
) % mod;
}
event NewRandomRequest(uint256 indexed id);
event RandomRequestFulfilled(uint256 indexed id);
function requestRandom() public returns (uint256 requestId) {
address userAddr = msg.sender;
currentRequestId += 1;
randomRequests[currentRequestId] = RandomRequest(
userAddr,
block.number
);
emit NewRandomRequest(currentRequestId);
return currentRequestId;
}
function fulfillRandomRequest(uint256 reqId) public returns (uint256) {
require(reqId <= currentRequestId, "reqId overflow");
require(!isRequestIdFulfilled[reqId], "reqId alreay fulfilled");
RandomRequest memory req = randomRequests[reqId];
require(req.blockNumber != block.number, "call me later");
uint256 randomSeed = uint256(blockhash(req.blockNumber));
require(randomSeed != 0x0, "req expired");
_salt += 1; // _salt is used for multiple random in a single call
uint256 r = random(req.user, randomSeed + _salt, 100);
// DO job with random Seed
randomResult[reqId] = r;
emit RandomRequestFulfilled(reqId);
isRequestIdFulfilled[reqId] = true;
return r;
}
}
import json
import os
import time
from tronpy import Tron
from tronpy import keys
__dir__ = os.path.dirname(__file__)
random_cntr = "TJRnneaqiBZhcgkpZt2yVmcvr3NnyX9eGv"
owner = "caller address"
priv_key = keys.PrivateKey.fromhex(
"private key of owner"
)
def timestamp():
return int(time.time())
client = Tron(network="nile")
cntr = client.get_contract(random_cntr)
for f in cntr.functions:
print(f)
print("Current reqId:", cntr.functions.currentRequestId())
req_id = cntr.functions.currentRequestId()
if not cntr.functions.isRequestIdFulfilled(req_id):
rand_val = (
cntr.functions.fulfillRandomRequest(req_id)
.with_owner(owner)
.fee_limit(10_000_000)
.build()
.sign(priv_key)
.broadcast()
.result()
)
while True:
req_id = (
cntr.functions.requestRandom()
.with_owner(owner)
.fee_limit(10_000_000)
.build()
.sign(priv_key)
.broadcast()
.result()
)
print("req_id:", req_id, end="", flush=True)
rand_val = (
cntr.functions.fulfillRandomRequest(req_id)
.with_owner(owner)
.fee_limit(10_000_000)
.build()
.sign(priv_key)
.broadcast()
.result()
)
print(" rand:", rand_val)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment