DeploySEALED

■◆╲○▫&^#●○◇#&@●●▪#╳▫%╲●!◇█%░□▪▫!?▪~*%!^%&█░□○■*!○▒&■□▫╲□╱◇%#█░○&

Transaction ID

Timestamp

Jan 09, 2026, 07:55:33 PM UTC
1mo ago

Block Height

138,375,743

Computation

0

Execution Fee

0.0051 FLOW

Transaction Summary

Deploy

Contract deployment

Contract deployment

Script Arguments

0nameString
RandomConsumer
1codeString
import Burner from 0xf233dcee88fe0abe import RandomBeaconHistory from 0xe467b9dd11fa00df import Xorshift128plus from 0xa092c4aab33daeda /// This contract is intended to make it easy to consume randomness securely from the Flow protocol's random beacon. It provides /// a simple construct to commit to a request, and reveal the randomness in a secure manner as well as helper functions to /// generate random numbers in a range without bias. /// /// See an example implementation in the repository: https://github.com/onflow/random-coin-toss /// access(all) contract RandomConsumer { /* --- PATHS --- */ // /// Canonical path for Consumer storage access(all) let ConsumerStoragePath: StoragePath /* --- EVENTS --- */ // access(all) event RandomnessRequested(requestUUID: UInt64, block: UInt64) access(all) event RandomnessSourced(requestUUID: UInt64, block: UInt64, randomSource: [UInt8]) access(all) event RandomnessFulfilled(requestUUID: UInt64, randomResult: UInt64) access(all) event RandomnessFulfilledWithPRG(requestUUID: UInt64) /////////////////// // PUBLIC FUNCTIONS /////////////////// /// Retrieves a revertible random number in the range [min, max]. By leveraging the Cadence's revertibleRandom /// method, this function ensures that the random number is generated within range without risk of modulo bias. /// /// @param min: The minimum value of the range /// @param max: The maximum value of the range /// /// @return A random number in the range [min, max] /// access(all) fun getRevertibleRandomInRange(min: UInt64, max: UInt64): UInt64 { return min + revertibleRandom<UInt64>(modulo: max - min + 1) } /// Retrieves a random number in the range [min, max] using the provided PRG reference to source additional /// randomness if needed. This method is implemented to avoid risk of modulo bias. Passing the PRG by reference /// ensures that its state is advanced and numbers proceed down the PRG's random walk. /// /// @param prg: The PRG (passed by reference) to use for random number generation /// @param min: The minimum value of the range /// @param max: The maximum value of the range /// /// @return A random number in the range [min, max] /// access(all) fun getNumberInRange(prg: &Xorshift128plus.PRG, min: UInt64, max: UInt64): UInt64 { pre { min < max: "RandomConsumer.getNumberInRange: Cannot get random number with the provided range! " .concat(" The min must be less than the max. Provided min of ") .concat(min.toString()).concat(" and max of ".concat(max.toString())) } let range = max - min // Calculate the inclusive range of the random number let bitsRequired = UInt256(self._mostSignificantBit(range)) // Number of bits needed to cover the range let mask: UInt256 = (1 << bitsRequired) - 1 // Create a bitmask to extract relevant bits let shiftLimit: UInt256 = 256 / bitsRequired // Number of shifts needed to cover 256 bits var shifts: UInt256 = 0 // Initialize shift counter var candidate: UInt64 = 0 // Initialize candidate var value: UInt256 = prg.nextUInt256() // Assign the first 256 bits of randomness while true { candidate = UInt64(value & mask) // Apply the bitmask to extract bits if candidate <= range { break } // Shift by the number of bits covered by the mask value = value >> bitsRequired shifts = shifts + 1 // Get a new value if we've exhausted the current one if shifts == shiftLimit { value = prg.nextUInt256() shifts = 0 } } // Scale candidate to the range [min, max] return min + candidate } /// Returns a new Consumer resource /// /// @return A Consumer resource /// access(all) fun createConsumer(): @Consumer { return <-create Consumer() } /* CONSUMER ADAPTERS The following public methods are helpful for those who wish to simply request & fulfill randomness without managing their own Consumer resource - e.g. request/fulfill randomness in transaction context without a contract */ /// Makes a request for randomness at some block height greater than or equal to the current block height /// /// @param at: The block height at which the Request may be revealed. Upon fulfillment, the source of randomness /// will be sourced from Flow's RandomnessBeaconHistory corresponding to the request's block height /// /// @return A Request resource which must be provided to fulfill the random request access(all) fun requestFutureRandomness(at blockHeight: UInt64): @Request { return <-self.borrowConsumer().requestFutureRandomness(at: blockHeight) } /// Fulfills a random request with a random UInt64 with randomness sourced from the corresponding Request.block /// /// @param request: The Request resource issued when randomness was requested /// /// @return A random UInt64 /// access(all) fun fulfillRandomRequest(_ request: @Request): UInt64 { return self.borrowConsumer().fulfillRandomRequest(<-request) } /// Fulfills a random request with a random UInt64 within inclusive range /// /// @param request: The Request resource issued when randomness was requested /// @param min: The inclusive minimum of the range /// @param max: The inclusive maximum of the range /// /// @return A random UInt64 within the requested range /// access(all) fun fulfillRandomRequestInRange(_ request: @Request, min: UInt64, max: UInt64): UInt64 { return self.borrowConsumer().fulfillRandomInRange(request: <-request, min: min, max: max) } /// Fulfills a random request with a pseudo-random generator struct /// /// @param request: The Request resource issued when randomness was requested /// /// @return A PRG with randomness sourced corresponding to the the Request's block height and salted with the /// Request's uuid /// access(all) fun fulfillRandomRequestWithPRG(_ request: @Request): Xorshift128plus.PRG { return self.borrowConsumer().fulfillWithPRG(request: <-request) } /////////////////// // CONSTRUCTS /////////////////// access(all) entitlement Commit access(all) entitlement Reveal /// Interface to allow for a Request to be contained within another resource. The existing default implementations /// enable an implementing resource to simply list the conformance without any additional implementation aside from /// the inner Request resource. However, implementations should properly consider the optional when interacting /// with the inner resource outside of the default implementations. The post-conditions ensure that implementations /// cannot act dishonestly even if they override the default implementations. /// access(all) resource interface RequestWrapper { /// The Request contained within the resource access(all) var request: @Request? /// Returns the block height of the Request contained within the resource /// /// @return The block height of the Request or nil if no Request is contained /// access(all) view fun getRequestBlock(): UInt64? { post { result == nil || result! == self.request?.block: "RandomConsumer.RequestWrapper.getRequestBlock(): Must return nil or the block height of RequestWrapper.request" } return self.request?.block ?? nil } /// Returns whether the Request contained within the resource can be fulfilled or not /// /// @return Whether the Request can be fulfilled /// access(all) view fun canFullfillRequest(): Bool { post { result == self.request?.canFullfill() ?? false: "RandomConsumer.RequestWrapper.canFullfillRequest(): Must return the result of RequestWrapper.request.canFullfill()" } return self.request?.canFullfill() ?? false } /// Pops the Request from the resource and returns it /// /// @return The Request that was contained within the resource /// access(Reveal) fun popRequest(): @Request { pre { self.request != nil: "RandomConsumer.RequestWrapper.popRequest(): Request must not be nil before popRequest" } post { self.request == nil: "RandomConsumer.RequestWrapper.popRequest(): Request must be nil after popRequest" result.uuid == before((self.request?.uuid)!): "RandomConsumer.RequestWrapper.popRequest(): Request uuid must match result uuid" } let req <- self.request <- nil return <- req! } } /// A resource representing a request for randomness /// access(all) resource Request { /// The block height at which the request was made access(all) let block: UInt64 /// Whether the request has been fulfilled access(all) var fulfilled: Bool init(_ blockHeight: UInt64) { pre { getCurrentBlock().height <= blockHeight: "Requested randomness for block \(blockHeight) which has passed. Can only request randomness sourced from future block heights." } self.block = blockHeight self.fulfilled = false } /// Returns whether the request can be fulfilled as defined by whether it has already been fulfilled and the /// created block height has been surpassed. /// /// @param: True if it can be fulfilled, false otherwise /// access(all) view fun canFullfill(): Bool { return !self.fulfilled && getCurrentBlock().height > self.block } /// Returns the Flow's random source for the requested block height /// /// @return The random source for the requested block height containing at least 16 bytes (128 bits) of entropy /// access(contract) fun _fulfill(): [UInt8] { pre { !self.fulfilled: "RandomConsumer.Request.fulfill(): The random request has already been fulfilled." self.block < getCurrentBlock().height: "RandomConsumer.Request.fulfill(): Cannot fulfill random request before the eligible block height of " .concat((self.block + 1).toString()) } self.fulfilled = true let res = RandomBeaconHistory.sourceOfRandomness(atBlockHeight: self.block).value emit RandomnessSourced(requestUUID: self.uuid, block: self.block, randomSource: res) return res } } /// This resource enables the easy implementation of secure randomness, implementing the commit-reveal pattern and /// using a PRG to generate random numbers from the protocol's random source. /// access(all) resource Consumer { /* ----- COMMIT STEP ----- */ // /// Requests randomness, returning a Request resource /// /// @return A Request resource /// access(Commit) fun requestRandomness(): @Request { post { result.block == getCurrentBlock().height: "Requested randomness for block height \(getCurrentBlock().height) but returned Request for randomness at block \(result.block)" } let currentHeight = getCurrentBlock().height let req <-create Request(currentHeight) emit RandomnessRequested(requestUUID: req.uuid, block: req.block) return <-req } /// Requests randomness sourced from a future block height, returning a Request resource /// /// @param at: The future block height for which randomness should be sourced /// /// @return A Request resource /// access(Commit) fun requestFutureRandomness(at blockHeight: UInt64): @Request { post { blockHeight == result.block: "Requested randomness for block height \(blockHeight) but returned Request for randomness at block \(result.block)" } let req <-create Request(blockHeight) emit RandomnessRequested(requestUUID: req.uuid, block: req.block) return <-req } /* ----- REVEAL STEP ----- */ // /// Fulfills a random request, returning a random number /// /// @param request: The Request to fulfill /// /// @return A random number /// access(Reveal) fun fulfillRandomRequest(_ request: @Request): UInt64 { let reqUUID = request.uuid // Create PRG from the provided request & generate a random number let prg = self._getPRGFromRequest(request: <-request) let res = prg.nextUInt64() emit RandomnessFulfilled(requestUUID: reqUUID, randomResult: res) return res } /// Fulfills a random request, returning a random number in the range [min, max] without bias. Developers may be /// tempted to use a simple modulo operation to generate random numbers in a range, but this can introduce bias /// when the range is not a multiple of the modulus. This function ensures that the random number is generated /// without bias using a variation on rejection sampling. /// /// @param request: The Request to fulfill /// @param min: The minimum value of the range /// @param max: The maximum value of the range /// /// @return A random number in the range [min, max] /// access(Reveal) fun fulfillRandomInRange(request: @Request, min: UInt64, max: UInt64): UInt64 { pre { min < max: "RandomConsumer.Consumer.fulfillRandomInRange(): Cannot fulfill random number with the provided range! " .concat(" The min must be less than the max. Provided min of ") .concat(min.toString()).concat(" and max of ".concat(max.toString())) } let reqUUID = request.uuid // Create PRG from the provided request & generate a random number & generate a random number in the range let prg = self._getPRGFromRequest(request: <-request) let prgRef: &Xorshift128plus.PRG = &prg let res = RandomConsumer.getNumberInRange(prg: prgRef, min: min, max: max) emit RandomnessFulfilled(requestUUID: reqUUID, randomResult: res) return res } /// Creates a PRG from a Request, using the request's block height source of randomness and UUID as a salt. /// This method fulfills the request, returning a PRG so that consumers can generate any number of random values /// using the request's source of randomness, seeded with the request's UUID as a salt. /// /// NOTE: The intention in exposing this method is for consumers to be able to generate several random values /// per request, and the returned PRG should be used in association to a single request. IOW, while the PRG is /// a storable object, it should be treated as ephemeral, discarding once all values have been generated /// corresponding to the fulfilled request. /// /// @param request: The Request to use for PRG creation /// /// @return A PRG object from which to generate random values in assocation with the fulfilled request /// access(Reveal) fun fulfillWithPRG(request: @Request): Xorshift128plus.PRG { let reqUUID = request.uuid let prg = self._getPRGFromRequest(request: <-request) emit RandomnessFulfilledWithPRG(requestUUID: reqUUID) return prg } /// Internal method to retrieve a PRG from a request. Doing so fulfills the request, and is intended for /// internal functionality serving a single random value. /// /// @param request: The Request to use for PRG creation /// /// @return A PRG object from which this Consumer can generate a single random value to fulfill the request /// access(self) fun _getPRGFromRequest(request: @Request): Xorshift128plus.PRG { let source = request._fulfill() let salt = request.uuid.toBigEndianBytes() Burner.burn(<-request) return Xorshift128plus.PRG(sourceOfRandomness: source, salt: salt) } } /// Returns the most significant bit of a UInt64 /// /// @param x: The UInt64 to find the most significant bit of /// /// @return The most significant bit of x /// access(self) view fun _mostSignificantBit(_ x: UInt64): UInt8 { var bits: UInt8 = 0 var tmp: UInt64 = x while tmp > 0 { tmp = tmp >> 1 bits = bits + 1 } return bits } /// Returns an authorized reference on the contract account's stored Consumer /// access(self) fun borrowConsumer(): auth(Commit, Reveal) &Consumer { let path = /storage/consumer return self.account.storage.borrow<auth(Commit, Reveal) &Consumer>(from: path) ?? panic("Consumer not found - ensure the Consumer has been initialized at \(path)") } init() { self.ConsumerStoragePath = StoragePath(identifier: "RandomConsumer_".concat(self.account.address.toString()))! self.account.storage.save(<-create Consumer(), to: /storage/consumer) } }

Cadence Script

1transaction(name: String, code: String ) {
2		prepare(signer: auth(AddContract) &Account) {
3			signer.contracts.add(name: name, code: code.utf8 )
4		}
5	}