Randcast
An Introduction
ARPA Network vs Randcast
Randcast is an on-chain verifiable random number generation service with an easy-to-use Smart Contract SDK that can be directly integrated into DApps to provide out-of-the-box functionalities like rolling dice, shuffling an array, generating in-game item attributes based on probability, generating random in-game maps or dungeons, and deciding the probability outcomes of a lottery.
Randcast responds to these randomness requests by leveraging the ARPA Network, which consists of many nodes that perform BLS threshold signature tasks. A signature generated by this task can be used as the initial entropy to create a random number, as BLS threshold signatures are verifiably random.
The full flow that occurs when a DApp requests randomness is as follows:
The Randcast Adapter Contract receives a randomness request from a DApp or Web3 game, initiates a BLS-TSS task, and sends an on-chain event.
The ARPA Network acknowledges this event and completes the task, then sends back the signature as the random seed.
The Randcast Adapter Contract takes the random seed, converts it to the desired randomness type (dice roll, shuffled array, etc..), then calls back the subsequent DApp or Web3 game logic that will utilize the randomness result.
When to use Randcast?
You can directly integrate our out-of-the-box functionality suite when building a DApp or Web3 game that requires safe, untampered, unbiased, verifiable randomness. You can also customize this functionality by extending our SDK.
The Need for Reliable Randomness
Using a random number in a smart contract is a common requirement. For example, a game may need to generate a random number to determine the lottery winner. However, the blockchain is deterministic, and the result of a smart contract is determined by the input. That is to say, a blockchain is a decentralized and trustless environment where the random number generation can be easily manipulated by any party in the network. e.g., if we use a block hash or timestamp as the source of randomness, the miners can manipulate it to their advantage by either withholding the block or manipulating the timestamp.
The solution is to use an external source of randomness. Randcast is a service that generates random numbers through a decentralized network and provides them to smart contracts. The process of generating randomness is both transparent and verifiable. It is facilitated by a group of nodes that utilize the threshold BLS signature scheme. Before returning the requested random number to the user's smart contract, the randomness is verified on-chain by the Randcast Adapter smart contract.
Randcast and the ARPA Network solve another major issue with random number generation. Randomness generated by a single off-chain entity could potentially be tampered with or manipulated by that entity. Randcast solves this issue by using multiple nodes in the ARPA Network to generate randomness through BLS Threshold signature tasks, which means that no single node has the ability to manipulate the final randomness result.
Request and Fulfillment Lifecycle
Within the ARPA Network, the randomness generation process has two phases: request and fulfillment. The request phase (initiated by the user) is to request randomness, and the fulfillment phase (initiated by the nodes) is to verify and return the randomness to the user's smart contract. The two phases are streamlined by a callback mechanism. The abstract callback function defined in the consumer contract can be overridden by the user to implement the logic beyond receiving the randomness. The callback function is called by the Adapter contract in the fulfillment phase.
During the request phase, the user signs a transaction invoking the request function in the consumer contract deployed by the user. The consumer contract then calls the request function in the Adapter contract, which emits a RandomnessRequest
event for the nodes in the network to listen to. A unique request ID is then generated and returned to the user's consumer contract. The user can use this request ID to query the request status.
Upon receiving the request, the nodes generate and aggregate the randomness. The randomness is then committed to the Adapter contract by the committer nodes in the group. Here comes the fulfillment phase: The Adapter contract verifies the randomness and calls the callback function in the user's consumer contract. Whether the callback function is successfully called or not, the Adapter contract will emit a RandomnessRequestResult
event to notify the user and the nodes in the network. Note that the gas cost of the verification and callback function is directly paid by the committer node and then reimbursed by the user.
Subscription
We provide an intuitive subscription mechanism to handle payments for the fulfillment phase.
Note: Randcast v0.1.0 is FREE. You ONLY need the subscription account to pay for the Gas fee. Accordingly, the subscription is funded with ETH.
Useres can interact with subscriptions in the following ways:
Create a subscription by calling the
createSubscription
function in the Adapter contract. (The subscription is identified by a subscription ID, which is returned to the user and emitted in theSubscriptionCreated
event. The user can use the subscription ID to query the subscription status.)Bind the consumer contract to the subscription by calling the
addConsumer
function in the Adapter contract. (The user can bind multiple consumer contracts to the same subscription. The consumer contract is part of your DApp or Web3 game implementation that handles the subsequent logic after receiving the randomness result from Randcast.)Fund the subscription by calling the
fundSubscription
function in the Adapter contract.Remove the consumer contract from the subscription by calling the
removeConsumer
function in the Adapter contract.Cancel the subscription as well as claim the remaining balance by calling the
cancelSubscription
function in the Adapter contract.
When the consumer contracts request randomness, the Adapter will check the subscription balance based on the inflight requests. If the subscription balance is insufficient, the request will fail. When the randomness is fulfilled, the transaction costs are calculated, and the subscription balance will be deducted accordingly. Here, Randcast tries to provide a fail-fast mechanism to inform the user in the request phase whether the request will be fulfilled successfully or not.
Automatic Gas Estimation
Since there are two phases in the randomness generation process, request and fulfillment do not happen in the same transaction. The user needs to tell the Adapter contract how much gas is needed to call the callback function in the user's consumer contract so that the Adapter contract can estimate the gas cost of the fulfillment phase to enable the fail-fast mechanism. callbackGasLimit
and callbackMaxGasPrice
are two parameters used to estimate the gas cost and instruct the behavior of committer nodes. callbackGasLimit
is the gas limit of the callback function, and callbackMaxGasPrice
is the maximum gas price that the user is willing to pay for the callback function. If the gas cost of the callback function is greater than callbackGasLimit
, the invocation of the callback function will fail. If the current gas price on-chain is greater than callbackMaxGasPrice
, the committer nodes will not commit the randomness to the Adapter contract.
Users need to correctly calculate the callbackGasLimit
and callbackMaxGasPrice
to ensure that the randomness generation process can be completed successfully. To make life easier, we provide an automatic gas estimation mechanism. As long as the consumer contract extends the GeneralRandcastConsumerBase
contract, these two parameters will be automatically calculated and set in the first request. With our Randcast CLI tool, the user can estimate the gas cost before the first request so that the user can fund the subscription with just enough funds to complete the request. The only thing the user needs to do is to implement business logic in the callback function. Experienced users can also manually set these two parameters by calling the setCallbackGasConfig
function in the consumer contract.
Last updated