From 03e349e2f7b4539f0283c1219d0a23d09f5c00cd Mon Sep 17 00:00:00 2001 From: Josh Hannan Date: Thu, 7 Mar 2024 17:07:36 -0600 Subject: [PATCH 1/2] update import tables to include preview and crescendo and update token standard docs --- .../build/core-contracts/02-fungible-token.md | 10 +- docs/build/core-contracts/03-flow-token.md | 10 +- .../core-contracts/04-service-account.md | 10 +- docs/build/core-contracts/05-flow-fees.md | 20 +- .../06-staking-contract-reference.md | 10 +- .../07-epoch-contract-reference.md | 10 +- .../core-contracts/08-non-fungible-token.md | 10 +- docs/build/core-contracts/09-nft-metadata.md | 9 +- .../build/core-contracts/10-nft-storefront.md | 5 + .../core-contracts/11-staking-collection.md | 9 +- .../build/core-contracts/12-hybrid-custody.md | 8 +- docs/build/core-contracts/flow-ft/index.md | 271 ++++++------- docs/build/core-contracts/flow-nft/index.md | 367 +++--------------- 13 files changed, 259 insertions(+), 490 deletions(-) diff --git a/docs/build/core-contracts/02-fungible-token.md b/docs/build/core-contracts/02-fungible-token.md index aacdc8e1d3..d5b978dc04 100644 --- a/docs/build/core-contracts/02-fungible-token.md +++ b/docs/build/core-contracts/02-fungible-token.md @@ -8,9 +8,9 @@ The `FungibleToken` contract implements the Fungible Token Standard. It is the s Source: [FungibleToken.cdc](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0xee82856bf20e2aa6` | -| Testnet | `0x9a0766d93b6608b7` | -| Mainnet | `0xf233dcee88fe0abe` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xee82856bf20e2aa6` | +| Testnet/Previewnet/Crescendo | `0x9a0766d93b6608b7` | +| Mainnet | `0xf233dcee88fe0abe` | diff --git a/docs/build/core-contracts/03-flow-token.md b/docs/build/core-contracts/03-flow-token.md index 87ae256358..3fc187e500 100644 --- a/docs/build/core-contracts/03-flow-token.md +++ b/docs/build/core-contracts/03-flow-token.md @@ -7,11 +7,11 @@ The `FlowToken` contract defines the FLOW network token. Source: [FlowToken.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowToken.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0x0ae53cb6e3f42a79` | -| Testnet | `0x7e60df042a9c0868` | -| Mainnet | `0x1654653399040a61` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0x0ae53cb6e3f42a79` | +| Testnet/Previewnet/Crescendo | `0x7e60df042a9c0868` | +| Mainnet | `0x1654653399040a61` | # Transactions diff --git a/docs/build/core-contracts/04-service-account.md b/docs/build/core-contracts/04-service-account.md index 16ca6e5644..3537506ee2 100644 --- a/docs/build/core-contracts/04-service-account.md +++ b/docs/build/core-contracts/04-service-account.md @@ -24,8 +24,8 @@ to execute/handle blocks at a given block height. Source: [NodeVersionBeacon.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/NodeVersionBeacon.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet | `0x8c5303eaa26202d6` | -| Mainnet | `0xe467b9dd11fa00df` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x8c5303eaa26202d6` | +| Mainnet | `0xe467b9dd11fa00df` | diff --git a/docs/build/core-contracts/05-flow-fees.md b/docs/build/core-contracts/05-flow-fees.md index 27492dbf90..c585ad8ac0 100644 --- a/docs/build/core-contracts/05-flow-fees.md +++ b/docs/build/core-contracts/05-flow-fees.md @@ -7,19 +7,19 @@ The `FlowFees` contract is where all the collected flow fees are gathered. Source: [FlowFees.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0xe5a8b7f23e8b548f` | -| Testnet | `0x912d5440f7e3769e` | -| Mainnet | `0xf919ee77447b7497` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xe5a8b7f23e8b548f` | +| Testnet/Previewnet/Crescendo | `0x912d5440f7e3769e` | +| Mainnet | `0xf919ee77447b7497` | The `FlowStorageFees` contract defines the parameters and utility methods for storage fees. Source: [FlowStorageFees.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStorageFees.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet | `0x8c5303eaa26202d6` | -| Mainnet | `0xe467b9dd11fa00df` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x8c5303eaa26202d6` | +| Mainnet | `0xe467b9dd11fa00df` | diff --git a/docs/build/core-contracts/06-staking-contract-reference.md b/docs/build/core-contracts/06-staking-contract-reference.md index 269983f70a..ce585e30ca 100644 --- a/docs/build/core-contracts/06-staking-contract-reference.md +++ b/docs/build/core-contracts/06-staking-contract-reference.md @@ -9,11 +9,11 @@ The `FlowIDTableStaking` contract is the central table that manages staked nodes Source: [FlowIDTableStaking.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowIDTableStaking.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet | `0x9eca2b38b18b5dfe` | -| Mainnet | `0x8624b52f9ddcd04a` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator/Canary | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x9eca2b38b18b5dfe` | +| Mainnet | `0x8624b52f9ddcd04a` | # Transactions diff --git a/docs/build/core-contracts/07-epoch-contract-reference.md b/docs/build/core-contracts/07-epoch-contract-reference.md index 6e3cb296aa..ccab6a9cab 100644 --- a/docs/build/core-contracts/07-epoch-contract-reference.md +++ b/docs/build/core-contracts/07-epoch-contract-reference.md @@ -15,11 +15,11 @@ Sources: - [FlowClusterQC.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowClusterQC.cdc) - [FlowDKG.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowDKG.cdc) -| Network | Contract Address | -|-----------------|----------------------| -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet | `0x9eca2b38b18b5dfe` | -| Mainnet | `0x8624b52f9ddcd04a` | +| Network | Contract Address | +|------------------------------|----------------------| +| Emulator | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x9eca2b38b18b5dfe` | +| Mainnet | `0x8624b52f9ddcd04a` | # Transactions diff --git a/docs/build/core-contracts/08-non-fungible-token.md b/docs/build/core-contracts/08-non-fungible-token.md index 5b7beb29b1..010e232cf9 100644 --- a/docs/build/core-contracts/08-non-fungible-token.md +++ b/docs/build/core-contracts/08-non-fungible-token.md @@ -8,8 +8,8 @@ All NFT contracts are encouraged to import and implement this standard. Source: [NonFungibleToken.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc) -| Network | Contract Address | -| --------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet | `0x631e88ae7f1d7c20` | -| Mainnet | `0x1d7e57aa55817448` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x631e88ae7f1d7c20` | +| Mainnet | `0x1d7e57aa55817448` | diff --git a/docs/build/core-contracts/09-nft-metadata.md b/docs/build/core-contracts/09-nft-metadata.md index 1c34102875..444dc5aaf2 100644 --- a/docs/build/core-contracts/09-nft-metadata.md +++ b/docs/build/core-contracts/09-nft-metadata.md @@ -10,10 +10,11 @@ It is deployed at the same address as the `NonFungibleToken` contract interface. Source: [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc) -| Network | Contract Address | -| ---------- | -------------------- | -| Testnet | `0x631e88ae7f1d7c20` | -| Mainnet | `0x1d7e57aa55817448` | +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x631e88ae7f1d7c20` | +| Mainnet | `0x1d7e57aa55817448` | There exists a tool, [Flow NFT Catalog](https://flow-nft-catalog.com), which enables dapp developers the ability to unlock interoperability of your NFT collection across the Flow ecosystem. This will help make your NFT collection’s metadata more discoverable and interoperable. diff --git a/docs/build/core-contracts/10-nft-storefront.md b/docs/build/core-contracts/10-nft-storefront.md index 6c70f1b4e7..55e17aee12 100644 --- a/docs/build/core-contracts/10-nft-storefront.md +++ b/docs/build/core-contracts/10-nft-storefront.md @@ -4,6 +4,11 @@ title: NFT Storefront Smart Contract ## Primer +|Name|Testnet/Previewnet/Crescendo|Mainnet| +|----|----------------------------|-------| +|[NFTStorefront](contracts/NFTStorefront.cdc)|[0x94b06cfca1d8a476](https://testnet.flowdiver.io/contract/A.94b06cfca1d8a476.NFTStorefront)|[0x4eb8a10cb9f87357](https://www.flowdiver.io/contract/A.4eb8a10cb9f87357.NFTStorefront)| +|[NFTStorefrontV2 (recommended)](contracts/NFTStorefrontV2.cdc)|[0x2d55b98eb200daef](https://testnet.flowdiver.io/contract/A.2d55b98eb200daef.NFTStorefrontV2)|[0x4eb8a10cb9f87357](https://www.flowdiver.io/contract/A.4eb8a10cb9f87357.NFTStorefrontV2)| + The `NFTStorefrontV2` contract lets you create a *non-custodial Resource (NFT) marketplace* on the FLOW blockchain. `NFTStorefrontV2` makes it simple for Sellers to list NFTs in dApp specific marketplaces. DApp developers leverage the APIs provided by the contract to manage listings being offered for sale and to transact NFT trades. diff --git a/docs/build/core-contracts/11-staking-collection.md b/docs/build/core-contracts/11-staking-collection.md index 1e4e4a368a..9d0862c2b2 100644 --- a/docs/build/core-contracts/11-staking-collection.md +++ b/docs/build/core-contracts/11-staking-collection.md @@ -20,10 +20,11 @@ See the [Staking Collection Docs](../../networks/staking/14-staking-collection.m Source: [FlowStakingCollection.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStakingCollection.cdc) -| Network | Contract Address | -|------------|----------------------| -| Testnet | `0x95e019a17d0e23d7` | -| Mainnet | `0x8d0e87b65159ae63` | +| Network | Contract Address | +|------------------------------|----------------------| +| Emulator | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x95e019a17d0e23d7` | +| Mainnet | `0x8d0e87b65159ae63` | ## Transactions diff --git a/docs/build/core-contracts/12-hybrid-custody.md b/docs/build/core-contracts/12-hybrid-custody.md index 77bbd419ff..8be16c5e6a 100644 --- a/docs/build/core-contracts/12-hybrid-custody.md +++ b/docs/build/core-contracts/12-hybrid-custody.md @@ -9,7 +9,7 @@ The Account Linking contracts manage ChildAccounts to permit hybrid custody in s You can see the docs for account linking [here](https://developers.flow.com/build/advanced-concepts/account-linking) -| Network | Contract Address | -|------------|----------------------| -| Testnet | [`0x294e44e1ec6993c6`](https://contractbrowser.com/account/0x294e44e1ec6993c6) | -| Mainnet | [`0xd8a7e05a7ac670c0`](https://contractbrowser.com/account/0xd8a7e05a7ac670c0) | \ No newline at end of file +| Network | Contract Address | +|------------------------------|----------------------| +| Testnet/Previewnet/Crescendo | [`0x294e44e1ec6993c6`](https://contractbrowser.com/account/0x294e44e1ec6993c6) | +| Mainnet | [`0xd8a7e05a7ac670c0`](https://contractbrowser.com/account/0xd8a7e05a7ac670c0) | \ No newline at end of file diff --git a/docs/build/core-contracts/flow-ft/index.md b/docs/build/core-contracts/flow-ft/index.md index c6155885a2..ed629a1e2a 100644 --- a/docs/build/core-contracts/flow-ft/index.md +++ b/docs/build/core-contracts/flow-ft/index.md @@ -3,129 +3,133 @@ title: Fungible Token (FT) Standard sidebar_position: 2 --- -This is a description of the Flow standard for fungible token contracts. It is meant to contain the minimum requirements to implement a safe, secure, easy to understand, and easy to use fungible token contract. It also includes an example implementation to show how a concrete smart contract would actually implement the interface. +This documentation comes from the README of +[the `flow-ft` github repository](https://github.com/onflow/flow-ft/blob/v2-standard/README.md). Please visit that repo to see more detailed documentation and examples. -## What is Flow? +# Fungible Token Standard -Flow is a new blockchain for open worlds. Read more about it [here](https://flow.com/). +This is a description of the Flow standard for fungible token contracts. +It is meant to contain the minimum requirements to implement a safe, secure, easy to understand, +and easy to use fungible token contract. +It also includes an example implementation to show how a +concrete smart contract would actually implement the interface. -## What is Cadence? +The version of the contracts in the `master` branch is the +Cadence 1.0 version of the contracts and is not the same +as the ones that are currently deployed to testnet and mainnet. +See the `cadence-0.42` branch for the currently deployed versions. -Cadence is a new Resource-oriented programming language -for developing smart contracts for the Flow Blockchain. -Read more about it [here](../../../build/smart-contracts/cadence.md) and see its implementation [here](https://github.com/onflow/cadence) +## Import Addresses -We recommend that anyone who is reading this should have already -completed the [Cadence Tutorials](https://cadence-lang.org/docs/tutorial/first-steps) -so they can build a basic understanding of the programming language. +The `FungibleToken`, `FungibleTokenMetadataViews`, and `FungibleTokenSwitchboard` contracts are already deployed +on various networks. You can import them in your contracts from these addresses. +There is no need to deploy them yourself. -Resource-oriented programming, and by extension Cadence, -is the perfect programming environment for currencies, because users are able -to store their tokens directly in their accounts and transact -peer-to-peer. Please see the [blog post about resources](https://medium.com/dapperlabs/resource-oriented-programming-bee4d69c8f8e) -to understand why they are perfect for digital assets. +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator | `0xee82856bf20e2aa6` | +| Testnet/Previewnet/Crescendo | `0x9a0766d93b6608b7` | +| Sandboxnet | `0xe20612a0776ca4bf` | +| Mainnet | `0xf233dcee88fe0abe` | -## Feedback - -Flow and Cadence are both still in development, so this standard will still -be going through a lot of changes as the protocol and language evolves, -and as we receive feedback from the community about the standard. - -We'd love to hear from anyone who has feedback. -Main feedback we are looking for is: - -The feedback we are looking for is: - -- Are there any features that are missing from the standard? -- Are the features that we have included defined in the best way possible? -- Are there any pre and post conditions for functions that are missing? -- Are the pre and post conditions defined well enough? Error messages? -- Are there any other actions that need an event defined for them? -- Are the current event definitions clear enough and do they provide enough information for apps and other actors a clear look into what is happening? -- Are the variable, function, and parameter names descriptive enough? -- Are there any openings for bugs or vulnerabilities that we are not noticing? -- Is the documentation/comments clear and concise and organized in a coherent manner? +The `Burner` contract is also deployed to these addresses, but should not be used until after the Cadence 1.0 network upgrade. ## Basics of the Standard: -The code for the standard is in `contracts/FungibleToken.cdc`. An example implementation of the standard that simulates what a simple token would be like is in `contracts/ExampleToken.cdc`. +The code for the standard is in [`contracts/FungibleToken.cdc`](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc). An example implementation of the standard that simulates what a simple token would be like is in [`contracts/ExampleToken.cdc`](https://github.com/onflow/flow-ft/blob/master/contracts/ExampleToken.cdc). -The exact smart contract that is used for the official Flow Network Token is in `contracts/FlowToken.cdc` +The exact smart contract that is used for the official Flow Network Token (`FlowToken`) is in [the `flow-core-contracts` repository](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowToken.cdc). Example transactions that users could use to interact with fungible tokens are located in the `transactions/` directory. These templates are mostly generic and can be used with any fungible token implementation by providing the correct addresses, names, and values. -The standard consists of a contract interface called `FungibleToken` that requires implementing contracts to define a `Vault` resource that represents the tokens that an account owns. Each account that owns tokens will have a `Vault` stored in its account storage. Users call functions on each other's `Vault`s to send and receive tokens. +The standard consists of a contract interface called `FungibleToken` that defines important +functionality for token implementations. Contracts are expected to define a resource +that implement the `FungibleToken.Vault` resource interface. +A `Vault` represents the tokens that an account owns. Each account that owns tokens +will have a `Vault` stored in its account storage. +Users call functions on each other's `Vault`s to send and receive tokens. -Right now we are using unsigned 64-bit fixed point numbers `UFix64` as the type to represent token balance information. This type has 8 decimal places and cannot represent negative numbers. +The standard uses unsigned 64-bit fixed point numbers `UFix64` as the type to represent token balance information. This type has 8 decimal places and cannot represent negative numbers. ## Core Features (All contained in the main FungibleToken interface) -1- Getting metadata for the token smart contract via the fields of the contract: - -- `pub var totalSupply: UFix64` - - The only required field of the contract. It would be incremented when new tokens are minted and decremented when they are destroyed. -- Event that gets emitted when the contract is initialized - - `pub event TokensInitialized(initialSupply: UFix64)` - -2- Retrieving the token fields of a `Vault` in an account that owns tokens. - -- Balance interface - - `pub var balance: UFix64` - - The only required field of the `Vault` type - -3- Withdrawing a specific amount of tokens *amount* using the *withdraw* function of the owner's `Vault` - -- Provider interface - - `pub fun withdraw(amount: UFix64): @FungibleToken.Vault` - - Conditions - - the returned Vault's balance must equal the amount withdrawn - - The amount withdrawn must be less than or equal to the balance - - The resulting balance must equal the initial balance - amount - - Users can give other accounts a reference to their `Vault` cast as a `Provider` to allow them to withdraw and send tokens for them. A contract can define any custom logic to govern the amount of tokens that can be withdrawn at a time with a `Provider`. This can mimic the `approve`, `transferFrom` functionality of ERC20. -- withdraw event - - Indicates how much was withdrawn and from what account the `Vault` is stored in. +### `Balance` Interface + +Specifies that the implementing type must have a `UFix64` `balance` field. + - `access(all) var balance: UFix64` + +### `Provider` Interface +Defines a [`withdraw ` function](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleToken.cdc#L95) for withdrawing a specific amount of tokens *amount*. + - `access(all) fun withdraw(amount: UFix64): @{FungibleToken.Vault}` + - Conditions + - the returned Vault's balance must equal the amount withdrawn + - The amount withdrawn must be less than or equal to the balance + - The resulting balance must equal the initial balance - amount + - Users can give other accounts a reference to their `Vault` cast as a `Provider` + to allow them to withdraw and send tokens for them. + A contract can define any custom logic to govern the amount of tokens + that can be withdrawn at a time with a `Provider`. + This can mimic the `approve`, `transferFrom` functionality of ERC20. +- [`FungibleToken.Withdrawn` event](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleToken.cdc#L50) + - Event that is emitted automatically to indicate how much was withdrawn + and from what account the `Vault` is stored in. If the `Vault` is not in account storage when the event is emitted, `from` will be `nil`. - - `pub event TokensWithdrawn(amount: UFix64, from: Address?)` - -4 - Depositing a specific amount of tokens *from* using the *deposit* function of the recipient's `Vault` - -- `Receiver` interface - - `pub fun deposit(from: @FungibleToken.Vault)` - - Conditions - - `from` balance must be non-zero - - The resulting balance must be equal to the initial balance + the balance of `from` -- deposit event - - Indicates how much was deposited and to what account the `Vault` is stored in. - If the `Vault` is not in account storage when the event is emitted, - `to` will be `nil`. - - `pub event TokensDeposited(amount: UFix64, to: Address?)` -- Users could create custom `Receiver`s to trigger special code when transfers to them happen, like forwarding the tokens - to another account, splitting them up, and much more. - -- It is important that if you are making your own implementation of the fungible token interface that + - Contracts do not have to emit their own events, + the standard events will automatically be emitted. + +Defines [an `isAvailableToWithdraw()` function](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleToken.cdc#L95) +to ask a `Provider` if the specified number of tokens can be withdrawn from the implementing type. + +### `Receiver` Interface +Defines functionality to depositing fungible tokens into a resource object. +- [`deposit()` function](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleToken.cdc#L119): + - `access(all) fun deposit(from: @{FungibleToken.Vault})` + - Conditions + - `from` balance must be non-zero + - The resulting balance must be equal to the initial balance + the balance of `from` + - It is important that if you are making your own implementation of the fungible token interface that you cast the input to `deposit` as the type of your token. `let vault <- from as! @ExampleToken.Vault` The interface specifies the argument as `@FungibleToken.Vault`, any resource that satisfies this can be sent to the deposit function. The interface checks that the concrete types match, but you'll still need to cast the `Vault` before storing it. - -5 - Creating an empty Vault resource - -- `pub fun createEmptyVault(): @FungibleToken.Vault` +- deposit event + - [`FungibleToken.Deposited` event](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleToken.cdc#L53) from the standard + that indicates how much was deposited and to what account the `Vault` is stored in. + - If the `Vault` is not in account storage when the event is emitted, + `to` will be `nil`. + - This event is emitted automatically on any deposit, so projects do not need + to define and emit their own events. + +Defines Functionality for Getting Supported Vault Types +- Some resource types can accept multiple different vault types in their deposit functions, + so the `getSupportedVaultTypes()` and `isSupportedVaultType()` functions allow callers + to query a resource that implements `Receiver` to see if the `Receiver` accepts + their desired `Vault` type in its deposit function. + +Users could create custom `Receiver`s to trigger special code when transfers to them happen, +like forwarding the tokens to another account, splitting them up, and much more. + +### `Vault` Interface +[Interface](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleToken.cdc#L134) that inherits from `Provider`, `Receiver`, `Balance`, `ViewResolver.Resolver`, +and `Burner.Burnable` and provides additional pre and post conditions. + +The `ViewResolver.Resolver` interface defines functionality for retrieving metadata +about a particular resource object. Fungible Token metadata is described below. + +See the comments in [the `Burner` contract](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/Burner.cdc) for context about it. +Basically, it defines functionality for tokens to have custom logic when those tokens +are destroyed. + +### Creating an empty Vault resource +Defines functionality in the contract to create a new empty vault of +of the contract's defined type. +- `access(all) fun createEmptyVault(vaultType: Type): @{FungibleToken.Vault}` - Defined in the contract - To create an empty `Vault`, the caller calls the function in the contract and stores the Vault in their storage. +- To create an empty `Vault`, the caller calls the function and provides the Vault Type + that they want. They get a vault back and can store it in their storage. - Conditions: - the balance of the returned Vault must be 0 -6 - Destroying a Vault - -If a `Vault` is explicitly destroyed using Cadence's `destroy` keyword, the balance of the destroyed vault must be subracted from the total supply. - -7 - Standard for Token Metadata - -- not sure what this should be yet -- Could be a dictionary, could be an IPFS hash, could be json, etc. -- need suggestions! - ## Comparison to Similar Standards in Ethereum @@ -138,58 +142,61 @@ This spec covers much of the same ground that a spec like ERC-20 covers, but wit - Transfers can trigger actions because users can define custom `Receivers` to execute certain code when a token is sent. - Cadence integer types protect against overflow and underflow, so a `SafeMath`-equivalent library is not needed. -### Metadata - -A standard for token metadata is still an unsolved problem in the general blockchain world and we are still thinking about ways to solve it in Cadence. We hope to be able to store all metadata on-chain and are open to any ideas or feedback on how this could be implemented. +## FT Metadata +FT Metadata is represented in a flexible and modular way using both +the [standard proposed in FLIP-0636](https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md) +and the [standard proposed in FLIP-1087](https://github.com/onflow/flips/blob/main/application/20220811-fungible-tokens-metadata.md). -## Bonus Features +[A guide for NFT metadata](https://developers.flow.com/build/advanced-concepts/metadata-views) +is provided on the docs site. Many of the concepts described there also apply +to fungible tokens, so it is useful to read for any Cadence developer. -**Minting and Burning are not included in the standard but are included in the FlowToken example contract to illustrate what minting and burning might look like for a token in Flow.** +When writing an FT contract interface, your contract will implement +the `FungibleToken` contract interface which already inherits +from [the `ViewResolver` contract interface](https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc), +so you will be required to implement the metadata functions. +Additionally, your `Vault` will also implement the `ViewResolver.Resolver` by default, +which allows your `Vault` resource to implement one or more metadata types called views. -8 - Minting or Burning a specific amount of tokens using a specific minter resource that an owner can control +Views do not specify or require how to store your metadata, they only specify +the format to query and return them, so projects can still be flexible with how they store their data. -- `MintandBurn` Resource - - function to mintTokens - - tokens minted event - - Each minter has a set amount of tokens that they are allowed to mint. This cannot be changed and a new minter needs to be created to add more allowance. - - function to burnTokens - - tokens Burnt event - - Each time tokens are minted or burnt, that value is added or subtracted to or from the total supply. +### Fungible token Metadata Views +The [FungibleTokenMetadataViews contract](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleTokenMetadataViews.cdc) defines four new views that can used to communicate any fungible token information: -**The following features could each be defined as a separate interface. It would be good to make standards for these, but not necessary to include in the main standard interface and are not currently defined in this example.** +1. `FTView`: A view that wraps the two other views that actually contain the data. +2. `FTDisplay`: The view that contains all the information that will be needed by other dApps to display the fungible token: name, symbol, description, external URL, logos and links to social media. +3. `FTVaultData`: The view that can be used by other dApps to interact programmatically with the fungible token, providing the information about the public and private paths used by default by the token, the public and private linked types for exposing capabilities and the function for creating new empty vaults. You can use this view to [setup an account using the vault stored in other account without the need of importing the actual token contract.](https://github.com/onflow/flow-ft/blob/v2-standard/transactions/setup_account_from_vault_reference.cdc) +4. `TotalSupply`: Specifies the total supply of the given token. -9 - Withdrawing a specific amount of tokens from someone else's `Vault` by using their `provider` reference. +### How to implement metadata -- approved withdraw event -- Providing a resource that only approves an account to send a specific amount per transaction or per day/month/etc. -- Returning the amount of tokens that an account can send for another account. -- Reading the balance of the account that you have permission to send tokens for -- Owner is able to increase and decrease the approval at will, or revoke it completely - - This is much harder than anticipated +The [Example Token contract](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/ExampleToken.cdc) shows how to implement metadata views for fungible tokens. -11 - Pausing Token transfers (maybe a way to prevent the contract from being imported) +### How to read metadata -12 - Cloning the token to create a new token with the same distribution +In the `flow-ft` github repository you can find examples on how to read metadata, accessing the `ExampleToken` display (name, symbol, logos, etc.) and its vault data (paths, linked types and the method to create a new vault). -13 - Restricted ownership (For accredited investors and such) -- allowlisting -- denylisting +Latter using that reference you can call methods defined in the [Fungible Token Metadata Views contract](https://github.com/onflow/flow-ft/blob/v2-standard/contracts/FungibleTokenMetadataViews.cdc) that will return you the structure containing the desired information. # How to use the Fungible Token contract To use the Flow Token contract as is, you need to follow these steps: -1. If you are using the Playground, you need to deploy the `FungibleToken` definition to account 1 yourself and import it in `ExampleToken`. It is a predeployed interface in the emulator, testnet, and mainnet and you can import definition from those accounts: +1. If you are using any network or the playground, there is no need to deploy +the `FungibleToken` definition to accounts yourself. +It is a pre-deployed interface in the emulator, testnet, mainnet, +and playground and you can import definition from those accounts: - `0xee82856bf20e2aa6` on emulator - `0x9a0766d93b6608b7` on testnet - `0xf233dcee88fe0abe` on mainnet -2. Deploy the `ExampleToken` definition +2. Deploy the `ExampleToken` definition, making sure to import the `FungibleToken` interface. 3. You can use the `get_balance.cdc` or `get_supply.cdc` scripts to read the balance of a user's `Vault` or the total supply of all tokens, respectively. -4. Use the `setupAccount.cdc` on any account to set up the account to be able to - use `FlowTokens`. +4. Use the `setup_account.cdc` on any account to set up the account to be able to + use `ExampleToken`. 5. Use the `transfer_tokens.cdc` transaction file to send tokens from one user with a `Vault` in their account storage to another user with a `Vault` in their account storage. 6. Use the `mint_tokens.cdc` transaction with the admin account to mint new tokens. @@ -197,13 +204,15 @@ To use the Flow Token contract as is, you need to follow these steps: 8. Use the `create_minter.cdc` transaction to create a new MintandBurn resource and store it in a new Admin's account. +# Fungible Token Switchboard -# Running Automated Tests +`FungibleTokenSwitchboard.cdc`, allows users to receive payments +in different fungible tokens using a single `&{FungibleToken.Receiver}` +placed in a standard receiver path `/public/GenericFTReceiver`. +The switchboard routes received tokens to the correct vault in the owner's account. -You can find automated tests in the `lib/go/test/token_test.go` file. It uses the transaction templates that are contained in the `lib/go/templates/transaction_templates.go` file. Currently, these rely on a dependency from a private dapper labs repository to run, so external users will not be able to run them. We are working on making all of this public so anyone can run tests, but haven't completed this work yet. +You can see more documentation about the switchboard in +[the flow-ft github repo](https://github.com/onflow/flow-ft/tree/v2-standard?tab=readme-ov-file#fungible-token-switchboard). -## License -The works in these folders are under the [Unlicense](https://github.com/onflow/flow-ft/blob/master/LICENSE): -- [/contracts](https://github.com/onflow/flow-ft/blob/master/contracts/) diff --git a/docs/build/core-contracts/flow-nft/index.md b/docs/build/core-contracts/flow-nft/index.md index d218892ba1..06b43291b7 100644 --- a/docs/build/core-contracts/flow-nft/index.md +++ b/docs/build/core-contracts/flow-nft/index.md @@ -1,131 +1,111 @@ --- sidebar_position: 2 --- -# Flow Non-Fungible Token (NFT) Standard + +This documentation comes from the README of +[the `flow-nft` github repository](https://github.com/onflow/flow-nft/blob/standard-v2/README.md). Please visit that repo to see more detailed documentation and examples. + +# Flow Non-Fungible Token Standard This standard defines the minimum functionality required to implement a safe, secure, and easy-to-use non-fungible token -contract on the [Flow blockchain](https://www.onflow.org/). +contract on the [Flow blockchain](https://flow.com/) -## What is Cadence? +The version of the contracts in the `master` branch is the +Cadence 1.0 version of the contracts and is not the same +as the ones that are currently deployed to testnet and mainnet. +See the `cadence-0.42` branch for the currently deployed versions. -[Cadence is the resource-oriented programming language](../../../build/smart-contracts/cadence.md) -for developing smart contracts on Flow. +## Import Addresses -Before reading this standard, -we recommend completing the [Cadence tutorials](https://cadence-lang.org/docs/tutorial/first-steps) -to build a basic understanding of the programming language. +The `NonFungibleToken`, `ViewResolver`, and `MetadataViews` contracts are already deployed +on various networks. You can import them in your contracts from these addresses. +There is no need to deploy them yourself. -Resource-oriented programming, and by extension Cadence, -provides an ideal programming model for non-fungible tokens (NFTs). -Users are able to store their NFT objects directly in their accounts and transact -peer-to-peer. Learn more in this [blog post about resources](https://medium.com/dapperlabs/resource-oriented-programming-bee4d69c8f8e). +Note: With the emulator, you must use the -contracts flag to deploy these contracts. -## Core features +| Network | Contract Address | +| ---------------------------- | -------------------- | +| Emulator/Canary | `0xf8d6e0586b0a20c7` | +| Testnet/Previewnet/Crescendo | `0x631e88ae7f1d7c20` | +| Mainnet | `0x1d7e57aa55817448` | -The `NonFungibleToken` contract defines the following set of functionality -that must be included in each implementation. +## Core Types -Contracts that implement the `NonFungibleToken` interface are required to implement two resource interfaces: +Contracts that implement the `NonFungibleToken` interface are expected +to utilize two resource interfaces: -- `NFT` - A resource that describes the structure of a single NFT. -- `Collection` - A resource that can hold multiple NFTs of the same type. +- `NFT` - A resource interface that describes the structure of a single NFT. +- `Collection` - A resource interface that describes an object + that can hold multiple NFTs of the same type and defines ways + to deposit, withdraw, and query information about the stored NFTs. Users typically store one collection per NFT type, saved at a well-known location in their account storage. For example, all NBA Top Shot Moments owned by a single user are held in a [`TopShot.Collection`](https://github.com/dapperlabs/nba-smart-contracts/blob/master/contracts/TopShot.cdc#L605) stored in their account at the path `/storage/MomentCollection`. -### Create a new NFT collection - -Create a new collection using the `createEmptyCollection` function. +## Core Features -This function MUST return an empty collection that contains no NFTs. +The `NonFungibleToken` contract defines the following set of functionality +that should be included in each implementation: -Users typically save new collections to a well-known location in their account -and link the `NonFungibleToken.CollectionPublic` interface as a public capability. +### Create a new NFT collection -```swift -let collection <- ExampleNFT.createEmptyCollection() +Create a new collection using the `Token.createEmptyCollection(nftType: Type)` function. -account.save(<-collection, to: /storage/ExampleNFTCollection) +This function MUST return an empty collection that contains no NFTs. -// create a public capability for the collection -account.link<&{NonFungibleToken.CollectionPublic}>( - /public/ExampleNFTCollection, - target: /storage/ExampleNFTCollection -) -``` +Users typically save new collections to a contract-defined location in their account +and public a capability to their collection. ### Withdraw an NFT -Withdraw an `NFT` from a `Collection` using the [`withdraw`](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc#L36-L42) function. -This function emits the [`Withdraw`](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc#L12) event. - -```swift -let collectionRef = account.borrow<&ExampleNFT.Collection>(from: /storage/ExampleNFTCollection) - ?? panic("Could not borrow a reference to the owner's collection") - -// withdraw the NFT from the owner's collection -let nft <- collectionRef.withdraw(withdrawID: 42) -``` +Withdraw an `NFT` from a `Collection` using the [`withdraw()`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/ExampleNFT.cdc#L160) function. +This function emits the [`NonFungibleToken.Withdrawn`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/NonFungibleToken.cdc#L78) event automatically. ### Deposit an NFT -Deposit an `NFT` into a `Collection` using the [`deposit`](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc#L46-L57) function. -This function emits the [`Deposit`](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc#L13) event. - -This function is available on the `NonFungibleToken.CollectionPublic` interface, -which accounts publish as public capability. -This capability allows anybody to deposit an NFT into a collection -without accessing the entire collection. - -```swift -let nft: ExampleNFT.NFT - -// ... - -let collection = account.getCapability(/public/ExampleNFTCollection) - .borrow<&{NonFungibleToken.CollectionPublic}>() - ?? panic("Could not borrow a reference to the receiver's collection") - -collection.deposit(token: <-nft) -``` +Deposit an `NFT` into a `Collection` using the [`deposit()`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/ExampleNFT.cdc#L169-L176) function. +This function emits the [`NonFungibleToken.Deposited`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/NonFungibleToken.cdc#L86) event automatically. #### ⚠️ Important In order to comply with the deposit function in the interface, -an implementation MUST take a `@NonFungibleToken.NFT` resource as an argument. -This means that anyone can send a resource object that conforms to `@NonFungibleToken.NFT` to a deposit function. +an implementation MUST take a `@{NonFungibleToken.NFT}` resource as an argument. +This means that anyone can send a resource object that conforms to `{NonFungibleToken.NFT}` to a deposit function. In an implementation, you MUST cast the `token` as your specific token type before depositing it or you will deposit another token type into your collection. For example: -```swift +```cadence +/// `ExampleNFT` much be changed to the name of your contract let token <- token as! @ExampleNFT.NFT ``` ### List NFTs in an account -Return a list of NFTs in a `Collection` using the [`getIDs`](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc#L59-L62) function. +Return a list of NFTs in a `Collection` using the [`getIDs`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/ExampleNFT.cdc#L179) function. -This function is available on the `NonFungibleToken.CollectionPublic` interface, -which accounts publish as public capability. +### Return the NFT type that a collection can accept in a deposit -```swift -let collection = account.getCapability(/public/ExampleNFTCollection) - .borrow<&{NonFungibleToken.CollectionPublic}>() - ?? panic("Could not borrow a reference to the receiver's collection") +Return types of NFTs that a `Collection` can accept in a deposit +using the [`getSupportedNFTTypes`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/ExampleNFT.cdc#L143-L157) functions. -let ids = collection.getIDs() -``` +### Get Available SubNFTs, if any + +Some NFTs can own other NFTs, the standard provides a [function](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/NonFungibleToken.cdc#L111-L131) that +projects can optionally implement to return information the owned NFTs. ## NFT Metadata +The primary documentation for metadata views is on [the Flow developer portal](https://developers.flow.com/build/advanced-concepts/metadata-views). +Please refer to that for the most thorough exploration of the views with examples. + NFT metadata is represented in a flexible and modular way using the [standard proposed in FLIP-0636](https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md). When writing an NFT contract, -you should implement the [`MetadataViews.Resolver`](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L3-L6)interface, -which allows your NFT to implement one or more metadata types called views. +you should implement the [`MetadataViews.Resolver`](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/MetadataViews.cdc#L3-L6) interface, +which allows your NFT to utilize one or more metadata types called views. Each view represents a different type of metadata, such as an on-chain creator biography or an off-chain video clip. @@ -137,157 +117,12 @@ the format to query and return them, so projects can still be flexible with how This example shows how to read basic information about an NFT including the name, description, image and owner. -**Source: [get_nft_metadata.cdc](https://github.com/onflow/flow-nft/blob/master/scripts/get_nft_metadata.cdc)** - -```swift -import ExampleNFT from "..." -import MetadataViews from "..." - -// ... - -// Get the regular public capability -let collection = account.getCapability(ExampleNFT.CollectionPublicPath) - .borrow<&{ExampleNFT.ExampleNFTCollectionPublic}>() - ?? panic("Could not borrow a reference to the collection") - -// Borrow a reference to the NFT as usual -let nft = collection.borrowExampleNFT(id: 42) - ?? panic("Could not borrow a reference to the NFT") - -// Call the resolveView method -// Provide the type of the view that you want to resolve -// View types are defined in the MetadataViews contract -// You can see if an NFT supports a specific view type by using the `getViews()` method -if let view = nft.resolveView(Type()) { - let display = view as! MetadataViews.Display - - log(display.name) - log(display.description) - log(display.thumbnail) -} - -// The owner is stored directly on the NFT object -let owner: Address = nft.owner!.address! - -// Inspect the type of this NFT to verify its origin -let nftType = nft.getType() - -// `nftType.identifier` is `A.e03daebed8ca0615.ExampleNFT.NFT` -``` +**Source: [get_nft_metadata.cdc](https://github.com/onflow/flow-nft/blob/standard-v2/scripts/get_nft_metadata.cdc)** ### How to implement metadata -The [example NFT contract](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc) shows how to implement metadata views. - -### List of common views - -| Name | Purpose | Status | Source | -| ----------- | ------------------------------------------ | ----------- | --------------------------------------------------------------------------------------------------------- | -| `Display` | Return the basic representation of an NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L35-L70) | -| `HTTPFile` | A file available at an HTTP(S) URL. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L80-L92) | -| `IPFSFile` | A file stored in IPFS. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L94-L133) | -| `Royalties` | An array of Royalty Cuts for a given NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L136-L208) | - -## Royalty View - -The `MetadataViews` contract also includes [a standard view for Royalties](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L136-L208). - -This view is meant to be used by 3rd party marketplaces to take a cut of the proceeds of an NFT sale -and send it to the author of a certain NFT. Each NFT can have its own royalty view: - -```cadence -pub struct Royalties { - - /// Array that tracks the individual royalties - access(self) let cutInfos: [Royalty] -} -``` - -and the royalty can indicate whatever fungible token it wants to accept via the type of the generic `{FungibleToken.Reciever}` capability that it specifies: - -```cadence -pub struct Royalty { - /// Generic FungibleToken Receiver for the beneficiary of the royalty - /// Can get the concrete type of the receiver with receiver.getType() - /// Recommendation - Users should create a new link for a FlowToken receiver for this using `getRoyaltyReceiverPublicPath()`, - /// and not use the default FlowToken receiver. - /// This will allow users to update the capability in the future to use a more generic capability - pub let receiver: Capability<&AnyResource{FungibleToken.Receiver}> - - /// Multiplier used to calculate the amount of sale value transferred to royalty receiver. - /// Note - It should be between 0.0 and 1.0 - /// Ex - If the sale value is x and multiplier is 0.56 then the royalty value would be 0.56 * x. - /// - /// Generally percentage get represented in terms of basis points - /// in solidity based smart contracts while cadence offers `UFix64` that already supports - /// the basis points use case because its operations - /// are entirely deterministic integer operations and support up to 8 points of precision. - pub let cut: UFix64 -} -``` - -If someone wants to make a listing for their NFT on a marketplace, -the marketplace can check to see if the royalty receiver accepts the seller's desired fungible token -by checking the concrete type of the reference. -If the concrete type is not the same as the type of token the seller wants to accept, -the marketplace has a few options. -They could either get the address of the receiver by using the -`receiver.owner.address` field and check to see if the account has a receiver for the desired token, -they could perform the sale without a royalty cut, or they could abort the sale -since the token type isn't accepted by the royalty beneficiary. - -You can see example implementations of royalties in the `ExampleNFT` contract -and the associated transactions and scripts. - -======= -| Name | Purpose | Status | Source | -| ----------- | ------------------------------------------ | ----------- | -------------------------------------------------------------------------------------------------------- | -| `Display` | Return the basic representation of an NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L35-L70) | -| `HTTPFile` | A file available at an HTTP(S) URL. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L80-L92) | -| `IPFSFile` | A file stored in IPFS. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L94-L133) | -| `Royalties` | An array of Royalty Cuts for a given NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L136-L208) | -| `Edition` | Return information about one or more editions for an NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L246-L266) | -| `NFTCollectionData` | Provides storage and retrieval information of an NFT | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L243-L299) | -| `NFTCollectionDisplay` | Returns the basic representation of an NFT's Collection. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L301-L328) | - -#### Important Royalty Instructions for Royalty Receivers - -If you plan to set your account as a receiver of royalties, you'll likely want to be able to accept -as many token types as possible. This won't be immediately possible at first, but eventually, -we will also design a contract that can act as a sort of switchboard for fungible tokens. -It will accept any generic fungible token and route it to the correct vault in your account. -This hasn't been built yet, but you can still set up your account to be ready for it in the future. -Therefore, if you want to receive royalties, you should set up your account with the -[`setup_account_to_receive_royalty.cdc` transaction](https://github.com/onflow/flow-nft/blob/c13545c37be4d1e63605c5d76340fb188923d997/transactions/setup_account_to_receive_royalty.cdc). - -This will link generic public path from `MetadataViews.getRoyaltyReceiverPublicPath()` -to your chosen fungible token for now. Then, use that public path for your royalty receiver -and in the future, you will be able to easily update the link at that path to use the -fungible token switchboard instead. - -## How to propose a new view - -Please open a pull request to propose a new metadata view or changes to an existing view. - -## Feedback - -As Flow and Cadence are still new, -we expect this standard to evolve based on feedback -from both developers and users. - -We'd love to hear from anyone who has feedback. For example: - -- Are there any features that are missing from the standard? -- Are the current features defined in the best way possible? -- Are there any pre and post conditions that are missing? -- Are the pre and post conditions defined well enough? Error messages? -- Are there any other actions that need an event defined for them? -- Are the current event definitions clear enough and do they provide enough information? -- Are the variable, function, and parameter names descriptive enough? -- Are there any openings for bugs or vulnerabilities that we are not noticing? - -Please create an issue in this repository if there is a feature that -you believe needs discussing or changing. +The [example NFT contract](https://github.com/onflow/flow-nft/blob/standard-v2/contracts/ExampleNFT.cdc) shows a basic example +for how to implement metadata views. ## Comparison to other standards on Ethereum @@ -299,86 +134,4 @@ but without most of the downsides. - Events are defined in the contract for withdrawing and depositing, so a recipient will always be notified that someone has sent them tokens with their own deposit event. - This version can support batch transfers of NFTs. Even though it isn't explicitly defined in the contract, a batch transfer can be done within a transaction by just withdrawing all the tokens to transfer, then depositing them wherever they need to be, all atomically. - Transfers can trigger actions because users can define custom `Receivers` to execute certain code when a token is sent. -- Easy ownership indexing: rathing than iterating through all tokens to find which ones you own, you have them all stored in your account's collection and can get the list of the ones you own instantly. - -## How to test the standard - -If you want to test out these contracts, we recommend either testing them -with the [Flow Playground](https://play.flow.com) -or with the [Visual Studio Code Extension](../../../tools/vscode-extension/index.mdx). - -The steps to follow are: - -1. Deploy `NonFungibleToken.cdc` -2. Deploy `ExampleNFT.cdc`, importing `NonFungibleToken` from the address you deployed it to. - -Then you can experiment with some of the other transactions and scripts in `transactions/` -or even write your own. You'll need to replace some of the import address placeholders with addresses that you deploy to, as well as some of the transaction arguments. - -## Running automated tests - -You can find automated tests in the `lib/go/test/nft_test.go` file. It uses the transaction templates that are contained in the `lib/go/templates/templates.go` file. - -Tests have also been written in JavaScript and can be found in `lib/js/test/tests/nft_test.js`. Similar to the tests written in Go, test helper functions can be found in `lib/js/test/templates/` directory. - -Entering the `make test` command from the root directory will run both Go and JavaScript test suites. If you'd like to run just one test suite, you can run `make test` from the test suite's `test/` directory (e.g. running `make test` from `lib/js/test` will run just your JavaScript tests). - -## Bonus features - -### NFT Forwarding - -While this utility contract is not a standard, it is a demonstration of how an account could be configured to forward NFTs to a specified forwarding recipient's collection. - -The NFTForwarder resource itself can be referenced like any `NonFungibleToken.Receiver` resource, allowing a sender to deposit NFT's as they usually would. However, `deposit()` as implemented in this resource forwards the deposited NFT to the designated recipient's collection. - -Several transactions are included in this repo to demonstrate how to interact with the `NFTForwarder` resource. Those are: -* `create_forwarder.cdc` - Creates the NFTForwarder resource and links the capability to `ExampleNFT.CollectionPublicPath`, where an Example NFT Collection would expect to be found. -* `transfer_nft_to_receiver.cdc` - Transfers an NFT to the forwarder by way of `deposit()` found in NonFungibleToken.Receiver` interface. By construction of the NFTForwarder resource, the NFT deposited by the signer is further forwarded to the forwarding recipient designated in the NFTForwarder resource. -* `change_forwarder_recipient.cdc` - Changes the designated recipient collection to which NFT will be forwarded. -* `unlink_forwarder_link_collection.cdc` - Unlinks the forwarder resource from `ExampleNFT.CollectionPublicPath`, restoring the accounts CollectionPublic capability. - -**(These could each be defined as a separate interface and standard and are probably not part of the main standard) They are not implemented in this repository yet** - -10- Withdrawing tokens from someone else's Collection by using their `Provider` reference. - -- approved withdraw event -- Providing a resource that only approves an account to withdraw a specific amount per transaction or per day/month/etc. -- Returning the list of tokens that an account can withdraw for another account. -- Reading the balance of the account that you have permission to send tokens for -- Owner is able to increase and decrease the approval at will, or revoke it completely - - This is much harder than anticipated - -11 - Standard for Composability/Extensibility - -12 - Minting a specific amount of tokens using a specific minter resource that an owner can control - -- tokens minted event -- Setting a cap on the total number of tokens that can be minted at a time or overall -- Setting a time frame where this is allowed - -13 - Burning a specific amount of tokens using a specific burner resource that an owner controls - -- tokens burnt event -- Setting a cap on the number of tokens that can be burned at a time or overall -- Setting a time frame where this is allowed - -14 - Pausing Token transfers (maybe a way to prevent the contract from being imported? probably not a good idea) - -15 - Cloning the token to create a new token with the same distribution - -## License - -The works in these files: - -- [ExampleNFT.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc) -- [NonFungibleToken.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc) - -are under the [Unlicense](https://github.com/onflow/flow-nft/blob/master/LICENSE). - -## Deploying updates - -### Testnet - -```sh -TESTNET_PRIVATE_KEY=xxxx flow project deploy --update --network testnet -``` +- Easy ownership indexing: rather than iterating through all tokens to find which ones you own, you have them all stored in your account's collection and can get the list of the ones you own instantly. \ No newline at end of file From 0b539c6c91c701cb1fb4393495fc797e175ce678 Mon Sep 17 00:00:00 2001 From: Josh Hannan Date: Fri, 8 Mar 2024 10:41:06 -0600 Subject: [PATCH 2/2] update previewnet addresses and fix links --- docs/build/core-contracts/02-fungible-token.md | 14 +++++++++----- docs/build/core-contracts/03-flow-token.md | 11 ++++++----- docs/build/core-contracts/04-service-account.md | 11 ++++++----- docs/build/core-contracts/05-flow-fees.md | 11 ++++++----- .../06-staking-contract-reference.md | 11 ++++++----- .../core-contracts/07-epoch-contract-reference.md | 11 ++++++----- docs/build/core-contracts/08-non-fungible-token.md | 11 ++++++----- docs/build/core-contracts/09-nft-metadata.md | 11 ++++++----- docs/build/core-contracts/10-nft-storefront.md | 6 +++--- docs/build/core-contracts/11-staking-collection.md | 11 ++++++----- docs/build/core-contracts/12-hybrid-custody.md | 2 +- docs/build/core-contracts/flow-ft/index.md | 13 +++++++------ docs/build/core-contracts/flow-nft/index.md | 11 ++++++----- 13 files changed, 74 insertions(+), 60 deletions(-) diff --git a/docs/build/core-contracts/02-fungible-token.md b/docs/build/core-contracts/02-fungible-token.md index d5b978dc04..e4af362dff 100644 --- a/docs/build/core-contracts/02-fungible-token.md +++ b/docs/build/core-contracts/02-fungible-token.md @@ -6,11 +6,15 @@ sidebar_label: Fungible Token The `FungibleToken` contract implements the Fungible Token Standard. It is the second contract ever deployed on Flow. +The `FungibleTokenMetadataViews` and `FungibleTokenSwitchboard` contracts +are also deployed to the same account as `FungibleToken`. + Source: [FungibleToken.cdc](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0xee82856bf20e2aa6` | -| Testnet/Previewnet/Crescendo | `0x9a0766d93b6608b7` | -| Mainnet | `0xf233dcee88fe0abe` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0xee82856bf20e2aa6` | +| PreviewNet | `0xa0225e7000ac82a9` | +| Testnet/Crescendo | `0x9a0766d93b6608b7` | +| Mainnet | `0xf233dcee88fe0abe` | diff --git a/docs/build/core-contracts/03-flow-token.md b/docs/build/core-contracts/03-flow-token.md index 3fc187e500..6f3169565c 100644 --- a/docs/build/core-contracts/03-flow-token.md +++ b/docs/build/core-contracts/03-flow-token.md @@ -7,11 +7,12 @@ The `FlowToken` contract defines the FLOW network token. Source: [FlowToken.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowToken.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0x0ae53cb6e3f42a79` | -| Testnet/Previewnet/Crescendo | `0x7e60df042a9c0868` | -| Mainnet | `0x1654653399040a61` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0x0ae53cb6e3f42a79` | +| Previewnet | `0x4445e7ad11568276` | +| Testnet/Crescendo | `0x7e60df042a9c0868` | +| Mainnet | `0x1654653399040a61` | # Transactions diff --git a/docs/build/core-contracts/04-service-account.md b/docs/build/core-contracts/04-service-account.md index 3537506ee2..0e66f17315 100644 --- a/docs/build/core-contracts/04-service-account.md +++ b/docs/build/core-contracts/04-service-account.md @@ -24,8 +24,9 @@ to execute/handle blocks at a given block height. Source: [NodeVersionBeacon.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/NodeVersionBeacon.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x8c5303eaa26202d6` | -| Mainnet | `0xe467b9dd11fa00df` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x8c5303eaa26202d6` | +| Mainnet | `0xe467b9dd11fa00df` | diff --git a/docs/build/core-contracts/05-flow-fees.md b/docs/build/core-contracts/05-flow-fees.md index c585ad8ac0..04c9b27b7b 100644 --- a/docs/build/core-contracts/05-flow-fees.md +++ b/docs/build/core-contracts/05-flow-fees.md @@ -7,11 +7,12 @@ The `FlowFees` contract is where all the collected flow fees are gathered. Source: [FlowFees.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0xe5a8b7f23e8b548f` | -| Testnet/Previewnet/Crescendo | `0x912d5440f7e3769e` | -| Mainnet | `0xf919ee77447b7497` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0xe5a8b7f23e8b548f` | +| PreviewNet | `0xab086ce9cc29fc80` | +| Testnet/Crescendo | `0x912d5440f7e3769e` | +| Mainnet | `0xf919ee77447b7497` | The `FlowStorageFees` contract defines the parameters and utility methods for storage fees. diff --git a/docs/build/core-contracts/06-staking-contract-reference.md b/docs/build/core-contracts/06-staking-contract-reference.md index ce585e30ca..1f6413c4b0 100644 --- a/docs/build/core-contracts/06-staking-contract-reference.md +++ b/docs/build/core-contracts/06-staking-contract-reference.md @@ -9,11 +9,12 @@ The `FlowIDTableStaking` contract is the central table that manages staked nodes Source: [FlowIDTableStaking.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowIDTableStaking.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator/Canary | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x9eca2b38b18b5dfe` | -| Mainnet | `0x8624b52f9ddcd04a` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x9eca2b38b18b5dfe` | +| Mainnet | `0x8624b52f9ddcd04a` | # Transactions diff --git a/docs/build/core-contracts/07-epoch-contract-reference.md b/docs/build/core-contracts/07-epoch-contract-reference.md index ccab6a9cab..8175e84229 100644 --- a/docs/build/core-contracts/07-epoch-contract-reference.md +++ b/docs/build/core-contracts/07-epoch-contract-reference.md @@ -15,11 +15,12 @@ Sources: - [FlowClusterQC.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowClusterQC.cdc) - [FlowDKG.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowDKG.cdc) -| Network | Contract Address | -|------------------------------|----------------------| -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x9eca2b38b18b5dfe` | -| Mainnet | `0x8624b52f9ddcd04a` | +| Network | Contract Address | +|-------------------|----------------------| +| Emulator | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x9eca2b38b18b5dfe` | +| Mainnet | `0x8624b52f9ddcd04a` | # Transactions diff --git a/docs/build/core-contracts/08-non-fungible-token.md b/docs/build/core-contracts/08-non-fungible-token.md index 010e232cf9..8075a4190f 100644 --- a/docs/build/core-contracts/08-non-fungible-token.md +++ b/docs/build/core-contracts/08-non-fungible-token.md @@ -8,8 +8,9 @@ All NFT contracts are encouraged to import and implement this standard. Source: [NonFungibleToken.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x631e88ae7f1d7c20` | -| Mainnet | `0x1d7e57aa55817448` | +| Network | Contract Address | +| ------------------| -------------------- | +| Emulator/Canary | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x631e88ae7f1d7c20` | +| Mainnet | `0x1d7e57aa55817448` | diff --git a/docs/build/core-contracts/09-nft-metadata.md b/docs/build/core-contracts/09-nft-metadata.md index 444dc5aaf2..a818c584f5 100644 --- a/docs/build/core-contracts/09-nft-metadata.md +++ b/docs/build/core-contracts/09-nft-metadata.md @@ -10,11 +10,12 @@ It is deployed at the same address as the `NonFungibleToken` contract interface. Source: [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc) -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x631e88ae7f1d7c20` | -| Mainnet | `0x1d7e57aa55817448` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x631e88ae7f1d7c20` | +| Mainnet | `0x1d7e57aa55817448` | There exists a tool, [Flow NFT Catalog](https://flow-nft-catalog.com), which enables dapp developers the ability to unlock interoperability of your NFT collection across the Flow ecosystem. This will help make your NFT collection’s metadata more discoverable and interoperable. diff --git a/docs/build/core-contracts/10-nft-storefront.md b/docs/build/core-contracts/10-nft-storefront.md index 55e17aee12..b4915e6684 100644 --- a/docs/build/core-contracts/10-nft-storefront.md +++ b/docs/build/core-contracts/10-nft-storefront.md @@ -4,10 +4,10 @@ title: NFT Storefront Smart Contract ## Primer -|Name|Testnet/Previewnet/Crescendo|Mainnet| +|Name|Testnet/Crescendo|Mainnet| |----|----------------------------|-------| -|[NFTStorefront](contracts/NFTStorefront.cdc)|[0x94b06cfca1d8a476](https://testnet.flowdiver.io/contract/A.94b06cfca1d8a476.NFTStorefront)|[0x4eb8a10cb9f87357](https://www.flowdiver.io/contract/A.4eb8a10cb9f87357.NFTStorefront)| -|[NFTStorefrontV2 (recommended)](contracts/NFTStorefrontV2.cdc)|[0x2d55b98eb200daef](https://testnet.flowdiver.io/contract/A.2d55b98eb200daef.NFTStorefrontV2)|[0x4eb8a10cb9f87357](https://www.flowdiver.io/contract/A.4eb8a10cb9f87357.NFTStorefrontV2)| +|[NFTStorefront](https://github.com/onflow/nft-storefront/blob/main/contracts/NFTStorefront.cdc)|[0x94b06cfca1d8a476](https://testnet.flowdiver.io/contract/A.94b06cfca1d8a476.NFTStorefront)|[0x4eb8a10cb9f87357](https://www.flowdiver.io/contract/A.4eb8a10cb9f87357.NFTStorefront)| +|[NFTStorefrontV2 (recommended)](https://github.com/onflow/nft-storefront/blob/main/contracts/NFTStorefrontV2.cdc)|[0x2d55b98eb200daef](https://testnet.flowdiver.io/contract/A.2d55b98eb200daef.NFTStorefrontV2)|[0x4eb8a10cb9f87357](https://www.flowdiver.io/contract/A.4eb8a10cb9f87357.NFTStorefrontV2)| The `NFTStorefrontV2` contract lets you create a *non-custodial Resource (NFT) marketplace* on the FLOW blockchain. diff --git a/docs/build/core-contracts/11-staking-collection.md b/docs/build/core-contracts/11-staking-collection.md index 9d0862c2b2..6a4c47202d 100644 --- a/docs/build/core-contracts/11-staking-collection.md +++ b/docs/build/core-contracts/11-staking-collection.md @@ -20,11 +20,12 @@ See the [Staking Collection Docs](../../networks/staking/14-staking-collection.m Source: [FlowStakingCollection.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStakingCollection.cdc) -| Network | Contract Address | -|------------------------------|----------------------| -| Emulator | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x95e019a17d0e23d7` | -| Mainnet | `0x8d0e87b65159ae63` | +| Network | Contract Address | +|------------------ |----------------------| +| Emulator | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x95e019a17d0e23d7` | +| Mainnet | `0x8d0e87b65159ae63` | ## Transactions diff --git a/docs/build/core-contracts/12-hybrid-custody.md b/docs/build/core-contracts/12-hybrid-custody.md index 8be16c5e6a..a1aa361b25 100644 --- a/docs/build/core-contracts/12-hybrid-custody.md +++ b/docs/build/core-contracts/12-hybrid-custody.md @@ -11,5 +11,5 @@ You can see the docs for account linking [here](https://developers.flow.com/buil | Network | Contract Address | |------------------------------|----------------------| -| Testnet/Previewnet/Crescendo | [`0x294e44e1ec6993c6`](https://contractbrowser.com/account/0x294e44e1ec6993c6) | +| Testnet/Crescendo | [`0x294e44e1ec6993c6`](https://contractbrowser.com/account/0x294e44e1ec6993c6) | | Mainnet | [`0xd8a7e05a7ac670c0`](https://contractbrowser.com/account/0xd8a7e05a7ac670c0) | \ No newline at end of file diff --git a/docs/build/core-contracts/flow-ft/index.md b/docs/build/core-contracts/flow-ft/index.md index ed629a1e2a..30bdf95802 100644 --- a/docs/build/core-contracts/flow-ft/index.md +++ b/docs/build/core-contracts/flow-ft/index.md @@ -25,12 +25,13 @@ The `FungibleToken`, `FungibleTokenMetadataViews`, and `FungibleTokenSwitchboard on various networks. You can import them in your contracts from these addresses. There is no need to deploy them yourself. -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator | `0xee82856bf20e2aa6` | -| Testnet/Previewnet/Crescendo | `0x9a0766d93b6608b7` | -| Sandboxnet | `0xe20612a0776ca4bf` | -| Mainnet | `0xf233dcee88fe0abe` | +| Network | Contract Address | +| ----------------- | -------------------- | +| Emulator | `0xee82856bf20e2aa6` | +| PreviewNet | `0xa0225e7000ac82a9` | +| Testnet/Crescendo | `0x9a0766d93b6608b7` | +| Sandboxnet | `0xe20612a0776ca4bf` | +| Mainnet | `0xf233dcee88fe0abe` | The `Burner` contract is also deployed to these addresses, but should not be used until after the Cadence 1.0 network upgrade. diff --git a/docs/build/core-contracts/flow-nft/index.md b/docs/build/core-contracts/flow-nft/index.md index 06b43291b7..39d4a5791b 100644 --- a/docs/build/core-contracts/flow-nft/index.md +++ b/docs/build/core-contracts/flow-nft/index.md @@ -24,11 +24,12 @@ There is no need to deploy them yourself. Note: With the emulator, you must use the -contracts flag to deploy these contracts. -| Network | Contract Address | -| ---------------------------- | -------------------- | -| Emulator/Canary | `0xf8d6e0586b0a20c7` | -| Testnet/Previewnet/Crescendo | `0x631e88ae7f1d7c20` | -| Mainnet | `0x1d7e57aa55817448` | +| Network | Contract Address | +| ------------------| -------------------- | +| Emulator/Canary | `0xf8d6e0586b0a20c7` | +| PreviewNet | `0xb6763b4399a888c8` | +| Testnet/Crescendo | `0x631e88ae7f1d7c20` | +| Mainnet | `0x1d7e57aa55817448` | ## Core Types