Skip to main content

Get a Random Number

Overview#

PlatON built-in system contract (contract address: lat1xqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9fgva) provides the function of generating VRF random numbers. The contract supports returning up to 500 random numbers, and the return value is an array of []bytes, where each 32 bytes represents a random number.

Input parameters#

  • input []byte: The number of random numbers to be obtained, which cannot exceed 500. The input parameter is expressed as a uint64 value, padded to 32 bytes. For example: 0x00000000000000000000000000000000000000000000000000000000000006 means get 6 random numbers

return value#

  • ret[]byte: every 32 bytes represents a random number

Code Example#

Python SDK calls#

from client_sdk_python import Web3, WebsocketProvider
w3 = Web3(WebsocketProvider('ws://192.168.120.121:7789'))
txn = {    "to": 'lat1xqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9fgva',    "data": 0x000000000000000000000000000000000000000000000000000000000000001f4,}
crypt_hex = w3.platon.call(txn).hex()[2:]crypts = [crypt_hex[i: i + 64] for i in range(len(crypt_hex)) if i % 64 == 0]
print(len(crypts), crypts)

Solidity cross-contract calls#

// SPDX-License-Identifier: MITpragma solidity ^0.8.0;
contract VRF {
  error InvalidRandomWords(uint32 numWords, uint256 returnValueLength);
  // VrfInnerContract system contract  address vrfInnerContractAddr = 0x3000000000000000000000000000000000000001;
  // every 32 bytes represents a random number  uint32 base = 32;
  /**   * Get Random Number   * @param numWords    */  function requestRandomWords(uint32 numWords) internal returns (uint256[] memory) {    bytes memory data = abi.encode(numWords);    bytes memory returnValue = assemblyCall(data, vrfInnerContractAddr);
    if (numWords * base != returnValue.length) {        revert InvalidRandomWords(            numWords,            returnValue.length        );    }
    uint256[] memory randomWords = new uint256[](numWords);    for(uint i = 0; i < numWords; i++) {        uint start = i * base;        randomWords[i] = sliceUint(returnValue, start);    }
    return randomWords;  }
  /**   * delegatecall   * @param data contract input data   * @param addr contract address   */    function assemblyCall(bytes memory data, address addr) internal returns (bytes memory) {        uint256 len = data.length;        uint retsize;        bytes memory resval;        assembly {            let result := delegatecall(gas(), addr, add(data, 0x20), len, 0, 0)            retsize := returndatasize()        }        resval = new bytes(retsize);        assembly {            returndatacopy(add(resval, 0x20), 0, returndatasize())        }        return resval;    }
    function sliceUint(bytes memory bs, uint start) internal pure returns (uint256) {        require(bs.length >= start + 32, "slicing out of range");        uint256 x;        assembly {            x := mload(add(bs, add(0x20, start)))        }        return x;    }}