Skip to content

Commit

Permalink
Merge branch 'main' into update-discord-link
Browse files Browse the repository at this point in the history
  • Loading branch information
bthaile authored Sep 25, 2024
2 parents d1f0478 + 134e9cf commit 361abeb
Show file tree
Hide file tree
Showing 28 changed files with 1,249 additions and 331 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Note: Previews are built for each Git branch by Vercel workflow.

For additional assistance or integration support, feel free to request help in the `#devex-builders` channel on the [Flow Discord](https://discord.gg/flow) server.


## Updating Existing Content

Updating existing content is a seamless process:
Expand Down
67 changes: 34 additions & 33 deletions docs/build/advanced-concepts/randomness.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Flow On-chain Randomness
sidebar_label: VRF (Randomness)
title: Flow On-chain Randomness in Cadence
sidebar_label: VRF (Randomness) in Cadence
---

# Randomness on FLOW
Expand All @@ -18,11 +18,11 @@ Flow’s onchain randomness delivers immediate random values within smart contra
- **DAOs:** Assists in unbiased voting and task assignments through immediate randomness.
- **Broad Applications:** Extends to any domain requiring impartial randomization, from asset distribution to security mechanisms, all with the added benefit of on-demand availability.

## History of the Distributed Random Beacon
## History of the Distributed Randomness Beacon

Within the Flow protocol, the heart of randomness generation lies in the "Distributed Random Beacon."
Within the Flow protocol, the heart of randomness generation lies in the "Distributed Randomness Beacon".
This module generates randomness that is distributed across the network while adhering to established cryptographic and security standards.
The output from the randomness beacon is a sequence of random bytes that are unpredictable and impartial.
The output from the randomness beacon is a random source for each block that is unpredictable and impartial.

For over three years, the beacon has ensured protocol security by selecting which consensus node gets to propose the next block and assigning verification nodes to oversee block computations. For those interested in a more detailed exploration of the randomness beacon and its inner workings, you can read [the technical deep dive on the Flow forum](https://forum.flow.com/t/secure-random-number-generator-for-flow-s-smart-contracts/5110).

Expand All @@ -34,12 +34,12 @@ Cadence has historically provided the `unsafeRandom` function to return a pseudo
2. A transaction calling into your smart contract can potentially bias the sequence of random numbers which your smart contract internally generates. Currently, the block hash seeds `unsafeRandom`. Consensus nodes can *easily* bias the block hash and **influence the seed for `unsafeRandom`**.

<Callout type="warning">
⚠️ Note `unsafeRandom` will be deprecated in the next Cadence release. **Developers are advised to refrain from using `unsafeRandom.`**
⚠️ Note `unsafeRandom` is deprecated since the Cadence 1.0 release.
</Callout>

## Guidelines for Safe Usage

For usage of randomness where result abortion is not an issue, it is recommended to use the Cadence built-in function `revertibleRandom.` `revertibleRandom` returns a pseudo-random number and is also based on the Distributed Random Beacon.
For usage of randomness where result abortion is not an issue, it is recommended to use the Cadence built-in function `revertibleRandom.` `revertibleRandom` returns a pseudo-random number and is based on the Distributed Randomness Beacon.

```cadence
// Language reference:
Expand All @@ -54,9 +54,12 @@ access(all) fun main(): UInt64 {

It is notable that the random number generation process is unpredictable (for miners unpredictable at block construction time and for cadence logic unpredictable at time of call), verifiable, uniform, as well as safe from bias by miners and previously-running Cadence code.

Protocol improvements (documented in [FLIP 120](https://github.com/onflow/flips/blob/main/cadence/20230713-random-function.md))
expose the randomness beacon to the FVM and Cadence where it can be used to draw safe randoms without latency.

Although Cadence exposes safe randomness generated by the Flow protocol via `revertibleRandom`, there is an additional safety-relevant aspect that developers need to be mindful about.

The `revertibleRandom` function can be used safely in some applications where the transaction results are _not_ deliberately reverted after the random number is revealed (i.e. a contract distributing random NFTs to registered users or onchain lucky draw).
The `revertibleRandom` function can be used safely in some applications where the transaction results are _not_ deliberately reverted after the random number is revealed (i.e. a trusted contract distributing random NFTs to registered users or onchain lucky draw).
However, if applications require a non-trusted party (for instance app users) to submit a transaction calling a randomized (non-deterministic) contract, the developer must explicitly protect the stream of random numbers to not break the security guarantees:

<Callout type="warning">
Expand All @@ -81,37 +84,16 @@ Although the user (or the honest coin toss contract) cannot predict or bias the

## Commit-Reveal Scheme

The recommended way to mitigate the problems above is via a commit-reveal scheme. The scheme involves two steps: commit and reveal. During the commit phase, the user transaction commits to accepting the future output of a smart contract where the last remaining input is an unknown stream of random numbers. The smart contract stores this commitment on the blockchain. At the current level of optimization, the reveal phase can start as early as the next block, when the beacon's source of randomness becomes available. With a second transaction, the smart contract can be executed to explicitly generate the output now that the stream of random numbers can be seeded (plus suitable salt).
The recommended way to mitigate the problems above is via a commit-reveal scheme. The scheme involves two steps: commit and reveal. During the commit phase, the user transaction commits to accepting the future output of a smart contract where the last remaining input is an unknown random source. The smart contract stores this commitment on the blockchain. At the current level of optimization, the reveal phase can start as early as the next block, when the "future" beacon's source of randomness becomes available. The reveal phase can be executed at any block after that, now that the commitment to a past block is stored on-chain. With a second transaction, the smart contract can be executed to explicitly generate the random outputs.

There are ideas how to further optimize the developer experience in the future. For example, a transaction could delegate part of its gas to an independent transaction it spawns. Conceptually, also this future solution would be a commit-and-reveal scheme, just immediately happening within the same block. Until we eventually get to this next level, developers may need to implement their own commit-reveal. In Cadence, it is clean and short.

Protocol improvements (documented in [FLIP 120](https://github.com/onflow/flips/blob/main/cadence/20230713-random-function.md))
expose the random beacon to the FVM and Cadence where it can be used to seed pseudo-random number generators [PRNGs] for smart contracts.

While both are backed by Flow's Random Beacon it is important for developers to mindfully choose between `revertibleRandom` or
seeding their own PRNG utilizing the `RandomBeaconHistory` smart contract:

- Under the hood, the FVM also just instantiates a PRNG for each transaction that `revertibleRandom` draws from.
Though, with `revertibleRandom` a developer is calling the PRNG that is controlled by the transaction,
which also has the power to abort and revert if it doesn't like `revertibleRandom`'s outputs.
`revertibleRandom` is only suitable for smart contract functions that exclusively run within the trusted transactions.
- In contrast, using the `RandomBeaconHistory` means to use a deterministically-seeded PRNG.
The `RandomBeaconHistory` is key for effectively implementing a commit-and-reveal scheme.
During the commit phase, the user commits to proceed with a future source of randomness,
which is revealed after the commit transaction concluded.
For each block, the `RandomBeaconHistory` automatically stores the subsequently generated source of randomness.

Adding a safe pattern to reveal randomness without the possibility of conditional transaction reversion unlocks applications relying on randomness. By providing examples of commit-reveal implementations we hope to foster a more secure ecosystem of decentralized applications and encourage developers to build with best practices.

In simpler terms, the native secure randomness provided by the protocol can now be safely utilized within Cadence smart contracts
and is available to all developers on Flow and the FVM.

## FLIP 123
### FLIP 123

On Flow, we have absorbed all security complexity into the platform.

[FLIP 123: On-chain Random beacon history for commit-reveal schemes](https://github.com/onflow/flips/blob/main/protocol/20230728-commit-reveal.md#flip-123-on-chain-random-beacon-history-for-commit-reveal-schemes) was introduced to provide a safe pattern to use randomness in transactions so that it's not possible to revert unfavorable randomized transaction results.
We recommend this approach as a best-practice example for implementing a commit-reveal-recover scheme in Cadence. The `RandomBeaconHistory` contract provides a convenient archive, where for each past block height (starting Nov 2023) the respective “source of randomness” can be retrieved. The `RandomBeaconHistory` contract is automatically executed by the system at each block to store the next source of randomness value.
We recommend this approach as a best-practice example for implementing a commit-reveal scheme in Cadence. The `RandomBeaconHistory` contract provides a convenient archive, where for each past block height (starting Nov 2023) the respective “source of randomness” can be retrieved. The `RandomBeaconHistory` contract is automatically executed by the system at each block to store the next source of randomness value.

<Callout type="info">
💡 While the commit-and-reveal scheme mitigates post-selection of results by adversarial clients, Flow’s secure randomness additionally protects against any pre-selection vulnerabilities (like biasing attacks by byzantine miners).
Expand Down Expand Up @@ -184,6 +166,25 @@ access(all) fun revealCoinToss(receipt: @Receipt): @FungibleToken.Vault {
}
```

### Which random function should be used:

While both are backed by Flow's Randomness Beacon it is important for developers to mindfully choose between `revertibleRandom` or
seeding their own PRNG utilizing the `RandomBeaconHistory` smart contract:

- With `revertibleRandom` a developer is calling the transaction environment,
which has the power to abort and revert if it doesn't like `revertibleRandom`'s outputs.
`revertibleRandom` is only suitable for smart contract functions that exclusively run within the trusted transactions.
- In contrast, the `RandomBeaconHistory` contract is key for effectively implementing a commit-reveal scheme, where the transaction is non-trusted and may revert the random outputs.
During the commit phase, the user commits to proceed with a future source of randomness,
which is only revealed after the commit transaction concluded.
For each block, the `RandomBeaconHistory` automatically stores the generated source of randomness.
At the time of revealing the source, the committed source becomes a past-block source that can be queried through the history contract.

Adding a safe pattern to reveal randomness without the possibility of conditional transaction reversion unlocks applications relying on randomness. By providing examples of commit-reveal implementations we hope to foster a more secure ecosystem of decentralized applications and encourage developers to build with best practices.

In simpler terms, the native secure randomness provided by the protocol can now be safely utilized within Cadence smart contracts
and is available to all developers on Flow and the FVM.

## An Invitation to Build

Flow's onchain randomness opens new doors for innovation in web3, offering developers the tools to create fair and transparent decentralized applications. With this feature, new possibilities emerge—from enhancing gameplay in decentralized gaming to ensuring the integrity of smart contract-driven lotteries or introducing novel mechanisms in DeFi.
Expand All @@ -198,4 +199,4 @@ If you’d like to dive deeper into Flow’s onchain randomness, here’s a list
- These documents provide a more in-depth technical understanding of the updates and enhancements to the Flow blockchain.
- **[FLIP 120: Update unsafeRandom function](https://github.com/onflow/flips/blob/main/cadence/20230713-random-function.md#flip-120-update-unsaferandom-function)**
- **[FLIP 123: On-chain Random beacon history for commit-reveal schemes](https://github.com/onflow/flips/blob/main/protocol/20230728-commit-reveal.md#flip-123-on-chain-random-beacon-history-for-commit-reveal-schemes)**
- To see working Cadence code, explore the [coin toss example on GitHub](https://github.com/onflow/random-coin-toss/tree/update-prg-impl).
- To see working Cadence code, explore the [coin toss example on GitHub](https://github.com/onflow/random-coin-toss).
2 changes: 1 addition & 1 deletion docs/build/guides/nft.md
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ access(all) contract FooBar: NonFungibleToken {
/// Allows a caller to borrow a reference to a specific NFT
/// so that they can get the metadata views for the specific NFT
access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)
return &self.ownedNFTs[id]
}
// ...[rest of code]...
Expand Down
16 changes: 14 additions & 2 deletions docs/evm/cadence/direct-calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Once you have access to an `EVMAddress`, you can query various pieces of state i
- `nonce() UInt64` retrieves the nonce associated with the address.
- `code(): [UInt8]` fetches the code at the address; it returns the smart contract code if applicable, and is empty otherwise.

```
```cadence
import EVM from <ServiceAddress>
access(all)
Expand All @@ -39,11 +39,23 @@ fun main(bytes: [UInt8; 20]): EVM.Balance {
}
```

Alternatively, you can use the EVM contract's native deserialization to access the balance provided a hex string representing the address:

```cadence
import EVM from <ServiceAddress>
access(all)
fun main(addressHex: String): UFix64 {
let addr = EVM.addressFromString(addressHex)
return addr.balance().inFLOW()
}
```

### Sending Transactions to Flow EVM

To send transactions to Flow EVM, use the `run` function which executes RLP-encoded transactions. RLP (Recursive Length Prefix) encoding is used to efficiently encode data into a byte-array format, suitable for Ethereum-based environments. Here's an example of wrapping and sending a transaction:

```
```cadence
import EVM from <ServiceAddress>
transaction(rlpEncodedTransaction: [UInt8], coinbaseBytes: [UInt8; 20]) {
Expand Down
Loading

0 comments on commit 361abeb

Please sign in to comment.