import "witnet-solidity-bridge/contracts/UsingWitnet.sol";
import "witnet-solidity-bridge/contracts/requests/WitnetRequest.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/// @dev Low-level Witnet Data Request composed on construction.
IWitnetRequest public witnetRequest;
/// @dev Randomness value eventually fetched from the Witnet oracle.
bytes32 public witnetRandomness;
/// @dev Unique identifier for the latest request posted to the Witnet Request Board.
uint256 public witnetQueryId;
modifier inStatus(Status _status) {
require(status() == _status, "bad mood");
constructor(WitnetRequestBoard _witnet)
// Compose low-level Witnet data request bytecode,
// that will be eventually posted to the Witnet side-chain
// when calling to _witnetPostRequest(witnetRequest)
witnetRequest = new WitnetRequest(
hex"0a0f120508021a01801a0210022202100b10e807180a200a2833308094ebdc03"
/// @dev Witnet Data Request decoded as:
/// @dev Calculate current status.
function status() public view returns (Status) {
if (witnetRandomness != bytes32(0)) {
} else if (witnetQueryId > 0) {
return Status.Randomizing;
/// @dev Pass from 'Playing' to 'Randomizing' status
// Use internal method inherited from UsingWitnet, as to send the low-level randomness
// request to the WitnetRequestBoard instance. `msg.value` needs to be high enough as
// to cover for `_witnetReward`
(witnetQueryId, _witnetReward) = _witnetPostRequest(witnetRequest);
// Transfer back unused funds:
if (msg.value > _witnetReward) {
payable(msg.sender).transfer(msg.value - _witnetReward);
/// @dev Pass from 'Randomizing' to either 'Awarding' or 'Playing' status, depending
/// @dev on whether the randomness request was solved, or reverted, respectively.
inStatus(Status.Randomizing)
uint _queryId = witnetQueryId;
// Use internal method inherited from UsingWitnet, as to check whether the randomness
// request has already been reported:
require(_witnetCheckResultAvailability(_queryId), "not yet reported");
// Low-level interaction with the WitnetRequestBoard as to deserialize the result,
// and check whether the randomness request failed or succeeded:
Witnet.Result memory _result = witnet.readResponseResult(_queryId);
witnetRandomness = witnet.asBytes32(_result);
// step back to 'Playing' status: