Get a provable Random Number on a blockchain from HPB chain

Jeff P
3 min readJan 13, 2022


The following is a guide to pulling a number from the HPB blockchain on Solidity versions 0.5.8 and above.

Many chains use pseudo-random number generators which are deterministic. Others use oracles or solutions such as Chainlink VRF, which can be a hassle to setup, and for some chains, can be prohibitively expensive to call. For example, calling a random number via Chainlink VRF on the Binance Smart Chain, currently costs 0.2 LINK (roughly $5!)

HPB chain is able to offer provable random numbers on-chain for FREE, thanks to HRNG. This stands for Hardware Random Number Generator, and is possible because of the Blockchain Offload Engine (BOE) card installed in every master node on the network. You can think of the BOE card as a bit like a graphics card in a PC, only it was developed and manufactured specifically for running a blockchain very fast, with the ability for the chain to scale.

Another important feature of the BOE is it’s ability to generate provable random numbers.


block.random is a Solidity value type, exclusive to HPB chain, whereby a random value will be published by a miner. The number is generated based on fractional micro-voltage fluctuations on the BOE hardware card itself.

block.random is currently only supported up to Solidity version 0.5.7, which makes it impossible to compile with the latest contract code (currently 0.8.11)

The current workaround is to release a hardware random number smart contract code to the HPB main network, which you can then reference in other (later) versions of Solidity smart contracts.

Also, this value type won’t be recognized by

Instead you would need to deploy the contract using HPB’s own compiler,

So for example, you could deploy this contract:

pragma solidity ^0.5.6;contract HRNG {

function getRandom() public view returns (bytes32) {
return block.random;

function getCurrentBlockNumber() public view returns (uint256) {
return block.number;

function getRandomFromRange(uint256 _min, uint256 _max)
public view returns (uint256) {
uint256 random = (uint256(block.random) % (_max) + _min);
return random;


Once deployed using HPB’s own custom compiler, you are now free to reference the getRandom() function from newer smart contracts, which can be deployed using

So for example, you could deploy this contract on solidity version 0.8.7 and reference the contract address of the first deployed contract HRNG.

So for example, the first contract was deployed to HPB


We then deploy a new smart contract that references this first smart contract. Here is an example:

/ SPDX-License-Identifier: Unlicensedpragma solidity 0.8.0;abstract contract HRNG {   function getRandom() public view virtual returns (bytes32);}contract RetrieveRandom {address hrngAddr;HRNG hrng;   constructor (address hrngaddr) {      hrngAddr = hrngaddr;      hrng = HRNG(hrngAddr);   }   function retrieveNumber() public view returns (uint256) {      uint256 random = uint256(hrng.getRandom());      return random;   }}

Once the contract is deployed, the random number called should match the random number from the first contract being pulled from the block.random value

You now have a provable random number, available at each new block, in any new smart contract.

For more information on the HPB chain, visit

HPB Telegram —



Jeff P

I tend to write about anything I find interesting. There’s not much more to it than that really :-)