-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding a non-fungible token standard (#116)
## Type of change <!--Delete points that do not apply--> - New feature - Improvement (refactoring, restructuring repository, cleaning tech debt, ...) - Documentation ## Changes This adds a minimal standard (abi and usage guidelines) which have been extracted from our existing NFT implementation. ## Notes - Name is open to discussion - location of this standard is open to discussion, but should be kept together with the standard for Fungible tokens. --------- Co-authored-by: bitzoic <[email protected]> Co-authored-by: Cameron Carstens <[email protected]>
- Loading branch information
1 parent
4c0c99a
commit 715a90d
Showing
14 changed files
with
285 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,48 @@ jobs: | |
run: | | ||
cargo test --manifest-path tests/Cargo.toml | ||
build-standards: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Install Rust toolchain | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: ${{ env.RUST_VERSION }} | ||
override: true | ||
|
||
- name: Init cache | ||
uses: Swatinem/rust-cache@v1 | ||
|
||
- name: Install a modern linker (mold) | ||
uses: rui314/setup-mold@v1 | ||
|
||
- name: Force Rust to use mold globally for compilation | ||
run: | | ||
touch ~/.cargo/config.toml | ||
echo "[target.x86_64-unknown-linux-gnu]" > ~/.cargo/config.toml | ||
echo 'linker = "clang"' >> ~/.cargo/config.toml | ||
echo 'rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"]' >> ~/.cargo/config.toml | ||
- name: Install rustfmt | ||
run: rustup component add rustfmt | ||
|
||
- name: Install Fuel toolchain | ||
uses: FuelLabs/[email protected] | ||
with: | ||
name: my-toolchain | ||
components: forc@${{ env.FORC_VERSION }}, fuel-core@${{ env.CORE_VERSION }} | ||
|
||
- name: Check Sway formatting | ||
run: forc fmt --path standards --check | ||
|
||
- name: Build All Standards | ||
run: forc build --path standards | ||
|
||
contributing-book: | ||
runs-on: ubuntu-latest | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[workspace] | ||
members = ["frc20", "frc721"] |
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
out | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[project] | ||
authors = ["Fuel Labs <[email protected]>"] | ||
entry = "lib.sw" | ||
license = "Apache-2.0" | ||
name = "frc721" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<p align="center"> | ||
<picture> | ||
<source media="(prefers-color-scheme: dark)" srcset=".docs/frc-721-logo-dark-theme.png"> | ||
<img alt="SwayApps logo" width="400px" src=".docs/frc-721-logo-light-theme.png"> | ||
</picture> | ||
</p> | ||
|
||
## Overview | ||
|
||
The FRC-721 standard defines and outlines NFTs on the Fuel Network. | ||
|
||
The official specification can be found in the [frc_721.sw](./src/frc_721.sw) file. | ||
|
||
To jumpstart the deployment of your own NFTs, the [NFT Library](../../libs/nft/) provides an easy to use outline following the FRC-721 standard and uses structs and traits for it's implementation. | ||
|
||
## Functions | ||
|
||
### `transfer()` | ||
|
||
Transfers ownership of an NFT from one Identity to another. | ||
|
||
> **NOTE:** At the time of a transfer, the approved Identity for that NFT (if any) **MUST** be reset to Option::None. | ||
### `approve()` | ||
|
||
Sets or reafirms the approved Identity for an NFT. | ||
|
||
> **NOTE:** The approved Identity for the specified NFT **MAY** transfer the token to a new owner. | ||
### `set_approval_for_all()` | ||
|
||
Enables or disables approval for a third party "Operator" to manage all of `msg_sender()`'s NFTs. | ||
|
||
> **NOTE:** An operator for an Identity **MAY** transfer and MAY set approved Identities for all tokens owned by the `msg_sender()`. | ||
### `approved()` | ||
|
||
Gets the approved Identity for a single NFT. | ||
|
||
> **NOTE:** Option::None indicates there is no approved Identity. | ||
### `balance_of()` | ||
|
||
Returns the number of NFTs owned by an Identity. | ||
|
||
### `is_approved_for_all()` | ||
|
||
Queries if an Identity is an authorized operator for another Identity. | ||
|
||
### `owner_of()` | ||
|
||
Queries the owner of an NFT. | ||
|
||
> **NOTE:** Option::None indicates there is no owner Identity. | ||
## Events | ||
|
||
### `ApprovalEvent` | ||
|
||
The `ApprovalEvent` event **MUST** be logged when the approved Identity for an NFT is changed or modified. | ||
The approved Identity for the specified NFT **MAY** transfer the token to a new owner. | ||
Option::None indicates there is no approved Identity. | ||
|
||
### `OperatorEvent` | ||
|
||
The `OperatorEvent` event **MUST** be logged when an operator is enabled or disabled for an owner. | ||
The operator can manage all NFTs of the owner. | ||
|
||
### `TransferEvent` | ||
|
||
The `TransferEvent` event **MUST** be logged when ownership of any NFT changes between two Identities. | ||
|
||
> **NOTE:** Exception: Cases where there is no new or previous owner, more formally known as minting and burning, the event **SHALL NOT** be logged. | ||
## Extensions | ||
|
||
### Metadata | ||
|
||
The metadata extension specification can be found [here](./src/extensions/frc721_metadata.sw). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
library frc721_metadata; | ||
|
||
/** | ||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, | ||
“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be | ||
interpreted as described in RFC 2119: https://www.ietf.org/rfc/rfc2119.txt | ||
*/ | ||
|
||
/// Any contract that implements FRC721_metadata SHALL also implement FRC721. | ||
abi FRC721_metadata { | ||
/// Get the name of the token | ||
/// Example (with trailing padding): "MY_TOKEN " | ||
fn name() -> str[64]; | ||
/// Get the symbol of the token | ||
/// Example (with trailing padding): "TKN " | ||
fn symbol() -> str[32]; | ||
/// A distinct Uniform Resource Identifier (URI) for a given asset. | ||
/// URIs are defined in FRC-3986. | ||
/// NOTE: This will be updated with StorageString once https://github.com/FuelLabs/sway-libs/issues/40 is merged. | ||
fn uri(token_id: u64) -> str[2048]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
library frc721; | ||
|
||
/** | ||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, | ||
“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be | ||
interpreted as described in RFC 2119: https://www.ietf.org/rfc/rfc2119.txt | ||
*/ | ||
|
||
/// This event MUST be logged when the approved Identity for an NFT is changed or modified. | ||
/// Option::None indicates there is no approved Identity. | ||
pub struct ApprovalEvent { | ||
approved: Option<Identity>, | ||
owner: Identity, | ||
token_id: u64, | ||
} | ||
/// This event MUST be logged when an operator is enabled or disabled for an owner. | ||
/// The operator can manage all NFTs of the owner. | ||
pub struct OperatorEvent { | ||
approved: bool, | ||
operator: Identity, | ||
owner: Identity, | ||
} | ||
/// This event MUST be logged when ownership of any NFT changes between two Identities. | ||
/// Exception: Cases where there is no new or previous owner, formally known as minting and burning, | ||
/// the event SHALL NOT be logged. | ||
pub struct TransferEvent { | ||
from: Identity, | ||
sender: Identity, | ||
to: Identity, | ||
token_id: u64, | ||
} | ||
|
||
abi FRC721 { | ||
/// Transfer ownership of an NFT from one Identity to another. | ||
/// At the time of a transfer, the approved Identity for that NFT (if any) MUST be reset to Option::None. | ||
/// | ||
/// -- THE CALLER IS RESPONSIBLE | ||
/// FOR CONFIRMING THAT `to` IS CAPABLE OF RECEIVING NFTS OR ELSE | ||
/// THEY MAY BE PERMANENTLY LOST! -- | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `to` - The Identity which the ownership of this token SHALL be set to. | ||
/// * `token_id` - The token of which ownership SHALL change. | ||
/// | ||
/// # Reverts | ||
/// | ||
/// * It is REQUIRED that `msg_sender()` is not the owner of this token. | ||
/// * It is REQUIRED that `msg_sender()` is not approved to transfer this token on the owner's behalf. | ||
/// * It is REQUIRED that `msg_sender()` is not approved to transfer all tokens on the owner's behalf. | ||
/// | ||
/// # Events | ||
/// | ||
/// * The TransferEvent event MUST be emitted when the function is not reverted. | ||
fn transfer(to: Identity, token_id: u64); | ||
/// Set or reafirm the approved Identity for an NFT. | ||
/// The approved Identity for the specified NFT MAY transfer the token to a new owner. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `approved` - The Identity that SHALL be approved as an NFT controller, or Option::None. | ||
/// * `token_id` - The token of which the NFT approval SHALL change. | ||
/// | ||
/// # Reverts | ||
/// | ||
/// * It is REQUIRED that `msg_sender()` is the owner of (or an approved Operator for) this NFT. | ||
/// | ||
/// # Events | ||
/// | ||
/// * The ApprovalEvent event MUST be emitted when the function is not reverted. | ||
fn approve(approved: Option<Identity>, token_id: u64); | ||
/// Enable or disable approval for a third party "Operator" to manage all | ||
/// of `msg_sender()`'s NFTs. | ||
/// An operator for an Identity MAY transfer and MAY set approved Identities for all tokens | ||
/// owned by the `msg_sender()`. | ||
/// | ||
/// -- The contract MUST allow multiple operators per owner. -- | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `approve` - MUST be `True` if the operator is approved and MUST be `False` to revoke approval. | ||
/// * `operator` - The Identity that SHALL be added to the set of authorized operators. | ||
/// | ||
/// # Events | ||
/// | ||
/// * The OperatorEvent event MUST be emitted. | ||
fn set_approval_for_all(approve: bool, operator: Identity); | ||
/// Get the approved Identity for a single NFT. | ||
/// Option::None indicates there is no approved Identity. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `token_id` - The NFT to find the approved Identity for. | ||
/// | ||
/// # Reverts | ||
/// | ||
/// * It is REQUIRED that `token_id` is valid NFT. | ||
fn approved(token_id: u64) -> Option<Identity>; | ||
/// The number of NFTs owned by an Identity. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `owner` - The Identity of which to query the balance. | ||
fn balance_of(owner: Identity) -> u64; | ||
/// Query if an Identity is an authorized operator for another Identity. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `operator` - The Identity that acts on behalf of the owner. | ||
/// * `owner` - The Identity that owns the NFT/NFTs. | ||
fn is_approved_for_all(operator: Identity, owner: Identity) -> bool; | ||
/// Query the owner of an NFT. | ||
/// Option::None indicates there is no owner Identity. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `token_id` - The NFT to find the owner for. | ||
/// | ||
/// # Reverts | ||
/// | ||
/// * It is REQUIRED that `token_id` is valid NFT. | ||
fn owner_of(token_id: u64) -> Option<Identity>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
library frc721; | ||
|
||
dep frc_721; | ||
dep extensions/frc721_metadata; |