Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Uniques: An economically-secure basic-featured NFT pallet #8813

Merged
merged 61 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
2d98b0d
Uniques: An economically-secure basic-featured NFT pallet
gavofyork May 14, 2021
628b1bd
Merge remote-tracking branch 'origin/master' into gav-uniques
gavofyork May 16, 2021
aa84878
force_transfer
gavofyork May 16, 2021
0c0c4cb
freeze/thaw
gavofyork May 16, 2021
a203c1f
team management
gavofyork May 16, 2021
b2c20f8
approvals
gavofyork May 16, 2021
f98dcaf
Fixes
gavofyork May 16, 2021
da78f22
force_asset_status
gavofyork May 16, 2021
ee5f32a
class_metadata
gavofyork May 17, 2021
c148760
instance metadata
gavofyork May 17, 2021
ec47648
Fixes
gavofyork May 17, 2021
2949d12
use nmap
gavofyork May 17, 2021
30f2f9e
Fixes
gavofyork May 17, 2021
00c8e04
class metadata has information field
gavofyork May 17, 2021
326beba
Intiial mock/tests and a fix
gavofyork May 19, 2021
f5c9d1d
Remove impl_non_fungibles
gavofyork May 19, 2021
7874135
Docs
gavofyork May 19, 2021
6a231a8
Update frame/uniques/src/lib.rs
gavofyork May 19, 2021
4699b23
Update frame/uniques/src/lib.rs
gavofyork May 19, 2021
fb6ea03
Update frame/uniques/src/lib.rs
gavofyork May 19, 2021
87cc1d8
Update frame/uniques/src/lib.rs
gavofyork May 19, 2021
3ad9a52
Merge remote-tracking branch 'origin/master' into gav-uniques
gavofyork May 19, 2021
8e8b4df
Reserve, don't transfer.
gavofyork May 19, 2021
01f9713
Fixes
gavofyork May 19, 2021
4bf6f54
Tests
gavofyork May 19, 2021
821de3d
Tests
gavofyork May 19, 2021
d410298
refresh_deposit
gavofyork May 19, 2021
d703510
Tests and proper handling of metdata destruction
gavofyork May 19, 2021
59ff5e9
test burn
gavofyork May 19, 2021
4be8928
Tests
gavofyork May 19, 2021
de1eb5a
Update impl_fungibles.rs
gavofyork May 20, 2021
53c666c
Initial benchmarking
gavofyork May 20, 2021
1545abe
benchmark
gavofyork May 20, 2021
24e08cc
Fixes
gavofyork May 20, 2021
3027c7b
Merge branch 'master' of https://github.com/paritytech/substrate into…
May 20, 2021
da6f748
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
May 20, 2021
95e49b9
Attributes
gavofyork May 20, 2021
ccaf6ec
Attribute metadata
gavofyork May 20, 2021
c51153f
Fixes
gavofyork May 20, 2021
5361afb
Update frame/uniques/README.md
gavofyork May 21, 2021
87ab1b4
Merge branch 'gav-uniques-attributes' into gav-uniques
gavofyork May 21, 2021
8a45594
Docs
gavofyork May 21, 2021
dad10a7
Docs
gavofyork May 21, 2021
33fd4a8
Docs
gavofyork May 21, 2021
31c6e03
Simple metadata
gavofyork May 21, 2021
092127c
Use BoundedVec
gavofyork May 24, 2021
67b190b
Merge branch 'master' of https://github.com/paritytech/substrate into…
May 24, 2021
f9f6f51
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
May 24, 2021
f38e9b9
Update frame/uniques/src/lib.rs
gavofyork May 31, 2021
04c900a
Update frame/uniques/src/lib.rs
gavofyork May 31, 2021
d41c1b4
Update frame/uniques/src/lib.rs
gavofyork May 31, 2021
7353b34
Update frame/uniques/src/lib.rs
gavofyork May 31, 2021
f84688d
Update frame/uniques/src/lib.rs
gavofyork May 31, 2021
bd82d6e
Fixes
gavofyork May 31, 2021
dce127c
Merge branch 'gav-uniques' of github.com:paritytech/substrate into ga…
gavofyork May 31, 2021
ca0b97c
Update frame/uniques/README.md
gavofyork May 31, 2021
59dbd0f
Update frame/uniques/README.md
gavofyork May 31, 2021
2e36b5c
Update frame/uniques/README.md
gavofyork May 31, 2021
f50d089
Docs
gavofyork Jun 1, 2021
f240bc4
Bump
gavofyork Jun 1, 2021
765a780
Merge branch 'master' into gav-uniques
gavofyork Jun 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ members = [
"frame/transaction-payment/rpc/runtime-api",
"frame/treasury",
"frame/tips",
"frame/uniques",
"frame/utility",
"frame/vesting",
"primitives/allocator",
Expand Down
4 changes: 4 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pallet-treasury = { version = "3.0.0", default-features = false, path = "../../.
pallet-utility = { version = "3.0.0", default-features = false, path = "../../../frame/utility" }
pallet-transaction-payment = { version = "3.0.0", default-features = false, path = "../../../frame/transaction-payment" }
pallet-transaction-payment-rpc-runtime-api = { version = "3.0.0", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" }
pallet-uniques = { version = "3.0.0", default-features = false, path = "../../../frame/uniques" }
pallet-vesting = { version = "3.0.0", default-features = false, path = "../../../frame/vesting" }

max-encoded-len = { version = "3.0.0", default-features = false, path = "../../../max-encoded-len", features = [ "derive" ] }
Expand Down Expand Up @@ -157,6 +158,7 @@ std = [
"sp-version/std",
"pallet-society/std",
"pallet-recovery/std",
"pallet-uniques/std",
"pallet-vesting/std",
"log/std",
"frame-try-runtime/std",
Expand Down Expand Up @@ -194,6 +196,7 @@ runtime-benchmarks = [
"pallet-tips/runtime-benchmarks",
"pallet-treasury/runtime-benchmarks",
"pallet-utility/runtime-benchmarks",
"pallet-uniques/runtime-benchmarks",
"pallet-vesting/runtime-benchmarks",
"pallet-offences-benchmarking",
"pallet-session-benchmarking",
Expand Down Expand Up @@ -237,6 +240,7 @@ try-runtime = [
"pallet-utility/try-runtime",
"pallet-society/try-runtime",
"pallet-recovery/try-runtime",
"pallet-uniques/try-runtime",
"pallet-vesting/try-runtime",
"pallet-gilt/try-runtime",
]
Expand Down
28 changes: 27 additions & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to 0. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 266,
spec_version: 267,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 2,
Expand Down Expand Up @@ -1090,6 +1090,30 @@ impl pallet_gilt::Config for Runtime {
type WeightInfo = pallet_gilt::weights::SubstrateWeight<Runtime>;
}

parameter_types! {
pub const ClassDeposit: Balance = 100 * DOLLARS;
pub const InstanceDeposit: Balance = 1 * DOLLARS;
pub const KeyLimit: u32 = 32;
pub const ValueLimit: u32 = 256;
}

impl pallet_uniques::Config for Runtime {
type Event = Event;
type ClassId = u32;
type InstanceId = u32;
type Currency = Balances;
type ForceOrigin = frame_system::EnsureRoot<AccountId>;
type ClassDeposit = ClassDeposit;
type InstanceDeposit = InstanceDeposit;
type MetadataDepositBase = MetadataDepositBase;
type AttributeDepositBase = MetadataDepositBase;
type DepositPerByte = MetadataDepositPerByte;
type StringLimit = StringLimit;
type KeyLimit = KeyLimit;
type ValueLimit = ValueLimit;
type WeightInfo = pallet_uniques::weights::SubstrateWeight<Runtime>;
}

construct_runtime!(
pub enum Runtime where
Block = Block,
Expand Down Expand Up @@ -1134,6 +1158,7 @@ construct_runtime!(
Mmr: pallet_mmr::{Pallet, Storage},
Lottery: pallet_lottery::{Pallet, Call, Storage, Event<T>},
Gilt: pallet_gilt::{Pallet, Call, Storage, Event<T>, Config},
Uniques: pallet_uniques::{Pallet, Call, Storage, Event<T>},
}
);

Expand Down Expand Up @@ -1508,6 +1533,7 @@ impl_runtime_apis! {
add_benchmark!(params, batches, pallet_timestamp, Timestamp);
add_benchmark!(params, batches, pallet_tips, Tips);
add_benchmark!(params, batches, pallet_treasury, Treasury);
add_benchmark!(params, batches, pallet_uniques, Uniques);
add_benchmark!(params, batches, pallet_utility, Utility);
add_benchmark!(params, batches, pallet_vesting, Vesting);

Expand Down
8 changes: 4 additions & 4 deletions frame/assets/src/impl_fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,26 +127,26 @@ impl<T: Config<I>, I: 'static> fungibles::Unbalanced<T::AccountId> for Pallet<T,
});
}
fn decrease_balance(asset: T::AssetId, who: &T::AccountId, amount: Self::Balance)
-> Result<Self::Balance, DispatchError>
-> Result<Self::Balance, DispatchError>
{
let f = DebitFlags { keep_alive: false, best_effort: false };
Self::decrease_balance(asset, who, amount, f, |_, _| Ok(()))
}
fn decrease_balance_at_most(asset: T::AssetId, who: &T::AccountId, amount: Self::Balance)
-> Self::Balance
-> Self::Balance
{
let f = DebitFlags { keep_alive: false, best_effort: true };
Self::decrease_balance(asset, who, amount, f, |_, _| Ok(()))
.unwrap_or(Zero::zero())
}
fn increase_balance(asset: T::AssetId, who: &T::AccountId, amount: Self::Balance)
-> Result<Self::Balance, DispatchError>
-> Result<Self::Balance, DispatchError>
{
Self::increase_balance(asset, who, amount, |_| Ok(()))?;
Ok(amount)
}
fn increase_balance_at_most(asset: T::AssetId, who: &T::AccountId, amount: Self::Balance)
-> Self::Balance
-> Self::Balance
{
match Self::increase_balance(asset, who, amount, |_| Ok(())) {
Ok(()) => amount,
Expand Down
16 changes: 7 additions & 9 deletions frame/assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,6 @@ pub mod pallet {
/// - `owner`: The owner of this class of assets. The owner has full superuser permissions
/// over this asset, but may later change and configure the permissions using `transfer_ownership`
/// and `set_team`.
/// - `max_zombies`: The total number of accounts which may hold assets in this class yet
/// have no existential deposit.
/// - `min_balance`: The minimum balance of this new asset that any single account must
/// have. If an account's balance is reduced below this, then it collapses to zero.
///
Expand Down Expand Up @@ -588,8 +586,8 @@ pub mod pallet {
/// to zero.
///
/// Weight: `O(1)`
/// Modes: Pre-existence of `target`; Post-existence of sender; Prior & post zombie-status
/// of sender; Account pre-existence of `target`.
/// Modes: Pre-existence of `target`; Post-existence of sender; Account pre-existence of
/// `target`.
#[pallet::weight(T::WeightInfo::transfer())]
pub(super) fn transfer(
origin: OriginFor<T>,
Expand Down Expand Up @@ -624,8 +622,8 @@ pub mod pallet {
/// to zero.
///
/// Weight: `O(1)`
/// Modes: Pre-existence of `target`; Post-existence of sender; Prior & post zombie-status
/// of sender; Account pre-existence of `target`.
/// Modes: Pre-existence of `target`; Post-existence of sender; Account pre-existence of
/// `target`.
#[pallet::weight(T::WeightInfo::transfer_keep_alive())]
pub(super) fn transfer_keep_alive(
origin: OriginFor<T>,
Expand Down Expand Up @@ -661,8 +659,8 @@ pub mod pallet {
/// to zero.
///
/// Weight: `O(1)`
/// Modes: Pre-existence of `dest`; Post-existence of `source`; Prior & post zombie-status
/// of `source`; Account pre-existence of `dest`.
/// Modes: Pre-existence of `dest`; Post-existence of `source`; Account pre-existence of
/// `dest`.
#[pallet::weight(T::WeightInfo::force_transfer())]
pub(super) fn force_transfer(
origin: OriginFor<T>,
Expand Down Expand Up @@ -779,7 +777,7 @@ pub mod pallet {
///
/// Origin must be Signed and the sender should be the Admin of the asset `id`.
///
/// - `id`: The identifier of the asset to be frozen.
/// - `id`: The identifier of the asset to be thawed.
///
/// Emits `Thawed`.
///
Expand Down
6 changes: 6 additions & 0 deletions frame/support/src/storage/bounded_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ impl<T, S> BoundedVec<T, S> {
}
}

impl<T, S: Get<u32>> From<BoundedVec<T, S>> for Vec<T> {
fn from(x: BoundedVec<T, S>) -> Vec<T> {
x.0
}
}

impl<T, S: Get<u32>> BoundedVec<T, S> {
/// Get the bound of the type in `usize`.
pub fn bound() -> usize {
Expand Down
2 changes: 1 addition & 1 deletion frame/support/src/storage/types/nmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ where

/// Iter over all value of the storage.
///
/// NOTE: If a value failed to decode becaues storage is corrupted then it is skipped.
/// NOTE: If a value failed to decode because storage is corrupted then it is skipped.
pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
<Self as crate::storage::StoragePrefixedMap<Value>>::iter_values()
}
Expand Down
46 changes: 46 additions & 0 deletions frame/uniques/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[package]
name = "pallet-uniques"
version = "3.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "FRAME NFT asset management pallet"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
sp-core = { version = "3.0.0", default-features = false, path = "../../primitives/core" }
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
frame-support = { version = "3.0.0", default-features = false, path = "../support" }
frame-system = { version = "3.0.0", default-features = false, path = "../system" }
frame-benchmarking = { version = "3.1.0", default-features = false, path = "../benchmarking", optional = true }

[dev-dependencies]
sp-std = { version = "3.0.0", path = "../../primitives/std" }
sp-core = { version = "3.0.0", path = "../../primitives/core" }
Comment on lines +25 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sp-std = { version = "3.0.0", path = "../../primitives/std" }
sp-core = { version = "3.0.0", path = "../../primitives/core" }

this seems redundant as they are part of deps above already

sp-io = { version = "3.0.0", path = "../../primitives/io" }
pallet-balances = { version = "3.0.0", path = "../balances" }

[features]
default = ["std"]
std = [
"codec/std",
"sp-std/std",
"sp-core/std",
"sp-runtime/std",
"frame-support/std",
"frame-system/std",
"frame-benchmarking/std",
]
runtime-benchmarks = [
"frame-benchmarking",
"sp-runtime/runtime-benchmarks",
"frame-system/runtime-benchmarks",
]
try-runtime = ["frame-support/try-runtime"]
78 changes: 78 additions & 0 deletions frame/uniques/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Uniques Module

A simple, secure module for dealing with non-fungible assets.

## Overview

The Uniques module provides functionality for asset management of non-fungible asset classes, including:

* Asset Issuance
* Asset Transfer
* Asset Destruction

To use it in your runtime, you need to implement the assets [`uniques::Config`](https://docs.rs/pallet-uniques/latest/pallet_uniques/pallet/trait.Config.html).

The supported dispatchable functions are documented in the [`uniques::Call`](https://docs.rs/pallet-uniques/latest/pallet_uniques/pallet/enum.Call.html) enum.

### Terminology

* **Asset issuance:** The creation of a new asset instance.
* **Asset transfer:** The action of transferring an asset instance from one account to another.
* **Asset burning:** The destruction of an asset instance.
* **Non-fungible asset:** An asset for which each unit has unique characteristics. There is exactly
one instance of such an asset in existance and there is exactly one owning account.

### Goals

The Uniques pallet in Substrate is designed to make the following possible:

* Allow accounts to permissionlessly create asset classes (collections of asset instances).
* Allow a named (permissioned) account to mint and burn unique assets within a class.
* Move asset instances between accounts permissionlessly.
* Allow a named (permissioned) account to freeze and unfreeze unique assets within a
class or the entire class.
* Allow the owner of an asset instance to delegate the ability to transfer the asset to some
named third-party.

## Interface

### Permissionless dispatchables
* `create`: Create a new asset class by placing a deposit.
* `transfer`: Transfer an asset instance to a new owner.
* `redeposit`: Update the deposit amount of an asset instance, potentially freeing funds.
* `approve_transfer`: Name a delegate who may authorise a transfer.
* `cancel_approval`: Revert the effects of a previous `approve_transfer`.

### Permissioned dispatchables
* `destroy`: Destroy an asset class.
* `mint`: Mint a new asset instance within an asset class.
* `burn`: Burn an asset instance within an asset class.
* `freeze`: Prevent an individual asset from being transferred.
* `thaw`: Revert the effects of a previous `freeze`.
* `freeze_class`: Prevent all asset within a class from being transferred.
* `thaw_class`: Revert the effects of a previous `freeze_class`.
* `transfer_ownership`: Alter the owner of an asset class, moving all associated deposits.
* `set_team`: Alter the permissioned accounts of an asset class.

### Metadata (permissioned) dispatchables
* `set_attribute`: Set a metadata attribute of an asset instance or class.
* `clear_attribute`: Remove a metadata attribute of an asset instance or class.
* `set_metadata`: Set general metadata of an asset instance.
* `clear_metadata`: Remove general metadata of an asset instance.
* `set_class_metadata`: Set general metadata of an asset class.
* `clear_class_metadata`: Remove general metadata of an asset class.

### Force (i.e. governance) dispatchables
* `force_create`: Create a new asset class.
* `force_asset_status`: Alter the underlying characteristics of an asset class.

Please refer to the [`Call`](https://docs.rs/pallet-assets/latest/pallet_assets/enum.Call.html) enum
and its associated variants for documentation on each function.

## Related Modules

* [`System`](https://docs.rs/frame-system/latest/frame_system/)
* [`Support`](https://docs.rs/frame-support/latest/frame_support/)
* [`Assets`](https://docs.rs/pallet-assets/latest/pallet_assetss/)

License: Apache-2.0
Loading