获取随机数教程
#
简介PlatON 内置合约(合约地址:lat1xqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9fgva)提供生成 VRF 随机数功能。该合约最多支持返回500个随机数,返回值为[]byte数组,每32个字节表示一个随机数。
#
入参- input []byte:需要获取的随机数的个数,不得超过500。该入参表示为将一个 uint64 值,填充到32个字节。比如:0x0000000000000000000000000000000000000000000000000000000000000006 表示获取6个随机数
#
返回值- ret []byte:每32个字节表示一个随机数
#
代码示例#
Python SDK 调用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跨合约调用// SPDX-License-Identifier: MITpragma solidity ^0.8.0;
/** * 调用PlatON内置合约生成VRF随机数 */contract VRF {
error InvalidRandomWords(uint32 numWords, uint256 returnValueLength);
// VrfInnerContract 内置合约地址 address vrfInnerContractAddr = 0x3000000000000000000000000000000000000001;
// 32个字节表示uint256 uint32 base = 32;
/** * 调用 VrfInnerContract 内置合约生成VRF随机数 * @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 合约input data * @param addr 合约地址 */ 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; }}