git.delta.rocks / unique-network / refs/commits / bc41c8bcd94a

difftreelog

Merge branch 'develop' into style/fix-unused_parens-warning

Yaroslav Bolyukin2021-03-15parents: #e12feb6 #07649f2.patch.diff
in: master

15 files changed

modified.devcontainer/Dockerfilediffbeforeafterboth
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -9,6 +9,6 @@
     export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" && \
     [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
     nvm install v12.20.1 && \
-    rustup toolchain install nightly-2020-10-01 && \
-    rustup default nightly-2020-10-01 && \
+    rustup toolchain install nightly-2021-03-01 && \
+    rustup default nightly-2021-03-01 && \
     rustup target add wasm32-unknown-unknown
\ No newline at end of file
modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16,7 +16,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
 dependencies = [
- "gimli 0.23.0",
+ "gimli",
 ]
 
 [[package]]
@@ -380,6 +380,12 @@
 ]
 
 [[package]]
+name = "base-x"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
+
+[[package]]
 name = "base58"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -439,12 +445,14 @@
 
 [[package]]
 name = "bitvec"
-version = "0.17.4"
+version = "0.20.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c"
+checksum = "f5011ffc90248764d7005b0e10c7294f5aa1bd87d9dd7248f4ad475b347c294d"
 dependencies = [
- "either",
+ "funty",
  "radium",
+ "tap",
+ "wyz",
 ]
 
 [[package]]
@@ -480,6 +488,32 @@
 ]
 
 [[package]]
+name = "blake2s_simd"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2"
+dependencies = [
+ "arrayref",
+ "arrayvec 0.5.2",
+ "constant_time_eq",
+]
+
+[[package]]
+name = "blake3"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9ff35b701f3914bdb8fad3368d822c766ef2858b2583198e41639b936f09d3f"
+dependencies = [
+ "arrayref",
+ "arrayvec 0.5.2",
+ "cc",
+ "cfg-if 0.1.10",
+ "constant_time_eq",
+ "crypto-mac 0.8.0",
+ "digest 0.9.0",
+]
+
+[[package]]
 name = "block-buffer"
 version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -555,6 +589,15 @@
 ]
 
 [[package]]
+name = "build-helper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f"
+dependencies = [
+ "semver 0.6.0",
+]
+
+[[package]]
 name = "bumpalo"
 version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -562,9 +605,9 @@
 
 [[package]]
 name = "byte-slice-cast"
-version = "0.3.5"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3"
+checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81"
 
 [[package]]
 name = "byte-tools"
@@ -608,6 +651,28 @@
 checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
 
 [[package]]
+name = "cargo-platform"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cargo_metadata"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f"
+dependencies = [
+ "cargo-platform",
+ "semver 0.11.0",
+ "semver-parser 0.10.2",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
 name = "cc"
 version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -674,6 +739,17 @@
 ]
 
 [[package]]
+name = "cid"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff0e3bc0b6446b3f9663c1a6aba6ef06c5aeaa1bc92bd18077be337198ab9768"
+dependencies = [
+ "multibase",
+ "multihash",
+ "unsigned-varint 0.5.1",
+]
+
+[[package]]
 name = "cipher"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -755,6 +831,16 @@
 checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
 
 [[package]]
+name = "cpp_demangle"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44919ecaf6f99e8e737bc239408931c9a01e9a6c74814fee8242dd2506b65390"
+dependencies = [
+ "cfg-if 1.0.0",
+ "glob",
+]
+
+[[package]]
 name = "cpuid-bool"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -768,25 +854,25 @@
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dcc286b052ee24a1e5a222e7c1125e6010ad35b0f248709b9b3737a8fedcfdf"
+checksum = "4066fd63b502d73eb8c5fa6bcab9c7962b05cd580f6b149ee83a8e730d8ce7fb"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d9badfe36176cb653506091693bc2bb1970c9bddfcd6ec7fac404f7eaec6f38"
+checksum = "1a54e4beb833a3c873a18a8fe735d73d732044004c7539a072c8faa35ccb0c60"
 dependencies = [
  "byteorder",
  "cranelift-bforest",
  "cranelift-codegen-meta",
  "cranelift-codegen-shared",
  "cranelift-entity",
- "gimli 0.21.0",
+ "gimli",
  "log",
  "regalloc",
  "serde",
@@ -797,9 +883,9 @@
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c3f460031861e4f4ad510be62b2ae50bba6cc886b598a36f9c0a970feab9598"
+checksum = "c54cac7cacb443658d8f0ff36a3545822613fa202c946c0891897843bc933810"
 dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
@@ -807,24 +893,24 @@
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76ad12409e922e7697cd0bdc7dc26992f64a77c31880dfe5e3c7722f4710206d"
+checksum = "a109760aff76788b2cdaeefad6875a73c2b450be13906524f6c2a81e05b8d83c"
 
 [[package]]
 name = "cranelift-entity"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d97cdc58972ea065d107872cfb9079f4c92ade78a8af85aaff519a65b5d13f71"
+checksum = "3b044234aa32531f89a08b487630ddc6744696ec04c8123a1ad388de837f5de3"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ef419efb4f94ecc02e5d9fbcc910d2bb7f0040e2de570e63a454f883bc891d6"
+checksum = "5452b3e4e97538ee5ef2cc071301c69a86c7adf2770916b9d04e9727096abd93"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -834,9 +920,9 @@
 
 [[package]]
 name = "cranelift-native"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e69d44d59826eef6794066ac2c0f4ad3975f02d97030c60dbc04e3886adf36e"
+checksum = "f68035c10b2e80f26cc29c32fa824380877f38483504c2a47b54e7da311caaf3"
 dependencies = [
  "cranelift-codegen",
  "raw-cpuid",
@@ -845,17 +931,19 @@
 
 [[package]]
 name = "cranelift-wasm"
-version = "0.66.0"
+version = "0.69.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "979df666b1304624abe99738e9e0e7c7479ee5523ba4b8b237df9ff49996acbb"
+checksum = "a530eb9d1c95b3309deb24c3d179d8b0ba5837ed98914a429787c395f614949d"
 dependencies = [
  "cranelift-codegen",
  "cranelift-entity",
  "cranelift-frontend",
+ "itertools",
  "log",
  "serde",
+ "smallvec 1.6.1",
  "thiserror",
- "wasmparser 0.59.0",
+ "wasmparser",
 ]
 
 [[package]]
@@ -1050,6 +1138,26 @@
 checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
 
 [[package]]
+name = "data-encoding-macro"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a94feec3d2ba66c0b6621bca8bc6f68415b1e5c69af3586fdd0af9fd9f29b17"
+dependencies = [
+ "data-encoding",
+ "data-encoding-macro-internal",
+]
+
+[[package]]
+name = "data-encoding-macro-internal"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f83e699727abca3c56e187945f303389590305ab2f0185ea445aa66e8d5f2a"
+dependencies = [
+ "data-encoding",
+ "syn",
+]
+
+[[package]]
 name = "derive_more"
 version = "0.99.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1080,21 +1188,21 @@
 
 [[package]]
 name = "directories"
-version = "2.0.2"
+version = "3.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
+checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f"
 dependencies = [
- "cfg-if 0.1.10",
  "dirs-sys",
 ]
 
 [[package]]
-name = "directories"
-version = "3.0.1"
+name = "directories-next"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f"
+checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
 dependencies = [
- "dirs-sys",
+ "cfg-if 1.0.0",
+ "dirs-sys-next",
 ]
 
 [[package]]
@@ -1104,11 +1212,22 @@
 checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
 dependencies = [
  "libc",
- "redox_users",
+ "redox_users 0.3.5",
  "winapi 0.3.9",
 ]
 
 [[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users 0.4.0",
+ "winapi 0.3.9",
+]
+
+[[package]]
 name = "dns-parser"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1322,17 +1441,17 @@
 
 [[package]]
 name = "finality-grandpa"
-version = "0.12.3"
+version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b"
+checksum = "2cd795898c348a8ec9edc66ec9e014031c764d4c88cc26d09b492cd93eb41339"
 dependencies = [
  "either",
  "futures 0.3.12",
- "futures-timer 2.0.2",
+ "futures-timer 3.0.2",
  "log",
  "num-traits",
  "parity-scale-codec",
- "parking_lot 0.9.0",
+ "parking_lot 0.11.1",
 ]
 
 [[package]]
@@ -1390,8 +1509,9 @@
 
 [[package]]
 name = "fork-tree"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "632b95f97f332b2ff5bc3a42bc8e28772b067e333830e03fd046504f11cd0fb8"
 dependencies = [
  "parity-scale-codec",
 ]
@@ -1408,14 +1528,15 @@
 
 [[package]]
 name = "frame-benchmarking"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70fe99487f84579a3f2c4ba52650fec875492eea41be0e4eea8019187f105052"
 dependencies = [
  "frame-support",
  "frame-system",
  "linregress",
  "parity-scale-codec",
- "paste",
+ "paste 1.0.4",
  "sp-api",
  "sp-io",
  "sp-runtime",
@@ -1426,8 +1547,9 @@
 
 [[package]]
 name = "frame-benchmarking-cli"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2921b7890c5e4421a0b2eafbf835417eed8127b1cec3e1a0389515069f11d219"
 dependencies = [
  "Inflector",
  "chrono",
@@ -1449,8 +1571,9 @@
 
 [[package]]
 name = "frame-executive"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1da8fd471442bee91b9b3f587ec832e3f47800374fdb89b4a66591cd7c42b29f"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -1465,8 +1588,9 @@
 
 [[package]]
 name = "frame-metadata"
-version = "12.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "13.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "073f7bef18421362441a1708f8528e442234954611f95bdc554b313fb321948e"
 dependencies = [
  "parity-scale-codec",
  "serde",
@@ -1476,17 +1600,18 @@
 
 [[package]]
 name = "frame-support"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04e521e6214615bd82ba6b5fc7fd40a9cc14fdeb40f83da5eba12aa2f8179fb8"
 dependencies = [
  "bitflags",
  "frame-metadata",
  "frame-support-procedural",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
  "once_cell",
  "parity-scale-codec",
- "paste",
+ "paste 1.0.4",
  "serde",
  "smallvec 1.6.1",
  "sp-arithmetic",
@@ -1494,6 +1619,7 @@
  "sp-inherents",
  "sp-io",
  "sp-runtime",
+ "sp-staking",
  "sp-state-machine",
  "sp-std",
  "sp-tracing",
@@ -1501,8 +1627,9 @@
 
 [[package]]
 name = "frame-support-procedural"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2668e24cbaba7f0e91d0c92a94bd1ae425a942608ad0b775db32477f5df4da9e"
 dependencies = [
  "Inflector",
  "frame-support-procedural-tools",
@@ -1513,8 +1640,9 @@
 
 [[package]]
 name = "frame-support-procedural-tools"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4f88cfd111e004590f4542b75e6d3302137b9067d7e7219e4ac47a535c3b5c1"
 dependencies = [
  "frame-support-procedural-tools-derive",
  "proc-macro-crate",
@@ -1525,8 +1653,9 @@
 
 [[package]]
 name = "frame-support-procedural-tools-derive"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79285388b120ac96c15a791c56b26b9264f7231324fbe0fd05026acd92bf2e6a"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1535,11 +1664,12 @@
 
 [[package]]
 name = "frame-system"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5fedbff05d665c00bf4e089b4377fcb15b8bd37ebc3e5fc06665474cf6e25d7"
 dependencies = [
  "frame-support",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "serde",
  "sp-core",
@@ -1551,8 +1681,9 @@
 
 [[package]]
 name = "frame-system-benchmarking"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e93602f58cdab9820b6d607b7b50834d9b878efa33405a65c89ebfb5a596b584"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -1565,8 +1696,9 @@
 
 [[package]]
 name = "frame-system-rpc-runtime-api"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cb9d2f86a903fdee4ca3d660c767e69a743cee8aeb103563a14ea52e9f0001d"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -1607,6 +1739,12 @@
 checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 
 [[package]]
+name = "funty"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
+
+[[package]]
 name = "futures"
 version = "0.1.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1841,20 +1979,14 @@
 
 [[package]]
 name = "gimli"
-version = "0.21.0"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
 dependencies = [
  "fallible-iterator",
  "indexmap",
  "stable_deref_trait",
 ]
-
-[[package]]
-name = "gimli"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
 
 [[package]]
 name = "glob"
@@ -2229,9 +2361,9 @@
 
 [[package]]
 name = "impl-codec"
-version = "0.4.2"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53"
+checksum = "df170efa359aebdd5cb7fe78edcc67107748e4737bdca8a8fb40d15ea7a877ed"
 dependencies = [
  "parity-scale-codec",
 ]
@@ -2243,17 +2375,6 @@
 checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f"
 dependencies = [
  "serde",
-]
-
-[[package]]
-name = "impl-trait-for-tuples"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
 ]
 
 [[package]]
@@ -2509,9 +2630,9 @@
 
 [[package]]
 name = "kvdb"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92312348daade49976a6dc59263ad39ed54f840aacb5664874f7c9aa16e5f848"
+checksum = "8891bd853eff90e33024195d79d578dc984c82f9e0715fcd2b525a0c19d52811"
 dependencies = [
  "parity-util-mem",
  "smallvec 1.6.1",
@@ -2519,9 +2640,9 @@
 
 [[package]]
 name = "kvdb-memorydb"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "986052a8d16c692eaebe775391f9a3ac26714f3907132658500b601dec94c8c2"
+checksum = "30a0da8e08caf08d384a620ec19bb6c9b85c84137248e202617fb91881f25912"
 dependencies = [
  "kvdb",
  "parity-util-mem",
@@ -2530,9 +2651,9 @@
 
 [[package]]
 name = "kvdb-rocksdb"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d92c36be64baba5ea549116ff0d7ffd445456a7be8aaee21ec05882b980cd11"
+checksum = "34446c373ccc494c2124439281c198c7636ccdc2752c06722bbffd56d459c1e4"
 dependencies = [
  "fs-swap",
  "kvdb",
@@ -3146,13 +3267,12 @@
 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
 [[package]]
-name = "memmap"
-version = "0.7.0"
+name = "memmap2"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
+checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6"
 dependencies = [
  "libc",
- "winapi 0.3.9",
 ]
 
 [[package]]
@@ -3175,9 +3295,9 @@
 
 [[package]]
 name = "memory-db"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cbd2a22f201c03cc1706a727842490abfea17b7b53260358239828208daba3c"
+checksum = "814bbecfc0451fc314eeea34f05bbcd5b98a7ad7af37faee088b86a1e633f1d4"
 dependencies = [
  "hash-db",
  "hashbrown",
@@ -3315,15 +3435,30 @@
 checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
 
 [[package]]
+name = "multibase"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b78c60039650ff12e140ae867ef5299a58e19dded4d334c849dc7177083667e2"
+dependencies = [
+ "base-x",
+ "data-encoding",
+ "data-encoding-macro",
+]
+
+[[package]]
 name = "multihash"
 version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4dac63698b887d2d929306ea48b63760431ff8a24fac40ddb22f9c7f49fb7cab"
 dependencies = [
+ "blake2b_simd",
+ "blake2s_simd",
+ "blake3",
  "digest 0.9.0",
  "generic-array 0.14.4",
  "multihash-derive",
  "sha2 0.9.3",
+ "sha3",
  "unsigned-varint 0.5.1",
 ]
 
@@ -3456,7 +3591,7 @@
 
 [[package]]
 name = "nft-runtime"
-version = "2.1.0"
+version = "3.0.0"
 dependencies = [
  "frame-benchmarking",
  "frame-executive",
@@ -3494,7 +3629,7 @@
  "sp-std",
  "sp-transaction-pool",
  "sp-version",
- "substrate-wasm-builder-runner",
+ "substrate-wasm-builder",
 ]
 
 [[package]]
@@ -3584,19 +3719,12 @@
 
 [[package]]
 name = "object"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
-
-[[package]]
-name = "object"
-version = "0.20.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
+checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
 dependencies = [
  "crc32fast",
  "indexmap",
- "wasmparser 0.57.0",
 ]
 
 [[package]]
@@ -3643,8 +3771,9 @@
 
 [[package]]
 name = "pallet-aura"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73ff6054e982e7841a2519c988680620a85c1da5cd32363998a30302ed47f6f9"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3654,7 +3783,6 @@
  "serde",
  "sp-application-crypto",
  "sp-consensus-aura",
- "sp-inherents",
  "sp-runtime",
  "sp-std",
  "sp-timestamp",
@@ -3662,12 +3790,13 @@
 
 [[package]]
 name = "pallet-authorship"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47433a94141451e7079aabf3ca28f2bde8c642d84b568be9626e9b7cae8b11b1"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "sp-authorship",
  "sp-inherents",
@@ -3677,8 +3806,9 @@
 
 [[package]]
 name = "pallet-balances"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41aaeaf084e594273f82bcbf96416ef1fcab602e15dd1df04b9930eceb2eb518"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -3691,15 +3821,16 @@
 
 [[package]]
 name = "pallet-contracts"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0979c1dd82fc56a87b37311006fe56f406de027c24591353058e9e9fc56487c"
 dependencies = [
  "frame-support",
  "frame-system",
  "pallet-contracts-primitives",
  "pallet-contracts-proc-macro",
  "parity-scale-codec",
- "parity-wasm",
+ "parity-wasm 0.41.0",
  "pwasm-utils 0.16.0",
  "serde",
  "sp-core",
@@ -3712,8 +3843,9 @@
 
 [[package]]
 name = "pallet-contracts-primitives"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "621d75148763349f72e76e79f62365d28adb51e3f2e0285e4e8b8600ae600978"
 dependencies = [
  "bitflags",
  "parity-scale-codec",
@@ -3723,8 +3855,9 @@
 
 [[package]]
 name = "pallet-contracts-proc-macro"
-version = "0.1.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90046017aeee3f77752a6c77cdfb1bc93eb728591dc6edad36e2706f7626fd50"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3733,8 +3866,9 @@
 
 [[package]]
 name = "pallet-contracts-rpc"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22491e3c304819f96c83d02e43bd99128e4e42a57da4d6a9d4b5193778da915b"
 dependencies = [
  "jsonrpc-core",
  "jsonrpc-core-client",
@@ -3752,8 +3886,9 @@
 
 [[package]]
 name = "pallet-contracts-rpc-runtime-api"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb4b410cb148e68256e3827854a67ec34b16157f448e78173219dcd6a8ec7343"
 dependencies = [
  "pallet-contracts-primitives",
  "parity-scale-codec",
@@ -3764,8 +3899,9 @@
 
 [[package]]
 name = "pallet-grandpa"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c012cb0337ce1eaf0685be2777bce1ef8c5d7b7be77ea33916c316b40af43fa"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -3785,12 +3921,11 @@
 
 [[package]]
 name = "pallet-nft"
-version = "2.1.0"
+version = "3.0.0"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
  "pallet-balances",
  "pallet-contracts",
  "pallet-randomness-collective-flip",
@@ -3806,8 +3941,9 @@
 
 [[package]]
 name = "pallet-randomness-collective-flip"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3ea6fa9aa36735ec11d7ec4d97dd6472650c0656fdc6d4adaca2578bd71134"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3819,12 +3955,13 @@
 
 [[package]]
 name = "pallet-session"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d243c3ccac56a4c55fade6be5c5af1de07fac374fa7856377980a76b0c193cf"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.1.3",
+ "impl-trait-for-tuples",
  "pallet-timestamp",
  "parity-scale-codec",
  "serde",
@@ -3839,8 +3976,9 @@
 
 [[package]]
 name = "pallet-sudo"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a96774302e3824b7924c2465935ca4d558ea5f6a762c043fbc45fd2646ce89"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3853,13 +3991,14 @@
 
 [[package]]
 name = "pallet-timestamp"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b17dd274716a55a2c3e34d9c0ed66aaac3d7e0393ec9fd985e2b8532d697a7f3"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "serde",
  "sp-inherents",
@@ -3871,8 +4010,9 @@
 
 [[package]]
 name = "pallet-transaction-payment"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48e10dc1a10dd3f52edb20d3885cf5b2b16f26273a4d93e61331c6691fb13ab3"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3887,8 +4027,9 @@
 
 [[package]]
 name = "pallet-transaction-payment-rpc"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7835717b7d8fb59c33dd73f083c68a6d143a1dbe6029364c63ea7f4cb0ba3f9c"
 dependencies = [
  "jsonrpc-core",
  "jsonrpc-core-client",
@@ -3904,8 +4045,9 @@
 
 [[package]]
 name = "pallet-transaction-payment-rpc-runtime-api"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a92d3383260d0d19d9a36f40766d48d779fd19baccba8b20c3e7d2670a26ee1"
 dependencies = [
  "pallet-transaction-payment",
  "parity-scale-codec",
@@ -3915,12 +4057,13 @@
 
 [[package]]
 name = "pallet-treasury"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d19f881664d42d1c33dd67e690d6bddd35d38723fcc099b19304f9723fc3070c"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "pallet-balances",
  "parity-scale-codec",
  "serde",
@@ -3930,8 +4073,9 @@
 
 [[package]]
 name = "pallet-vesting"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e4e1af42bbdf1d477c3762387c74855f24bca47700df3ce7d9428045986b544"
 dependencies = [
  "enumflags2",
  "frame-support",
@@ -3944,16 +4088,18 @@
 
 [[package]]
 name = "parity-db"
-version = "0.1.2"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00d595e372d119261593297debbe4193811a4dc811d2a1ccbb8caaa6666ad7ab"
+checksum = "111e193c96758d476d272093a853882668da17489f76bf4361b8decae0b6c515"
 dependencies = [
  "blake2-rfc",
  "crc32fast",
+ "hex",
  "libc",
  "log",
- "memmap",
- "parking_lot 0.10.2",
+ "memmap2",
+ "parking_lot 0.11.1",
+ "rand 0.8.3",
 ]
 
 [[package]]
@@ -3976,9 +4122,9 @@
 
 [[package]]
 name = "parity-scale-codec"
-version = "1.3.6"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79602888a81ace83e3d1d4b2873286c1f5f906c84db667594e8db8da3506c383"
+checksum = "0cd3dab59b5cf4bc81069ade0fc470341a1ef3ad5fa73e5a8943bed2ec12b2e8"
 dependencies = [
  "arrayvec 0.5.2",
  "bitvec",
@@ -3989,9 +4135,9 @@
 
 [[package]]
 name = "parity-scale-codec-derive"
-version = "1.2.2"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "198db82bb1c18fc00176004462dd809b2a6d851669550aa17af6dacd21ae0c14"
+checksum = "fa04976a81fde04924b40cc4036c4d12841e8bb04325a5cf2ada75731a150a7d"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -4026,13 +4172,13 @@
 
 [[package]]
 name = "parity-util-mem"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f17f15cb05897127bf36a240085a1f0bbef7bce3024849eccf7f93f6171bc27"
+checksum = "664a8c6b8e62d8f9f2f937e391982eb433ab285b4cd9545b342441e04a906e42"
 dependencies = [
  "cfg-if 1.0.0",
  "hashbrown",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-util-mem-derive",
  "parking_lot 0.11.1",
  "primitive-types",
@@ -4053,6 +4199,15 @@
 
 [[package]]
 name = "parity-wasm"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "parity-wasm"
 version = "0.41.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865"
@@ -4167,6 +4322,12 @@
 ]
 
 [[package]]
+name = "paste"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5d65c4d95931acda4498f675e332fcbdc9a06705cd07086c510e9b6009cd1c1"
+
+[[package]]
 name = "paste-impl"
 version = "0.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4337,9 +4498,9 @@
 
 [[package]]
 name = "platforms"
-version = "0.2.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e"
+checksum = "989d43012e2ca1c4a02507c67282691a0a3207f9dc67cec596b43fe925b3d325"
 
 [[package]]
 name = "polling"
@@ -4383,9 +4544,9 @@
 
 [[package]]
 name = "primitive-types"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3824ae2c5e27160113b9e029a10ec9e3f0237bad8029f69c7724393c9fdefd8"
+checksum = "2415937401cb030a2a0a4d922483f945fa068f52a7dbb22ce0fe5f2b6f6adace"
 dependencies = [
  "fixed-hash",
  "impl-codec",
@@ -4449,11 +4610,11 @@
 
 [[package]]
 name = "prometheus"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30d70cf4412832bcac9cffe27906f4a66e450d323525e977168c70d1b36120ae"
+checksum = "c8425533e7122f0c3cc7a37e6244b16ad3a2cc32ae7ac6276e2a75da0d9c200d"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "fnv",
  "lazy_static",
  "parking_lot 0.11.1",
@@ -4513,6 +4674,15 @@
 ]
 
 [[package]]
+name = "psm"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3abf49e5417290756acfd26501536358560c4a5cc4a0934d390939acb3e7083a"
+dependencies = [
+ "cc",
+]
+
+[[package]]
 name = "pwasm-utils"
 version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4520,7 +4690,7 @@
 dependencies = [
  "byteorder",
  "log",
- "parity-wasm",
+ "parity-wasm 0.41.0",
 ]
 
 [[package]]
@@ -4531,7 +4701,7 @@
 dependencies = [
  "byteorder",
  "log",
- "parity-wasm",
+ "parity-wasm 0.41.0",
 ]
 
 [[package]]
@@ -4568,9 +4738,9 @@
 
 [[package]]
 name = "radium"
-version = "0.3.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac"
+checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
 
 [[package]]
 name = "rand"
@@ -4712,9 +4882,9 @@
 
 [[package]]
 name = "raw-cpuid"
-version = "7.0.4"
+version = "8.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "beb71f708fe39b2c5e98076204c3cc094ee5a4c12c4cdb119a2b72dc34164f41"
+checksum = "1fdf7d9dbd43f3d81d94a49c1c3df73cc2b3827995147e6cf7f89d4ec5483e73"
 dependencies = [
  "bitflags",
  "cc",
@@ -4788,6 +4958,16 @@
 ]
 
 [[package]]
+name = "redox_users"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
+dependencies = [
+ "getrandom 0.2.2",
+ "redox_syscall 0.2.5",
+]
+
+[[package]]
 name = "ref-cast"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4809,9 +4989,9 @@
 
 [[package]]
 name = "regalloc"
-version = "0.0.27"
+version = "0.0.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ba8aaf5fe7cf307c6dbdaeed85478961d29e25e3bee5169e11b92fa9f027a8"
+checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
 dependencies = [
  "log",
  "rustc-hash",
@@ -4944,7 +5124,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 dependencies = [
- "semver",
+ "semver 0.9.0",
 ]
 
 [[package]]
@@ -5021,9 +5201,19 @@
 ]
 
 [[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
 name = "sc-basic-authorship"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de86afb63617599821312bda08882451ff2b49d9c45e22513ddff5a07c6d966e"
 dependencies = [
  "futures 0.3.12",
  "futures-timer 3.0.2",
@@ -5045,8 +5235,9 @@
 
 [[package]]
 name = "sc-block-builder"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9862161f9d09d870401c7256c89ad1eb3afa56a61f7d7135c2bac76ff7152955"
 dependencies = [
  "parity-scale-codec",
  "sc-client-api",
@@ -5062,10 +5253,11 @@
 
 [[package]]
 name = "sc-chain-spec"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d97030776b49bc9c109e2d349212d8f2500637761048e1af5b7ce2dfd994c7"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "sc-chain-spec-derive",
  "sc-consensus-babe",
@@ -5083,8 +5275,9 @@
 
 [[package]]
 name = "sc-chain-spec-derive"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f14985513db9798fcedea58bdc8a08f1c6b3a515d6546ced7467b059b7982c4"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -5094,8 +5287,9 @@
 
 [[package]]
 name = "sc-cli"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ec1647b5c1483fa05f7f32e436d0e378e2f3d5696a5a30bddf66f5faf28acb4"
 dependencies = [
  "chrono",
  "fdlimit",
@@ -5132,8 +5326,9 @@
 
 [[package]]
 name = "sc-client-api"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56d8b2c8dc0cee9ac56e87ad50c980edbdeb35bdd5b5d9da4ae90567423363be"
 dependencies = [
  "derive_more",
  "fnv",
@@ -5166,8 +5361,9 @@
 
 [[package]]
 name = "sc-client-db"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5741e447d71ff36c147f961b2271b6b3fad0cc347e96936bc8b63ddffa594b27"
 dependencies = [
  "blake2-rfc",
  "hash-db",
@@ -5196,8 +5392,9 @@
 
 [[package]]
 name = "sc-consensus"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99f20cc8b8a74e218365ac4187bce26ea631d58d221caa1797bc6ec8056dba33"
 dependencies = [
  "sc-client-api",
  "sp-blockchain",
@@ -5207,8 +5404,9 @@
 
 [[package]]
 name = "sc-consensus-aura"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e0d32ccddef567a0fe373729aa4da51b2d437cbb102b9810400c9e77e040c1d"
 dependencies = [
  "derive_more",
  "futures 0.3.12",
@@ -5226,6 +5424,7 @@
  "sp-blockchain",
  "sp-consensus",
  "sp-consensus-aura",
+ "sp-consensus-slots",
  "sp-core",
  "sp-inherents",
  "sp-io",
@@ -5238,8 +5437,9 @@
 
 [[package]]
 name = "sc-consensus-babe"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98d52048476e0fcb53feae8ca919a602104f1ba0b89a729b496440f36b332961"
 dependencies = [
  "derive_more",
  "fork-tree",
@@ -5269,6 +5469,7 @@
  "sp-blockchain",
  "sp-consensus",
  "sp-consensus-babe",
+ "sp-consensus-slots",
  "sp-consensus-vrf",
  "sp-core",
  "sp-inherents",
@@ -5283,8 +5484,9 @@
 
 [[package]]
 name = "sc-consensus-epochs"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "326313ffb249a526e8ee8e08af9fdf0c4459cebeaa760b934e9df3985b68e4df"
 dependencies = [
  "fork-tree",
  "parity-scale-codec",
@@ -5296,8 +5498,9 @@
 
 [[package]]
 name = "sc-consensus-slots"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76e09ff8b680d449102da9717a70c3bbbbb981fd4cf1bfbafc1739d954eb0898"
 dependencies = [
  "futures 0.3.12",
  "futures-timer 3.0.2",
@@ -5322,8 +5525,9 @@
 
 [[package]]
 name = "sc-consensus-uncles"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37294bae6d787eecf2b15255dc75cd559b4ad813e0efcf28cd4423e218931b80"
 dependencies = [
  "log",
  "sc-client-api",
@@ -5336,15 +5540,16 @@
 
 [[package]]
 name = "sc-executor"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bace6a35999d2da7311d8fb98a29c1e89dbf0d14e50ac14140f2c38089819f46"
 dependencies = [
  "derive_more",
  "lazy_static",
  "libsecp256k1",
  "log",
  "parity-scale-codec",
- "parity-wasm",
+ "parity-wasm 0.41.0",
  "parking_lot 0.11.1",
  "sc-executor-common",
  "sc-executor-wasmi",
@@ -5365,12 +5570,13 @@
 
 [[package]]
 name = "sc-executor-common"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87004102a8e95f432f1c624c7fa7fb0edc5995db2e0fcbabbb697f1955e7c1d2"
 dependencies = [
  "derive_more",
  "parity-scale-codec",
- "parity-wasm",
+ "parity-wasm 0.41.0",
  "sp-allocator",
  "sp-core",
  "sp-serializer",
@@ -5381,8 +5587,9 @@
 
 [[package]]
 name = "sc-executor-wasmi"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d3d7b6db2df5f2c24848883a855a8276363f00cef5b49744974f7e1203bf274"
 dependencies = [
  "log",
  "parity-scale-codec",
@@ -5396,12 +5603,13 @@
 
 [[package]]
 name = "sc-executor-wasmtime"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24673c981fad2dff4398a09a1086579e2774f18d81639fa2bd9cb215e6dd9e36"
 dependencies = [
  "log",
  "parity-scale-codec",
- "parity-wasm",
+ "parity-wasm 0.41.0",
  "pwasm-utils 0.14.0",
  "sc-executor-common",
  "scoped-tls",
@@ -5414,8 +5622,9 @@
 
 [[package]]
 name = "sc-finality-grandpa"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7e87e63c57933e173a8643ff197b579e3fc5c91b16ca006096f482de8159318"
 dependencies = [
  "derive_more",
  "finality-grandpa",
@@ -5426,7 +5635,7 @@
  "log",
  "parity-scale-codec",
  "parking_lot 0.11.1",
- "pin-project 0.4.27",
+ "pin-project 1.0.5",
  "rand 0.7.3",
  "sc-block-builder",
  "sc-client-api",
@@ -5452,8 +5661,9 @@
 
 [[package]]
 name = "sc-informant"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f4c8994853e1158dc4f448b014aa83eef56ced214ec0af316eecf4a6ca3268f"
 dependencies = [
  "ansi_term 0.12.1",
  "futures 0.3.12",
@@ -5470,8 +5680,9 @@
 
 [[package]]
 name = "sc-keystore"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d966ed36c404eced656bd63aad8a30d2c1a14633f07cd1d7d9c11b62f75a7905"
 dependencies = [
  "async-trait",
  "derive_more",
@@ -5490,8 +5701,9 @@
 
 [[package]]
 name = "sc-light"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04e8dbcb2951f7cf76ddf97ed26dcef0dab79d76745de4a8f169d58236ea8704"
 dependencies = [
  "hash-db",
  "lazy_static",
@@ -5509,8 +5721,9 @@
 
 [[package]]
 name = "sc-network"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20fb4ed5d6b86faafb0743c8c2fd1c89b52cde7697373b254c7553800efaebbf"
 dependencies = [
  "async-std",
  "async-trait",
@@ -5518,6 +5731,7 @@
  "bitflags",
  "bs58",
  "bytes 1.0.1",
+ "cid",
  "derive_more",
  "either",
  "erased-serde",
@@ -5535,7 +5749,7 @@
  "nohash-hasher",
  "parity-scale-codec",
  "parking_lot 0.11.1",
- "pin-project 0.4.27",
+ "pin-project 1.0.5",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -5561,8 +5775,9 @@
 
 [[package]]
 name = "sc-network-gossip"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2cd5487d6f8051863a186e2aea4c233a07bb691780d3b117c9d6ffe1ff9a8fe"
 dependencies = [
  "futures 0.3.12",
  "futures-timer 3.0.2",
@@ -5577,8 +5792,9 @@
 
 [[package]]
 name = "sc-offchain"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bc91fc71c128748a3393cb3421e12a7759ccffcc1cc4a9e6ff4ead6cc68ba48"
 dependencies = [
  "bytes 0.5.6",
  "fnv",
@@ -5604,8 +5820,9 @@
 
 [[package]]
 name = "sc-peerset"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce454e528e7797a239e734d0d66bf904d48be47aa92691ac7546a45ec32a64cf"
 dependencies = [
  "futures 0.3.12",
  "libp2p",
@@ -5617,8 +5834,9 @@
 
 [[package]]
 name = "sc-proposer-metrics"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecfc2c6cc5dc0ecb1109cce9773b50ad9a3cdbf239dc702ef9071949244dcf3e"
 dependencies = [
  "log",
  "substrate-prometheus-endpoint",
@@ -5626,8 +5844,9 @@
 
 [[package]]
 name = "sc-rpc"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "750397c6aa5a4f922cac99599ad74a4082e3e87553d51ceb4c48abfa056ff32c"
 dependencies = [
  "futures 0.3.12",
  "hash-db",
@@ -5660,8 +5879,9 @@
 
 [[package]]
 name = "sc-rpc-api"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc8393410297df2885efec20d0629a9833b4fd9e4ad83a92471e1ea0c11a0a54"
 dependencies = [
  "derive_more",
  "futures 0.3.12",
@@ -5684,8 +5904,9 @@
 
 [[package]]
 name = "sc-rpc-server"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17c76164897bd3b0d04c2d6aeeb4d3492c86e324b0b08f408b847ea35421b589"
 dependencies = [
  "futures 0.1.30",
  "jsonrpc-core",
@@ -5702,10 +5923,11 @@
 
 [[package]]
 name = "sc-service"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9315b44eb991ca4f477d889bbd649a2b4b557f963fe48ec5a36c3422518e4a0"
 dependencies = [
- "directories 3.0.1",
+ "directories",
  "exit-future",
  "futures 0.1.30",
  "futures 0.3.12",
@@ -5718,7 +5940,7 @@
  "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
- "pin-project 0.4.27",
+ "pin-project 1.0.5",
  "rand 0.7.3",
  "sc-block-builder",
  "sc-chain-spec",
@@ -5765,8 +5987,9 @@
 
 [[package]]
 name = "sc-state-db"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f144043d5860ce133f701fa78679d6278f2dfc698686beb5f6d892c267e9d92"
 dependencies = [
  "log",
  "parity-scale-codec",
@@ -5780,15 +6003,16 @@
 
 [[package]]
 name = "sc-telemetry"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05040c594b331d90d7341e82c6dc6a3eb7bb2afb4e5dc9c36a79a6754166057"
 dependencies = [
  "chrono",
  "futures 0.3.12",
  "libp2p",
  "log",
  "parking_lot 0.11.1",
- "pin-project 0.4.27",
+ "pin-project 1.0.5",
  "rand 0.7.3",
  "serde",
  "serde_json",
@@ -5802,8 +6026,9 @@
 
 [[package]]
 name = "sc-tracing"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef0a4aa327b8bc89d9c5ae57a2f493d8f54ccd706f6763614ab522559fe481d8"
 dependencies = [
  "ansi_term 0.12.1",
  "atty",
@@ -5830,8 +6055,9 @@
 
 [[package]]
 name = "sc-tracing-proc-macro"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec18b0506911e6d624d9ea8f8cc5f503e7944a0fe7d37de95ee84033cf160ebc"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -5841,8 +6067,9 @@
 
 [[package]]
 name = "sc-transaction-graph"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87b385b8f66cce185478c500ad3de8f4775ab0e948c31561aeac78a27bedc654"
 dependencies = [
  "derive_more",
  "futures 0.3.12",
@@ -5863,8 +6090,9 @@
 
 [[package]]
 name = "sc-transaction-pool"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09f4331ea8da2ff45a9466637f90f5cc89f9d31fcd1cd20f74f2520b33bff069"
 dependencies = [
  "futures 0.3.12",
  "futures-diagnose",
@@ -5992,11 +6220,30 @@
 
 [[package]]
 name = "semver"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
+dependencies = [
+ "semver-parser 0.7.0",
+]
+
+[[package]]
+name = "semver"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 dependencies = [
- "semver-parser",
+ "semver-parser 0.7.0",
+]
+
+[[package]]
+name = "semver"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
+dependencies = [
+ "semver-parser 0.10.2",
+ "serde",
 ]
 
 [[package]]
@@ -6006,6 +6253,15 @@
 checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
 [[package]]
+name = "semver-parser"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
+dependencies = [
+ "pest",
+]
+
+[[package]]
 name = "serde"
 version = "1.0.123"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6147,7 +6403,7 @@
  "approx",
  "num-complex",
  "num-traits",
- "paste",
+ "paste 0.1.18",
 ]
 
 [[package]]
@@ -6218,8 +6474,9 @@
 
 [[package]]
 name = "sp-allocator"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec5f988ad0cabdb646318cb515a91e9d89062debc9728f9b634d73acab3f3f39"
 dependencies = [
  "log",
  "sp-core",
@@ -6230,8 +6487,9 @@
 
 [[package]]
 name = "sp-api"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e63c3460d5daecf67df542c34c2bbd636214a5a200d4bddcfa2ffb9e72c346af"
 dependencies = [
  "hash-db",
  "parity-scale-codec",
@@ -6246,8 +6504,9 @@
 
 [[package]]
 name = "sp-api-proc-macro"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "289624f4fe0f61e63a5019ed26c3bc732b5145eb52796ac6053cd72656d947a1"
 dependencies = [
  "blake2-rfc",
  "proc-macro-crate",
@@ -6258,8 +6517,9 @@
 
 [[package]]
 name = "sp-application-crypto"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c52e2e6d43036b97c4fce1ed87c5262c1ffdc78c655ada4d3024a3f8094bdd2c"
 dependencies = [
  "parity-scale-codec",
  "serde",
@@ -6270,8 +6530,9 @@
 
 [[package]]
 name = "sp-arithmetic"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0f1c69966c192d1dee8521f0b29ece2b14db07b9b44d801a94e295234761645"
 dependencies = [
  "integer-sqrt",
  "num-traits",
@@ -6283,8 +6544,9 @@
 
 [[package]]
 name = "sp-authorship"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ec68fb8e5a37548b06c14ee91a9c574cc330324c86d37810ec29dd4f8bc68d7"
 dependencies = [
  "parity-scale-codec",
  "sp-inherents",
@@ -6294,8 +6556,9 @@
 
 [[package]]
 name = "sp-block-builder"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0adc979dbe619f56d664ebd1293dce13fcad6b8a47bcdd620ed53a454d330d12"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -6306,8 +6569,9 @@
 
 [[package]]
 name = "sp-blockchain"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8007c1ad8e9fb6cd8eed4e0fc91504a9ca4b228e1315302a2fbb0ac7f509f1b"
 dependencies = [
  "futures 0.3.12",
  "log",
@@ -6324,8 +6588,9 @@
 
 [[package]]
 name = "sp-chain-spec"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a24beb11980d0c755ead0c05f3f966c490e4a3730785c04c03855fada65d697"
 dependencies = [
  "serde",
  "serde_json",
@@ -6333,8 +6598,9 @@
 
 [[package]]
 name = "sp-consensus"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "884db6c4b03f0f2fb2993127a2db95fc740fcd3496746dcaa6829c9868e7dc75"
 dependencies = [
  "futures 0.3.12",
  "futures-timer 3.0.2",
@@ -6359,12 +6625,14 @@
 
 [[package]]
 name = "sp-consensus-aura"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd00fc95b26393522be1394fb67cc536736cc5a902dec0d3e2827909b7c1118"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
  "sp-application-crypto",
+ "sp-consensus-slots",
  "sp-inherents",
  "sp-runtime",
  "sp-std",
@@ -6373,8 +6641,9 @@
 
 [[package]]
 name = "sp-consensus-babe"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a153085b1542b5cbe23686433cd36d1a634964f1b707671d0ffb01d8d9313047"
 dependencies = [
  "merlin",
  "parity-scale-codec",
@@ -6393,17 +6662,20 @@
 
 [[package]]
 name = "sp-consensus-slots"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32bd501ab76c827d74f145063cd8cb993a9f634dac93c9b0d909111cd5900a6a"
 dependencies = [
  "parity-scale-codec",
+ "sp-arithmetic",
  "sp-runtime",
 ]
 
 [[package]]
 name = "sp-consensus-vrf"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "030895d70bf3095c857f4727a7cce7c43af29efe3413bb547ee28700f7d78766"
 dependencies = [
  "parity-scale-codec",
  "schnorrkel",
@@ -6414,8 +6686,9 @@
 
 [[package]]
 name = "sp-core"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abbc8d4e9b8a7d5819ed26f1374017bb32833ef4890e4ff065e1da30669876bc"
 dependencies = [
  "base58",
  "blake2-rfc",
@@ -6458,8 +6731,9 @@
 
 [[package]]
 name = "sp-database"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8c3f018913eef191d95c824657c5759c459d28670e654fa34f5d9bd5e6f0492"
 dependencies = [
  "kvdb",
  "parking_lot 0.11.1",
@@ -6467,8 +6741,9 @@
 
 [[package]]
 name = "sp-debug-derive"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e80275f23b4e7ba8f54dec5f90f016530e7307d2ee9445f617ab986cbe97f31e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6477,8 +6752,9 @@
 
 [[package]]
 name = "sp-externalities"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fdc625f8c7b13b9a136d334888b21b5743d2081cb666cb03efca1dc9b8f74d1"
 dependencies = [
  "environmental",
  "parity-scale-codec",
@@ -6488,8 +6764,9 @@
 
 [[package]]
 name = "sp-finality-grandpa"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "702e0be150e1b557df42326ec9b82c2010366631d03be27c69912d446abbf87a"
 dependencies = [
  "finality-grandpa",
  "log",
@@ -6505,8 +6782,9 @@
 
 [[package]]
 name = "sp-inherents"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2542380b535c6941502a0a3069a657eb5abb70fd67b11afa164d4a4b038ba73a"
 dependencies = [
  "parity-scale-codec",
  "parking_lot 0.11.1",
@@ -6517,8 +6795,9 @@
 
 [[package]]
 name = "sp-io"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33fd69f0a6e91bedc2fb1c5cc3689c212474b6c918274cb4cb14dbbe3c428c14"
 dependencies = [
  "futures 0.3.12",
  "hash-db",
@@ -6541,8 +6820,9 @@
 
 [[package]]
 name = "sp-keyring"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b59f2b0e94b2048d4984aa6eb40eef2e4c05d3adf27a083dd3c9b0fce74ef7a"
 dependencies = [
  "lazy_static",
  "sp-core",
@@ -6552,8 +6832,9 @@
 
 [[package]]
 name = "sp-keystore"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6ccd2baf189112355338e8b224dc513cd239b974dbd717f12b3dc7a7248c3b"
 dependencies = [
  "async-trait",
  "derive_more",
@@ -6569,8 +6850,9 @@
 
 [[package]]
 name = "sp-offchain"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bd80eedcedcc8342e77c26d59ad90b6904715a862731fa16616650773570e63"
 dependencies = [
  "sp-api",
  "sp-core",
@@ -6579,16 +6861,18 @@
 
 [[package]]
 name = "sp-panic-handler"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54702e109f1c8a870dd4065a497d2612d42cec5817126e96cc0658c5ea975784"
 dependencies = [
  "backtrace",
 ]
 
 [[package]]
 name = "sp-rpc"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2e5b1ed655d11449073b914b048895f45241e02b3919d1d0187f315435fee18"
 dependencies = [
  "serde",
  "sp-core",
@@ -6596,16 +6880,17 @@
 
 [[package]]
 name = "sp-runtime"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfa4b353b76f04616dbdb8d269d58dcac47acb31c006d3b70e7b64233e68695e"
 dependencies = [
  "either",
  "hash256-std-hasher",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
  "parity-scale-codec",
  "parity-util-mem",
- "paste",
+ "paste 1.0.4",
  "rand 0.7.3",
  "serde",
  "sp-application-crypto",
@@ -6617,10 +6902,11 @@
 
 [[package]]
 name = "sp-runtime-interface"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2e5c88b4bc8d607e4e2ff767a85db58cf7101f3dd6064f06929342ea67fe8fb"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "primitive-types",
  "sp-externalities",
@@ -6634,8 +6920,9 @@
 
 [[package]]
 name = "sp-runtime-interface-proc-macro"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19a6c7c2251512c9e533d15db8a863b06ece1cbee778130dd9adbe44b6b39aa9"
 dependencies = [
  "Inflector",
  "proc-macro-crate",
@@ -6646,8 +6933,9 @@
 
 [[package]]
 name = "sp-sandbox"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e92caf4555d676d8f0b67def0041da789f79a5d5f341130496f15a6261926cc"
 dependencies = [
  "parity-scale-codec",
  "sp-core",
@@ -6659,8 +6947,9 @@
 
 [[package]]
 name = "sp-serializer"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "982d793f01eb9eea9f30ffc63b821170068b9f0d9edf715d8ba77dc4de9c300f"
 dependencies = [
  "serde",
  "serde_json",
@@ -6668,8 +6957,9 @@
 
 [[package]]
 name = "sp-session"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c7cf161533725a78083b04f3269effe4c3b4b6ce5f655019b3eec3e729ba4d4"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -6681,8 +6971,9 @@
 
 [[package]]
 name = "sp-staking"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc729eb10f8809c61a1fe439ac118a4413de004aaf863003ee8752ac0b596e73"
 dependencies = [
  "parity-scale-codec",
  "sp-runtime",
@@ -6691,8 +6982,9 @@
 
 [[package]]
 name = "sp-state-machine"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46fa4143e58e9130f726d4e8a9b86f3530a8bd19a2eedcdcf4af205f4b5a6d4f"
 dependencies = [
  "hash-db",
  "log",
@@ -6713,13 +7005,15 @@
 
 [[package]]
 name = "sp-std"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35391ea974fa5ee869cb094d5b437688fbf3d8127d64d1b9fed5822a1ed39b12"
 
 [[package]]
 name = "sp-storage"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86af458d4a0251c490cdde9dcaaccb88d398f3b97ac6694cdd49ed9337e6b961"
 dependencies = [
  "impl-serde",
  "parity-scale-codec",
@@ -6731,8 +7025,9 @@
 
 [[package]]
 name = "sp-tasks"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c585340cbee96c53a9b43fd07d81edf6cebeb80e4ca7c0ee79b856c0b1883a0e"
 dependencies = [
  "log",
  "sp-core",
@@ -6744,10 +7039,11 @@
 
 [[package]]
 name = "sp-timestamp"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27387c541197b9f47f3d9ddcab5649a3ecdca582d2f2ea2b511af24a3d3cbf83"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "sp-api",
  "sp-inherents",
@@ -6758,8 +7054,9 @@
 
 [[package]]
 name = "sp-tracing"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567382d8d4e14fb572752863b5cd57a78f9e9a6583332b590b726f061f3ea957"
 dependencies = [
  "log",
  "parity-scale-codec",
@@ -6771,8 +7068,9 @@
 
 [[package]]
 name = "sp-transaction-pool"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3264d3b7ea31483eddffa2cc7f28c4d9c022598e456a985fd1cb5879a4609853"
 dependencies = [
  "derive_more",
  "futures 0.3.12",
@@ -6787,8 +7085,9 @@
 
 [[package]]
 name = "sp-trie"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b85b7f745da41ef825c6f7b93f1fdc897b03df94a4884adfbb70fbcd0aed1298"
 dependencies = [
  "hash-db",
  "memory-db",
@@ -6801,8 +7100,9 @@
 
 [[package]]
 name = "sp-utils"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ec2a5f924f7affd1e959f8f3c02bd87cdfa0e11c71a4cbc075f955ead8c1a1"
 dependencies = [
  "futures 0.3.12",
  "futures-core",
@@ -6813,8 +7113,9 @@
 
 [[package]]
 name = "sp-version"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbeffa538a13d715d30e01d57a2636ba32845b737a29a3ea32403576588222e7"
 dependencies = [
  "impl-serde",
  "parity-scale-codec",
@@ -6825,10 +7126,11 @@
 
 [[package]]
 name = "sp-wasm-interface"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b214e125666a6416cf30a70cc6a5dacd34a4e5197f8a3d479f714af7e1dc7a47"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "sp-std",
  "wasmi",
@@ -6912,18 +7214,18 @@
 
 [[package]]
 name = "strum"
-version = "0.16.0"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22"
+checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
 dependencies = [
  "strum_macros",
 ]
 
 [[package]]
 name = "strum_macros"
-version = "0.16.0"
+version = "0.20.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81"
+checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -6946,16 +7248,18 @@
 
 [[package]]
 name = "substrate-build-script-utils"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd540ba72520174c2c73ce96bf507eeba3cc8a481f58be92525b69110e1fa645"
 dependencies = [
  "platforms",
 ]
 
 [[package]]
 name = "substrate-frame-rpc-system"
-version = "2.0.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e46123ec4a690d91967de07cd6af4dde90d14519a1a8d43f61bd3f78dd3d0ef"
 dependencies = [
  "frame-system-rpc-runtime-api",
  "futures 0.3.12",
@@ -6977,8 +7281,9 @@
 
 [[package]]
 name = "substrate-prometheus-endpoint"
-version = "0.8.1"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#0e070672cf7a7bec72fb3f26188915cfb43c440f"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eb561c19a121e1c89daa79dbfa67a55080f813caa47fd231833a0669696d508"
 dependencies = [
  "async-std",
  "derive_more",
@@ -6990,10 +7295,20 @@
 ]
 
 [[package]]
-name = "substrate-wasm-builder-runner"
-version = "1.0.6"
+name = "substrate-wasm-builder"
+version = "4.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2a965994514ab35d3893e9260245f2947fd1981cdd4fffd2c6e6d1a9ce02e6a"
+checksum = "93a3d51ad6abbc408b03ea962062bfcc959b438a318d7d4bedd181e1effd0610"
+dependencies = [
+ "ansi_term 0.12.1",
+ "atty",
+ "build-helper",
+ "cargo_metadata",
+ "tempfile",
+ "toml",
+ "walkdir",
+ "wasm-gc-api",
+]
 
 [[package]]
 name = "subtle"
@@ -7037,10 +7352,16 @@
 checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
 
 [[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
 name = "target-lexicon"
-version = "0.10.0"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
+checksum = "422045212ea98508ae3d28025bc5aaa2bd4a9cdaecd442a08da2ee620ee9ea95"
 
 [[package]]
 name = "tempfile"
@@ -7752,6 +8073,17 @@
 checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
 
 [[package]]
+name = "walkdir"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
+dependencies = [
+ "same-file",
+ "winapi 0.3.9",
+ "winapi-util",
+]
+
+[[package]]
 name = "want"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -7851,6 +8183,17 @@
 checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
 
 [[package]]
+name = "wasm-gc-api"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9"
+dependencies = [
+ "log",
+ "parity-wasm 0.32.0",
+ "rustc-demangle",
+]
+
+[[package]]
 name = "wasm-timer"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -7875,7 +8218,7 @@
  "memory_units",
  "num-rational",
  "num-traits",
- "parity-wasm",
+ "parity-wasm 0.41.0",
  "wasmi-validation",
 ]
 
@@ -7885,38 +8228,36 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93"
 dependencies = [
- "parity-wasm",
+ "parity-wasm 0.41.0",
 ]
 
 [[package]]
 name = "wasmparser"
-version = "0.57.0"
+version = "0.71.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
-
-[[package]]
-name = "wasmparser"
-version = "0.59.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a950e6a618f62147fd514ff445b2a0b53120d382751960797f85f058c7eda9b9"
+checksum = "89a30c99437829ede826802bfcf28500cf58df00e66cb9114df98813bc145ff1"
 
 [[package]]
 name = "wasmtime"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd3c4f449382779ef6e0a7c3ec6752ae614e20a42e4100000c3efdc973100e2"
+checksum = "7426055cb92bd9a1e9469b48154d8d6119cd8c498c8b70284e420342c05dc45d"
 dependencies = [
  "anyhow",
  "backtrace",
- "cfg-if 0.1.10",
- "lazy_static",
+ "bincode",
+ "cfg-if 1.0.0",
+ "cpp_demangle",
+ "indexmap",
  "libc",
  "log",
  "region",
  "rustc-demangle",
+ "serde",
  "smallvec 1.6.1",
  "target-lexicon",
- "wasmparser 0.59.0",
+ "wasmparser",
+ "wasmtime-cache",
  "wasmtime-environ",
  "wasmtime-jit",
  "wasmtime-profiling",
@@ -7926,73 +8267,100 @@
 ]
 
 [[package]]
+name = "wasmtime-cache"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c01d9287e36921e46f5887a47007824ae5dbb9b7517a2d565660ab4471478709"
+dependencies = [
+ "anyhow",
+ "base64 0.13.0",
+ "bincode",
+ "directories-next",
+ "errno",
+ "file-per-thread-logger",
+ "libc",
+ "log",
+ "serde",
+ "sha2 0.9.3",
+ "toml",
+ "winapi 0.3.9",
+ "zstd",
+]
+
+[[package]]
+name = "wasmtime-cranelift"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4134ed3a4316cd0de0e546c6004850afe472b0fa3fcdc2f2c15f8d449562d962"
+dependencies = [
+ "cranelift-codegen",
+ "cranelift-entity",
+ "cranelift-frontend",
+ "cranelift-wasm",
+ "wasmtime-environ",
+]
+
+[[package]]
 name = "wasmtime-debug"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e634af9067a3af6cf2c7d33dc3b84767ddaf5d010ba68e80eecbcea73d4a349"
+checksum = "e91fa931df6dd8af2b02606307674d3bad23f55473d5f4c809dddf7e4c4dc411"
 dependencies = [
  "anyhow",
- "gimli 0.21.0",
+ "gimli",
  "more-asserts",
- "object 0.20.0",
+ "object 0.22.0",
  "target-lexicon",
  "thiserror",
- "wasmparser 0.59.0",
+ "wasmparser",
  "wasmtime-environ",
 ]
 
 [[package]]
 name = "wasmtime-environ"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f85619a94ee4034bd5bb87fc3dcf71fd2237b81c840809da1201061eec9ab3"
+checksum = "a1098871dc3120aaf8190d79153e470658bb79f63ee9ca31716711e123c28220"
 dependencies = [
  "anyhow",
- "base64 0.12.3",
- "bincode",
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "cranelift-codegen",
  "cranelift-entity",
- "cranelift-frontend",
  "cranelift-wasm",
- "directories 2.0.2",
- "errno",
- "file-per-thread-logger",
+ "gimli",
  "indexmap",
- "libc",
  "log",
  "more-asserts",
- "rayon",
  "serde",
- "sha2 0.8.2",
  "thiserror",
- "toml",
- "wasmparser 0.59.0",
- "winapi 0.3.9",
- "zstd",
+ "wasmparser",
 ]
 
 [[package]]
 name = "wasmtime-jit"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e914c013c7a9f15f4e429d5431f2830fb8adb56e40567661b69c5ec1d645be23"
+checksum = "738bfcd1561ede8bb174215776fd7d9a95d5f0a47ca3deabe0282c55f9a89f68"
 dependencies = [
+ "addr2line",
  "anyhow",
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "cranelift-codegen",
  "cranelift-entity",
  "cranelift-frontend",
  "cranelift-native",
  "cranelift-wasm",
- "gimli 0.21.0",
+ "gimli",
  "log",
  "more-asserts",
- "object 0.20.0",
+ "object 0.22.0",
+ "rayon",
  "region",
+ "serde",
  "target-lexicon",
  "thiserror",
- "wasmparser 0.59.0",
+ "wasmparser",
+ "wasmtime-cranelift",
  "wasmtime-debug",
  "wasmtime-environ",
  "wasmtime-obj",
@@ -8003,13 +8371,13 @@
 
 [[package]]
 name = "wasmtime-obj"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e81d8e02e9bc9fe2da9b6d48bbc217f96e089f7df613f11a28a3958abc44641e"
+checksum = "3e96d77f1801131c5e86d93e42a3cf8a35402107332c202c245c83f34888a906"
 dependencies = [
  "anyhow",
  "more-asserts",
- "object 0.20.0",
+ "object 0.22.0",
  "target-lexicon",
  "wasmtime-debug",
  "wasmtime-environ",
@@ -8017,16 +8385,16 @@
 
 [[package]]
 name = "wasmtime-profiling"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e8d4d1af8dd5f7096cfcc89dd668d358e52980c38cce199643372ffd6590e27"
+checksum = "60bb672c9d894776d7b9250dd9b4fe890f8760201ee4f53e5f2da772b6c4debb"
 dependencies = [
  "anyhow",
- "cfg-if 0.1.10",
- "gimli 0.21.0",
+ "cfg-if 1.0.0",
+ "gimli",
  "lazy_static",
  "libc",
- "object 0.19.0",
+ "object 0.22.0",
  "scroll",
  "serde",
  "target-lexicon",
@@ -8036,19 +8404,20 @@
 
 [[package]]
 name = "wasmtime-runtime"
-version = "0.19.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a25f140bbbaadb07c531cba99ce1a966dba216138dc1b2a0ddecec851a01a93"
+checksum = "a978086740949eeedfefcee667b57a9e98d9a7fc0de382fcfa0da30369e3530d"
 dependencies = [
  "backtrace",
  "cc",
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "indexmap",
  "lazy_static",
  "libc",
  "log",
- "memoffset 0.5.6",
+ "memoffset 0.6.1",
  "more-asserts",
+ "psm",
  "region",
  "thiserror",
  "wasmtime-environ",
@@ -8184,6 +8553,12 @@
 ]
 
 [[package]]
+name = "wyz"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
+
+[[package]]
 name = "x25519-dalek"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
modifiedDockerfilediffbeforeafterboth
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,8 +3,8 @@
 FROM phusion/baseimage:18.04-1.0.0 as builder
 LABEL maintainer="UniqueNetwork.io"
 
-ENV WASM_TOOLCHAIN=nightly-2021-01-27
-ENV NATIVE_TOOLCHAIN=1.49.0
+ENV WASM_TOOLCHAIN=nightly-2021-03-01
+# ENV NATIVE_TOOLCHAIN=1.50.0
 
 ARG PROFILE=release
 
@@ -25,10 +25,10 @@
 RUN export PATH="/cargo-home/bin:$PATH" && \
     export CARGO_HOME="/cargo-home" && \
 	rustup toolchain uninstall $(rustup toolchain list) && \
-	rustup toolchain install $NATIVE_TOOLCHAIN && \
+	# rustup toolchain install $NATIVE_TOOLCHAIN && \
 	rustup toolchain install $WASM_TOOLCHAIN && \
 	rustup target add wasm32-unknown-unknown --toolchain $WASM_TOOLCHAIN && \
-	rustup default $NATIVE_TOOLCHAIN && \
+	rustup default $WASM_TOOLCHAIN && \
     rustup target list --installed && \
     rustup show
 
modifiedREADME.mddiffbeforeafterboth
--- a/README.md
+++ b/README.md
@@ -63,18 +63,17 @@
 
 2. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall <toolchain>`.
 
-3. Install stable toolchain 1.49.0 and make it default, install nightly 2021-01-27:
+3. Install install nightly 2021-03-01 and make it default:
 
 ```bash
-rustup toolchain install 1.49.0
-rustup toolchain install nightly-2020-01-27
-rustup default nightly-2021-01-27
+rustup toolchain install nightly-2021-03-01
+rustup default nightly-2021-03-01
 ```
 
 4. Add wasm target for nightly toolchain:
 
 ```bash
-rustup target add wasm32-unknown-unknown --toolchain nightly-2021-01-27
+rustup target add wasm32-unknown-unknown --toolchain nightly-2021-03-01
 ```
 
 5. Build:
modifiednode/Cargo.tomldiffbeforeafterboth
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -1,7 +1,5 @@
-[build-dependencies.substrate-build-script-utils]
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
+[build-dependencies]
+substrate-build-script-utils = '3.0.0'
 
 [[bin]]
 name = 'nft'
@@ -29,36 +27,37 @@
 jsonrpc-core = '15.0.0'
 
 # Substrate dependencies
-nft-runtime = { path = '../runtime', version = '2.1.0' }
-frame-benchmarking = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-frame-benchmarking-cli = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-pallet-transaction-payment-rpc = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-basic-authorship = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-cli = { features = ['wasmtime'], version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sc-client-api = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-consensus = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-consensus-aura = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-executor = { features = ['wasmtime'], version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sc-finality-grandpa = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-rpc = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-rpc-api = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-service = { features = ['wasmtime'], version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sc-transaction-pool = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-api = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-block-builder = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-blockchain = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-consensus = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-consensus-aura = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-core = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-finality-grandpa = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-inherents = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-runtime = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sp-transaction-pool = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-sc-network = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'} 
-substrate-frame-rpc-system = {version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'}
-pallet-contracts-rpc = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique'} 
-sc-keystore = { version = "2.0.0", git = "https://github.com/usetech-llc/substrate.git", branch = 'unique'}
-sc-telemetry = { version = "2.0.0", git = "https://github.com/usetech-llc/substrate.git", branch = 'unique'}
+nft-runtime = { path = '../runtime', version = '3.0.0' }
+frame-benchmarking = '3.0.0'
+frame-benchmarking-cli = '3.0.0'
+pallet-transaction-payment-rpc = '3.0.0'
+sc-basic-authorship = '0.9.0'
+sc-cli = { features = ['wasmtime'], version = '0.9.0' }
+sc-client-api = '3.0.0'
+sc-consensus = '0.9.0'
+sc-consensus-aura = '0.9.0'
+sc-executor = { features = ['wasmtime'], version = '0.9.0' }
+sc-finality-grandpa = '0.9.0'
+
+sc-keystore = '3.0.0'
+sc-rpc = '3.0.0'
+sc-rpc-api = '0.9.0'
+sc-service = { features = ['wasmtime'], version = '0.9.0' }
+sc-transaction-pool = '3.0.0'
+sp-api = '3.0.0'
+sp-block-builder = '3.0.0'
+sp-blockchain = '3.0.0'
+sp-consensus = '0.9.0'
+sp-consensus-aura = '0.9.0'
+sp-core = '3.0.0'
+sp-finality-grandpa = '3.0.0'
+sp-inherents = '3.0.0'
+sp-runtime = '3.0.0'
+sp-transaction-pool = '3.0.0'
+substrate-frame-rpc-system = '3.0.0'
+sc-network = '0.9.0'
+pallet-contracts-rpc = '3.0.0'
+sc-telemetry = '3.0.0'
 
 serde = { version = "1.0.102", features = ["derive"] }
 serde_json = "1.0.41"
modifiednode/src/chain_spec.rsdiffbeforeafterboth
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -15,6 +15,7 @@
 use sp_finality_grandpa::AuthorityId as GrandpaId;
 use sp_runtime::traits::{IdentifyAccount, Verify};
 use serde_json::map::Map;
+// use crate::chain_spec::api::chain_extension::*;
 
 // Note this is the URL for the telemetry server
 //const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
modifiednode/src/service.rsdiffbeforeafterboth
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -16,7 +16,6 @@
 use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};
 use sc_finality_grandpa::SharedVoterState;
 use sc_keystore::LocalKeystore;
-use sc_telemetry::TelemetrySpan;
 
 // Our native executor instance.
 native_executor_instance!(
@@ -42,7 +41,6 @@
 			AuraPair
 		>,
 		sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
-		Option<TelemetrySpan>,
 	)
 >, ServiceError> {
 	if config.keystore_remote.is_some() {
@@ -51,7 +49,7 @@
 	}
 	let inherent_data_providers = sp_inherents::InherentDataProviders::new();
 
-	let (client, backend, keystore_container, task_manager, telemetry_span) =
+	let (client, backend, keystore_container, task_manager) =
 		sc_service::new_full_parts::<Block, RuntimeApi, Executor>(&config)?;
 	let client = Arc::new(client);
 
@@ -59,6 +57,7 @@
 
 	let transaction_pool = sc_transaction_pool::BasicPool::new_full(
 		config.transaction_pool.clone(),
+		config.role.is_authority().into(),
 		config.prometheus_registry(),
 		task_manager.spawn_handle(),
 		client.clone(),
@@ -84,15 +83,9 @@
 	)?;
 
 	Ok(sc_service::PartialComponents {
-		client,
-		backend,
-		task_manager,
-		import_queue,
-		keystore_container,
-		select_chain,
-		transaction_pool,
+		client, backend, task_manager, import_queue, keystore_container, select_chain, transaction_pool,
 		inherent_data_providers,
-		other: (aura_block_import, grandpa_link, telemetry_span),
+		other: (aura_block_import, grandpa_link),
 	})
 }
 
@@ -106,15 +99,9 @@
 /// Builds a new service for a full client.
 pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError> {
 	let sc_service::PartialComponents {
-		client,
-		backend,
-		mut task_manager,
-		import_queue,
-		mut keystore_container,
-		select_chain,
-		transaction_pool,
+		client, backend, mut task_manager, import_queue, mut keystore_container, select_chain, transaction_pool,
 		inherent_data_providers,
-		other: (block_import, grandpa_link, telemetry_span),
+		other: (block_import, grandpa_link),
 	} = new_partial(&config)?;
 
 	if let Some(url) = &config.keystore_remote {
@@ -182,7 +169,6 @@
 			network_status_sinks,
 			system_rpc_tx,
 			config,
-			telemetry_span,
 		},
 	)?;
 
@@ -197,7 +183,7 @@
 		let can_author_with =
 			sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
 
-		let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _,_>(
+		let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _, _>(
 			sc_consensus_aura::slot_duration(&*client)?,
 			client.clone(),
 			select_chain,
@@ -262,10 +248,9 @@
 	network_starter.start_network();
 	Ok(task_manager)
 }
-
 /// Builds a new service for a light client.
 pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError> {
-	let (client, backend, keystore_container, mut task_manager, on_demand, telemetry_span) =
+	let (client, backend, keystore_container, mut task_manager, on_demand) =
 		sc_service::new_light_parts::<Block, RuntimeApi, Executor>(&config)?;
 
 	config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());
@@ -332,7 +317,6 @@
 		network,
 		network_status_sinks,
 		system_rpc_tx,
-		telemetry_span,
 	})?;
 
 	network_starter.start_network();
modifiedpallets/nft/Cargo.tomldiffbeforeafterboth
--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -6,7 +6,7 @@
 license = 'Unlicense'
 name = 'pallet-nft'
 repository = 'https://github.com/substrate-developer-hub/nft/'
-version = '2.1.0'
+version = '3.0.0'
 
 [package.metadata.docs.rs]
 targets = ['x86_64-unknown-linux-gnu']
@@ -16,101 +16,35 @@
 default-features = false
 features = ['derive']
 package = 'parity-scale-codec'
-version = '1.3.6'
-
-[dependencies.frame-support]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
-
-[dependencies.frame-system]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
-
-[dev-dependencies.sp-core]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
-
-[dev-dependencies.sp-io]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
+version = '2.0.0'
 
-[dependencies.sp-runtime]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
-	
 [dependencies]
-# third-party dependencies
-serde = { version = "1.0.102", features = ["derive"] }
-log = "0.4.8"
-
-[dependencies.sp-std]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-version = '2.0.1'
-
-[dependencies.transaction-payment]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-package = 'pallet-transaction-payment'
-branch = 'unique'
-version = '2.0.1'
-
-[dependencies.frame-benchmarking]
-version = "2.0.1"
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'unique'
-optional = true
-
-[dependencies.pallet-contracts]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-package = 'pallet-contracts'
-branch = 'unique'
-version = '2.0.1'
+serde = { version = "1.0.119" }
+frame-support = { default-features = false, version = '3.0.0' }
+frame-system = { default-features = false, version = '3.0.0' }
+pallet-balances = { default-features = false, version = '3.0.0' }
+pallet-timestamp = { default-features = false, version = '3.0.0' }
+pallet-randomness-collective-flip = { default-features = false, version = '3.0.0' }
+sp-std = { default-features = false, version = '3.0.0' }
+frame-benchmarking = { default-features = false, version = '3.0.0', optional = true }
+sp-core = { default-features = false, version = '3.0.0' }
+sp-io = { default-features = false, version = '3.0.0' }
+sp-runtime = { default-features = false, version = '3.0.0' }
+pallet-contracts = { default-features = false, version = '3.0.0' }
+pallet-transaction-payment = { default-features = false, version = "3.0.0" }
 
-[dependencies.pallet-balances]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-package = 'pallet-balances'
-branch = 'unique'
-version = '2.0.1'
-
-[dependencies.pallet-timestamp]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-package = 'pallet-timestamp'
-branch = 'unique'
-version = '2.0.1'
-
-[dependencies.pallet-randomness-collective-flip]
-default-features = false
-git = 'https://github.com/usetech-llc/substrate.git'
-package = 'pallet-randomness-collective-flip'
-branch = 'unique'
-version = '2.0.1'
-
 [features]
 default = ['std']
 std = [
     'codec/std',
-    "serde/std",
+    'serde/std',
     'frame-support/std',
     'frame-system/std',
     'pallet-balances/std',
     'pallet-timestamp/std',
+    'pallet-contracts/std',
     'pallet-randomness-collective-flip/std',
+    'pallet-transaction-payment/std',
     'sp-std/std',
     'sp-runtime/std',
     'frame-benchmarking/std',
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
before · pallets/nft/src/lib.rs
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56#![recursion_limit = "1024"]78#![cfg_attr(not(feature = "std"), no_std)]910#[cfg(feature = "std")]11pub use std::*;1213#[cfg(feature = "std")]14pub use serde::*;1516use codec::{Decode, Encode};17pub use frame_support::{18    construct_runtime, decl_event, decl_module, decl_storage, decl_error,19    dispatch::DispatchResult,20    ensure, fail, parameter_types,21    traits::{22        Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,23        Randomness, IsSubType,24    },25    weights::{26        constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},27        DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,28        WeightToFeePolynomial, DispatchClass,29    },30    StorageValue,31};3233use frame_system::{self as system, ensure_signed, ensure_root};34use sp_runtime::sp_std::prelude::Vec;35use sp_runtime::{36    traits::{37        DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SaturatedConversion, SignedExtension, Zero,38    },39    transaction_validity::{40        TransactionPriority, InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,41    },42    FixedPointOperand, FixedU128,43};44use sp_runtime::traits::StaticLookup;45use pallet_contracts::chain_extension::UncheckedFrom;46use transaction_payment::OnChargeTransaction;4748#[cfg(test)]49mod mock;5051#[cfg(test)]52mod tests;5354mod default_weights;5556pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;57pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;58pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;59pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;6061// Structs62// #region6364pub type CollectionId = u32;65pub type TokenId = u32;66pub type DecimalPoints = u8;6768#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]69#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]70pub enum CollectionMode {71    Invalid,72    NFT,73    // decimal points74    Fungible(DecimalPoints),75    ReFungible,76}7778impl Default for CollectionMode {79    fn default() -> Self {80        Self::Invalid81    }82}8384impl Into<u8> for CollectionMode {85    fn into(self) -> u8 {86        match self {87            CollectionMode::Invalid => 0,88            CollectionMode::NFT => 1,89            CollectionMode::Fungible(_) => 2,90            CollectionMode::ReFungible => 3,91        }92    }93}9495#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]96#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]97pub enum AccessMode {98    Normal,99    WhiteList,100}101impl Default for AccessMode {102    fn default() -> Self {103        Self::Normal104    }105}106107#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]108#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]109pub enum SchemaVersion {110    ImageURL,111    Unique,112}113impl Default for SchemaVersion {114    fn default() -> Self {115        Self::ImageURL116    }117}118119#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]120#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]121pub struct Ownership<AccountId> {122    pub owner: AccountId,123    pub fraction: u128,124}125126#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]127#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]128pub struct CollectionType<AccountId> {129    pub owner: AccountId,130    pub mode: CollectionMode,131    pub access: AccessMode,132    pub decimal_points: DecimalPoints,133    pub name: Vec<u16>,        // 64 include null escape char134    pub description: Vec<u16>, // 256 include null escape char135    pub token_prefix: Vec<u8>, // 16 include null escape char136    pub mint_mode: bool,137    pub offchain_schema: Vec<u8>,138    pub schema_version: SchemaVersion,139    pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender140    pub sponsor_confirmed: bool, // False if sponsor address has not yet confirmed sponsorship. True otherwise.141    pub limits: CollectionLimits, // Collection private restrictions 142    pub variable_on_chain_schema: Vec<u8>, //143    pub const_on_chain_schema: Vec<u8>, //144}145146#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]147#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]148pub struct NftItemType<AccountId> {149    pub owner: AccountId,150    pub const_data: Vec<u8>,151    pub variable_data: Vec<u8>,152}153154#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]155#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]156pub struct FungibleItemType {157    pub value: u128,158}159160#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]161#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]162pub struct ReFungibleItemType<AccountId> {163    pub owner: Vec<Ownership<AccountId>>,164    pub const_data: Vec<u8>,165    pub variable_data: Vec<u8>,166}167168// #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]169// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]170// pub struct VestingItem<AccountId, Moment> {171//     pub sender: AccountId,172//     pub recipient: AccountId,173//     pub collection_id: CollectionId,174//     pub item_id: TokenId,175//     pub amount: u64,176//     pub vesting_date: Moment,177// }178179#[derive(Encode, Decode, Debug, Clone, PartialEq)]180#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]181pub struct CollectionLimits {182    pub account_token_ownership_limit: u32,183    pub sponsored_data_size: u32,184    pub token_limit: u32,185186    // Timeouts for item types in passed blocks187    pub sponsor_transfer_timeout: u32,188    pub owner_can_transfer: bool,189    pub owner_can_destroy: bool,190}191192impl Default for CollectionLimits {193    fn default() -> CollectionLimits {194        CollectionLimits { 195            account_token_ownership_limit: 10_000_000, 196            token_limit: u32::max_value(),197            sponsored_data_size: u32::MAX,198            sponsor_transfer_timeout: 14400,199            owner_can_transfer: true,200            owner_can_destroy: true201        }202    }203}204205#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]206#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]207pub struct ChainLimits {208    pub collection_numbers_limit: u32,209    pub account_token_ownership_limit: u32,210    pub collections_admins_limit: u64,211    pub custom_data_limit: u32,212213    // Timeouts for item types in passed blocks214    pub nft_sponsor_transfer_timeout: u32,215    pub fungible_sponsor_transfer_timeout: u32,216    pub refungible_sponsor_transfer_timeout: u32,217218    // Schema limits219    pub offchain_schema_limit: u32,220    pub variable_on_chain_schema_limit: u32,221    pub const_on_chain_schema_limit: u32,222}223224pub trait WeightInfo {225	fn create_collection() -> Weight;226	fn destroy_collection() -> Weight;227	fn add_to_white_list() -> Weight;228	fn remove_from_white_list() -> Weight;229    fn set_public_access_mode() -> Weight;230    fn set_mint_permission() -> Weight;231    fn change_collection_owner() -> Weight;232    fn add_collection_admin() -> Weight;233    fn remove_collection_admin() -> Weight;234    fn set_collection_sponsor() -> Weight;235    fn confirm_sponsorship() -> Weight;236    fn remove_collection_sponsor() -> Weight;237    fn create_item(s: usize) -> Weight;238    fn burn_item() -> Weight;239    fn transfer() -> Weight;240    fn approve() -> Weight;241    fn transfer_from() -> Weight;242    fn set_offchain_schema() -> Weight;243    fn set_const_on_chain_schema() -> Weight;244    fn set_variable_on_chain_schema() -> Weight;245    fn set_variable_meta_data() -> Weight;246    fn enable_contract_sponsoring() -> Weight;247    fn set_schema_version() -> Weight;248    fn set_chain_limits() -> Weight;249    fn set_contract_sponsoring_rate_limit() -> Weight;250    fn toggle_contract_white_list() -> Weight;251    fn add_to_contract_white_list() -> Weight;252    fn remove_from_contract_white_list() -> Weight;253    fn set_collection_limits() -> Weight;254}255256#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]257#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]258pub struct CreateNftData {259    pub const_data: Vec<u8>,260    pub variable_data: Vec<u8>,261}262263#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]264#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]265pub struct CreateFungibleData {266    pub value: u128,267}268269#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]270#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]271pub struct CreateReFungibleData {272    pub const_data: Vec<u8>,273    pub variable_data: Vec<u8>,274    pub pieces: u128,275}276277#[derive(Encode, Decode, Debug, Clone, PartialEq)]278#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]279pub enum CreateItemData {280    NFT(CreateNftData),281    Fungible(CreateFungibleData),282    ReFungible(CreateReFungibleData),283}284285impl CreateItemData {286    pub fn len(&self) -> usize {287        let len = match self {288            CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),289            CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),290            _ => 0291        };292        293        return len;294    }295}296297impl From<CreateNftData> for CreateItemData {298    fn from(item: CreateNftData) -> Self {299        CreateItemData::NFT(item)300    }301}302303impl From<CreateReFungibleData> for CreateItemData {304    fn from(item: CreateReFungibleData) -> Self {305        CreateItemData::ReFungible(item)306    }307}308309impl From<CreateFungibleData> for CreateItemData {310    fn from(item: CreateFungibleData) -> Self {311        CreateItemData::Fungible(item)312    }313}314315316decl_error! {317	/// Error for non-fungible-token module.318	pub enum Error for Module<T: Config> {319        /// Total collections bound exceeded.320        TotalCollectionsLimitExceeded,321		/// Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.322        CollectionDecimalPointLimitExceeded, 323        /// Collection name can not be longer than 63 char.324        CollectionNameLimitExceeded, 325        /// Collection description can not be longer than 255 char.326        CollectionDescriptionLimitExceeded, 327        /// Token prefix can not be longer than 15 char.328        CollectionTokenPrefixLimitExceeded,329        /// This collection does not exist.330        CollectionNotFound,331        /// Item not exists.332        TokenNotFound,333        /// Admin not found334        AdminNotFound,335        /// Arithmetic calculation overflow.336        NumOverflow,       337        /// Account already has admin role.338        AlreadyAdmin,  339        /// You do not own this collection.340        NoPermission,341        /// This address is not set as sponsor, use setCollectionSponsor first.342        ConfirmUnsetSponsorFail,343        /// Collection is not in mint mode.344        PublicMintingNotAllowed,345        /// Sender parameter and item owner must be equal.346        MustBeTokenOwner,347        /// Item balance not enough.348        TokenValueTooLow,349        /// Size of item is too large.350        NftSizeLimitExceeded,351        /// No approve found352        ApproveNotFound,353        /// Requested value more than approved.354        TokenValueNotEnough,355        /// Only approved addresses can call this method.356        ApproveRequired,357        /// Address is not in white list.358        AddresNotInWhiteList,359        /// Number of collection admins bound exceeded.360        CollectionAdminsLimitExceeded,361        /// Owned tokens by a single address bound exceeded.362        AddressOwnershipLimitExceeded,363        /// Length of items properties must be greater than 0.364        EmptyArgument,365        /// const_data exceeded data limit.366        TokenConstDataLimitExceeded,367        /// variable_data exceeded data limit.368        TokenVariableDataLimitExceeded,369        /// Not NFT item data used to mint in NFT collection.370        NotNftDataUsedToMintNftCollectionToken,371        /// Not Fungible item data used to mint in Fungible collection.372        NotFungibleDataUsedToMintFungibleCollectionToken,373        /// Not Re Fungible item data used to mint in Re Fungible collection.374        NotReFungibleDataUsedToMintReFungibleCollectionToken,375        /// Unexpected collection type.376        UnexpectedCollectionType,377        /// Can't store metadata in fungible tokens.378        CantStoreMetadataInFungibleTokens,379        /// Collection token limit exceeded380        CollectionTokenLimitExceeded,381        /// Account token limit exceeded per collection382        AccountTokenLimitExceeded,383        /// Collection limit bounds per collection exceeded384        CollectionLimitBoundsExceeded,385        /// Tried to enable permissions which are only permitted to be disabled386        OwnerPermissionsCantBeReverted,387        /// Schema data size limit bound exceeded388        SchemaDataLimitExceeded,389        /// Maximum refungibility exceeded390        WrongRefungiblePieces391	}392}393394pub trait Config: system::Config + Sized + transaction_payment::Config + pallet_contracts::Config {395    type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;396397    /// Weight information for extrinsics in this pallet.398	type WeightInfo: WeightInfo;399}400401#[cfg(feature = "runtime-benchmarks")]402mod benchmarking;403404// #endregion405406decl_storage! {407    trait Store for Module<T: Config> as Nft {408409        // Private members410        NextCollectionID: CollectionId;411        CreatedCollectionCount: u32;412        ChainVersion: u64;413        ItemListIndex: map hasher(identity) CollectionId => TokenId;414415        // Chain limits struct416        pub ChainLimit get(fn chain_limit) config(): ChainLimits;417418        // Bound counters419        CollectionCount: u32;420        pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;421422        // Basic collections423        pub Collection get(fn collection) config(): map hasher(identity) CollectionId => CollectionType<T::AccountId>;424        pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;425        pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;426427        /// Balance owner per collection map428        pub Balance get(fn balance_count): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => u128;429430        /// second parameter: item id + owner account id + spender account id431        pub Allowances get(fn approved): double_map hasher(identity) CollectionId, hasher(twox_64_concat) (TokenId, T::AccountId, T::AccountId) => u128;432433        /// Item collections434        pub NftItemList get(fn nft_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => NftItemType<T::AccountId>;435        pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => FungibleItemType;436        pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => ReFungibleItemType<T::AccountId>;437438        /// Index list439        pub AddressTokens get(fn address_tokens): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => Vec<TokenId>;440441        /// Tokens transfer baskets442        pub CreateItemBasket get(fn create_item_basket): map hasher(twox_64_concat) (CollectionId, T::AccountId) => T::BlockNumber;443        pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;444        pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;445        pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;446447        // Contract Sponsorship and Ownership448        pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;449        pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;450        pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;451        pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;452        pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 453        pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId => bool; 454    }455    add_extra_genesis {456        build(|config: &GenesisConfig<T>| {457            // Modification of storage458            for (_num, _c) in &config.collection {459                <Module<T>>::init_collection(_c);460            }461462            for (_num, _c, _i) in &config.nft_item_id {463                <Module<T>>::init_nft_token(*_c, _i);464            }465466            for (collection_id, account_id, fungible_item) in &config.fungible_item_id {467                <Module<T>>::init_fungible_token(*collection_id, account_id, fungible_item);468            }469470            for (_num, _c, _i) in &config.refungible_item_id {471                <Module<T>>::init_refungible_token(*_c, _i);472            }473        })474    }475}476477decl_event!(478    pub enum Event<T>479    where480        AccountId = <T as system::Config>::AccountId,481    {482        /// New collection was created483        /// 484        /// # Arguments485        /// 486        /// * collection_id: Globally unique identifier of newly created collection.487        /// 488        /// * mode: [CollectionMode] converted into u8.489        /// 490        /// * account_id: Collection owner.491        Created(CollectionId, u8, AccountId),492493        /// New item was created.494        /// 495        /// # Arguments496        /// 497        /// * collection_id: Id of the collection where item was created.498        /// 499        /// * item_id: Id of an item. Unique within the collection.500        ///501        /// * recipient: Owner of newly created item 502        ItemCreated(CollectionId, TokenId, AccountId),503504        /// Collection item was burned.505        /// 506        /// # Arguments507        /// 508        /// collection_id.509        /// 510        /// item_id: Identifier of burned NFT.511        ItemDestroyed(CollectionId, TokenId),512513        /// Item was transferred514        ///515        /// * collection_id: Id of collection to which item is belong516        ///517        /// * item_id: Id of an item518        ///519        /// * sender: Original owner of item520        ///521        /// * recipient: New owner of item522        ///523        /// * amount: Always 1 for NFT524        Transfer(CollectionId, TokenId, AccountId, AccountId, u128),525    }526);527528decl_module! {529    pub struct Module<T: Config> for enum Call 530    where 531        origin: T::Origin532    {533        fn deposit_event() = default;534        type Error = Error<T>;535536        fn on_initialize(now: T::BlockNumber) -> Weight {537538            if ChainVersion::get() < 2539            {540                let value = NextCollectionID::get();541                CreatedCollectionCount::put(value);542                ChainVersion::put(2);543            }544545            0546        }547548        /// This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner and admin of the collection are set to the address that signed the transaction. Both addresses can be changed later.549        /// 550        /// # Permissions551        /// 552        /// * Anyone.553        /// 554        /// # Arguments555        /// 556        /// * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.557        /// 558        /// * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.559        /// 560        /// * token_prefix: UTF-8 string with token prefix.561        /// 562        /// * mode: [CollectionMode] collection type and type dependent data.563        // returns collection ID564        #[weight = <T as Config>::WeightInfo::create_collection()]565        pub fn create_collection(origin,566                                 collection_name: Vec<u16>,567                                 collection_description: Vec<u16>,568                                 token_prefix: Vec<u8>,569                                 mode: CollectionMode) -> DispatchResult {570571            // Anyone can create a collection572            let who = ensure_signed(origin)?;573574            let decimal_points = match mode {575                CollectionMode::Fungible(points) => points,576                _ => 0577            };578579            let chain_limit = ChainLimit::get();580581            // bound Total number of collections582            ensure!(CollectionCount::get() < chain_limit.collection_numbers_limit, Error::<T>::TotalCollectionsLimitExceeded);583584            // check params585            ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);586            ensure!(collection_name.len() <= 64, Error::<T>::CollectionNameLimitExceeded);587            ensure!(collection_description.len() <= 256, Error::<T>::CollectionDescriptionLimitExceeded);588            ensure!(token_prefix.len() <= 16, Error::<T>::CollectionTokenPrefixLimitExceeded);589590            // Generate next collection ID591            let next_id = CreatedCollectionCount::get()592                .checked_add(1)593                .ok_or(Error::<T>::NumOverflow)?;594595            // bound counter596            let total = CollectionCount::get()597                .checked_add(1)598                .ok_or(Error::<T>::NumOverflow)?;599600            CreatedCollectionCount::put(next_id);601            CollectionCount::put(total);602603            let limits = CollectionLimits {604                sponsored_data_size: chain_limit.custom_data_limit,605                ..Default::default()606            };607608            // Create new collection609            let new_collection = CollectionType {610                owner: who.clone(),611                name: collection_name,612                mode: mode.clone(),613                mint_mode: false,614                access: AccessMode::Normal,615                description: collection_description,616                decimal_points: decimal_points,617                token_prefix: token_prefix,618                offchain_schema: Vec::new(),619                schema_version: SchemaVersion::ImageURL,620                sponsor: T::AccountId::default(),621                sponsor_confirmed: false,622                variable_on_chain_schema: Vec::new(),623                const_on_chain_schema: Vec::new(),624                limits,625            };626627            // Add new collection to map628            <Collection<T>>::insert(next_id, new_collection);629630            // call event631            Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));632633            Ok(())634        }635636        /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.637        /// 638        /// # Permissions639        /// 640        /// * Collection Owner.641        /// 642        /// # Arguments643        /// 644        /// * collection_id: collection to destroy.645        #[weight = <T as Config>::WeightInfo::destroy_collection()]646        pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {647648            let sender = ensure_signed(origin)?;649            Self::check_owner_permissions(collection_id, sender)?;650651            let target_collection = <Collection<T>>::get(collection_id);652            if !target_collection.limits.owner_can_destroy {653                fail!(Error::<T>::NoPermission);654            }655656            <AddressTokens<T>>::remove_prefix(collection_id);657            <Allowances<T>>::remove_prefix(collection_id);658            <Balance<T>>::remove_prefix(collection_id);659            <ItemListIndex>::remove(collection_id);660            <AdminList<T>>::remove(collection_id);661            <Collection<T>>::remove(collection_id);662            <WhiteList<T>>::remove_prefix(collection_id);663664            <NftItemList<T>>::remove_prefix(collection_id);665            <FungibleItemList<T>>::remove_prefix(collection_id);666            <ReFungibleItemList<T>>::remove_prefix(collection_id);667668            <NftTransferBasket<T>>::remove_prefix(collection_id);669            <FungibleTransferBasket<T>>::remove_prefix(collection_id);670            <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);671672            if CollectionCount::get() > 0673            {674                // bound couter675                let total = CollectionCount::get()676                    .checked_sub(1)677                    .ok_or(Error::<T>::NumOverflow)?;678679                CollectionCount::put(total);680            }681682            Ok(())683        }684685        /// Add an address to white list.686        /// 687        /// # Permissions688        /// 689        /// * Collection Owner690        /// * Collection Admin691        /// 692        /// # Arguments693        /// 694        /// * collection_id.695        /// 696        /// * address.697        #[weight = <T as Config>::WeightInfo::add_to_white_list()]698        pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{699700            let sender = ensure_signed(origin)?;701            Self::check_owner_or_admin_permissions(collection_id, sender)?;702703            <WhiteList<T>>::insert(collection_id, address, true);704            705            Ok(())706        }707708        /// Remove an address from white list.709        /// 710        /// # Permissions711        /// 712        /// * Collection Owner713        /// * Collection Admin714        /// 715        /// # Arguments716        /// 717        /// * collection_id.718        /// 719        /// * address.720        #[weight = <T as Config>::WeightInfo::remove_from_white_list()]721        pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{722723            let sender = ensure_signed(origin)?;724            Self::check_owner_or_admin_permissions(collection_id, sender)?;725726            <WhiteList<T>>::remove(collection_id, address);727728            Ok(())729        }730731        /// Toggle between normal and white list access for the methods with access for `Anyone`.732        /// 733        /// # Permissions734        /// 735        /// * Collection Owner.736        /// 737        /// # Arguments738        /// 739        /// * collection_id.740        /// 741        /// * mode: [AccessMode]742        #[weight = <T as Config>::WeightInfo::set_public_access_mode()]743        pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult744        {745            let sender = ensure_signed(origin)?;746747            Self::check_owner_permissions(collection_id, sender)?;748            let mut target_collection = <Collection<T>>::get(collection_id);749            target_collection.access = mode;750            <Collection<T>>::insert(collection_id, target_collection);751752            Ok(())753        }754755        /// Allows Anyone to create tokens if:756        /// * White List is enabled, and757        /// * Address is added to white list, and758        /// * This method was called with True parameter759        /// 760        /// # Permissions761        /// * Collection Owner762        ///763        /// # Arguments764        /// 765        /// * collection_id.766        /// 767        /// * mint_permission: Boolean parameter. If True, allows minting to Anyone with conditions above.768        #[weight = <T as Config>::WeightInfo::set_mint_permission()]769        pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult770        {771            let sender = ensure_signed(origin)?;772773            Self::check_owner_permissions(collection_id, sender)?;774            let mut target_collection = <Collection<T>>::get(collection_id);775            target_collection.mint_mode = mint_permission;776            <Collection<T>>::insert(collection_id, target_collection);777778            Ok(())779        }780781        /// Change the owner of the collection.782        /// 783        /// # Permissions784        /// 785        /// * Collection Owner.786        /// 787        /// # Arguments788        /// 789        /// * collection_id.790        /// 791        /// * new_owner.792        #[weight = <T as Config>::WeightInfo::change_collection_owner()]793        pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {794795            let sender = ensure_signed(origin)?;796            Self::check_owner_permissions(collection_id, sender)?;797            let mut target_collection = <Collection<T>>::get(collection_id);798            target_collection.owner = new_owner;799            <Collection<T>>::insert(collection_id, target_collection);800801            Ok(())802        }803804        /// Adds an admin of the Collection.805        /// NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership. 806        /// 807        /// # Permissions808        /// 809        /// * Collection Owner.810        /// * Collection Admin.811        /// 812        /// # Arguments813        /// 814        /// * collection_id: ID of the Collection to add admin for.815        /// 816        /// * new_admin_id: Address of new admin to add.817        #[weight = <T as Config>::WeightInfo::add_collection_admin()]818        pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::AccountId) -> DispatchResult {819820            let sender = ensure_signed(origin)?;821            Self::check_owner_or_admin_permissions(collection_id, sender)?;822            let mut admin_arr: Vec<T::AccountId> = Vec::new();823824            if <AdminList<T>>::contains_key(collection_id)825            {826                admin_arr = <AdminList<T>>::get(collection_id);827                ensure!(!admin_arr.contains(&new_admin_id), Error::<T>::AlreadyAdmin);828            }829830            // Number of collection admins831            ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, Error::<T>::CollectionAdminsLimitExceeded);832833            admin_arr.push(new_admin_id);834            <AdminList<T>>::insert(collection_id, admin_arr);835836            Ok(())837        }838839        /// Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.840        ///841        /// # Permissions842        /// 843        /// * Collection Owner.844        /// * Collection Admin.845        /// 846        /// # Arguments847        /// 848        /// * collection_id: ID of the Collection to remove admin for.849        /// 850        /// * account_id: Address of admin to remove.851        #[weight = <T as Config>::WeightInfo::remove_collection_admin()]852        pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::AccountId) -> DispatchResult {853854            let sender = ensure_signed(origin)?;855            Self::check_owner_or_admin_permissions(collection_id, sender)?;856            ensure!(<AdminList<T>>::contains_key(collection_id), Error::<T>::AdminNotFound);857858            let mut admin_arr = <AdminList<T>>::get(collection_id);859            admin_arr.retain(|i| *i != account_id);860            <AdminList<T>>::insert(collection_id, admin_arr);861862            Ok(())863        }864865        /// # Permissions866        /// 867        /// * Collection Owner868        /// 869        /// # Arguments870        /// 871        /// * collection_id.872        /// 873        /// * new_sponsor.874        #[weight = <T as Config>::WeightInfo::set_collection_sponsor()]875        pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {876877            let sender = ensure_signed(origin)?;878            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);879880            let mut target_collection = <Collection<T>>::get(collection_id);881            ensure!(sender == target_collection.owner, Error::<T>::NoPermission);882883            target_collection.sponsor = new_sponsor;884            target_collection.sponsor_confirmed = false;885            <Collection<T>>::insert(collection_id, target_collection);886887            Ok(())888        }889890        /// # Permissions891        /// 892        /// * Sponsor.893        /// 894        /// # Arguments895        /// 896        /// * collection_id.897        #[weight = <T as Config>::WeightInfo::confirm_sponsorship()]898        pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {899900            let sender = ensure_signed(origin)?;901            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);902903            let mut target_collection = <Collection<T>>::get(collection_id);904            ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);905906            target_collection.sponsor_confirmed = true;907            <Collection<T>>::insert(collection_id, target_collection);908909            Ok(())910        }911912        /// Switch back to pay-per-own-transaction model.913        ///914        /// # Permissions915        ///916        /// * Collection owner.917        /// 918        /// # Arguments919        /// 920        /// * collection_id.921        #[weight = <T as Config>::WeightInfo::remove_collection_sponsor()]922        pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {923924            let sender = ensure_signed(origin)?;925            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);926927            let mut target_collection = <Collection<T>>::get(collection_id);928            ensure!(sender == target_collection.owner, Error::<T>::NoPermission);929930            target_collection.sponsor = T::AccountId::default();931            target_collection.sponsor_confirmed = false;932            <Collection<T>>::insert(collection_id, target_collection);933934            Ok(())935        }936937        /// This method creates a concrete instance of NFT Collection created with CreateCollection method.938        /// 939        /// # Permissions940        /// 941        /// * Collection Owner.942        /// * Collection Admin.943        /// * Anyone if944        ///     * White List is enabled, and945        ///     * Address is added to white list, and946        ///     * MintPermission is enabled (see SetMintPermission method)947        /// 948        /// # Arguments949        /// 950        /// * collection_id: ID of the collection.951        /// 952        /// * owner: Address, initial owner of the NFT.953        ///954        /// * data: Token data to store on chain.955        // #[weight =956        // (130_000_000 as Weight)957        // .saturating_add((2135 as Weight).saturating_mul((properties.len() as u64) as Weight))958        // .saturating_add(RocksDbWeight::get().reads(10 as Weight))959        // .saturating_add(RocksDbWeight::get().writes(8 as Weight))]960961        #[weight = <T as Config>::WeightInfo::create_item(data.len())]962        pub fn create_item(origin, collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {963964            let sender = ensure_signed(origin)?;965966            Self::collection_exists(collection_id)?;967968            let target_collection = <Collection<T>>::get(collection_id);969970            Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;971            Self::validate_create_item_args(&target_collection, &data)?;972            Self::create_item_no_validation(collection_id, owner, data)?;973974            Ok(())975        }976977        /// This method creates multiple instances of NFT Collection created with CreateCollection method.978        /// 979        /// # Permissions980        /// 981        /// * Collection Owner.982        /// * Collection Admin.983        /// * Anyone if984        ///     * White List is enabled, and985        ///     * Address is added to white list, and986        ///     * MintPermission is enabled (see SetMintPermission method)987        /// 988        /// # Arguments989        /// 990        /// * collection_id: ID of the collection.991        /// 992        /// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].993        /// 994        /// * owner: Address, initial owner of the NFT.995        #[weight = <T as Config>::WeightInfo::create_item(items_data.into_iter()996                               .map(|data| { data.len() })997                               .sum())]998        pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::AccountId, items_data: Vec<CreateItemData>) -> DispatchResult {9991000            ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);1001            let sender = ensure_signed(origin)?;10021003            Self::collection_exists(collection_id)?;1004            let target_collection = <Collection<T>>::get(collection_id);10051006            Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;10071008            for data in &items_data {1009                Self::validate_create_item_args(&target_collection, data)?;1010            }1011            for data in &items_data {1012                Self::create_item_no_validation(collection_id, owner.clone(), data.clone())?;1013            }10141015            Ok(())1016        }10171018        /// Destroys a concrete instance of NFT.1019        /// 1020        /// # Permissions1021        /// 1022        /// * Collection Owner.1023        /// * Collection Admin.1024        /// * Current NFT Owner.1025        /// 1026        /// # Arguments1027        /// 1028        /// * collection_id: ID of the collection.1029        /// 1030        /// * item_id: ID of NFT to burn.1031        #[weight = <T as Config>::WeightInfo::burn_item()]1032        pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {10331034            let sender = ensure_signed(origin)?;1035            Self::collection_exists(collection_id)?;10361037            // Transfer permissions check1038            let target_collection = <Collection<T>>::get(collection_id);1039            ensure!(1040                Self::is_item_owner(sender.clone(), collection_id, item_id) ||1041                (1042                    target_collection.limits.owner_can_transfer &&1043                    Self::is_owner_or_admin_permissions(collection_id, sender.clone())1044                ),1045                Error::<T>::NoPermission1046            );10471048            if target_collection.access == AccessMode::WhiteList {1049                Self::check_white_list(collection_id, &sender)?;1050            }10511052            match target_collection.mode1053            {1054                CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,1055                CollectionMode::Fungible(_)  => Self::burn_fungible_item(&sender, collection_id, value)?,1056                CollectionMode::ReFungible  => Self::burn_refungible_item(collection_id, item_id, &sender)?,1057                _ => ()1058            };10591060            // call event1061            Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));10621063            Ok(())1064        }10651066        /// Change ownership of the token.1067        /// 1068        /// # Permissions1069        /// 1070        /// * Collection Owner1071        /// * Collection Admin1072        /// * Current NFT owner1073        ///1074        /// # Arguments1075        /// 1076        /// * recipient: Address of token recipient.1077        /// 1078        /// * collection_id.1079        /// 1080        /// * item_id: ID of the item1081        ///     * Non-Fungible Mode: Required.1082        ///     * Fungible Mode: Ignored.1083        ///     * Re-Fungible Mode: Required.1084        /// 1085        /// * value: Amount to transfer.1086        ///     * Non-Fungible Mode: Ignored1087        ///     * Fungible Mode: Must specify transferred amount1088        ///     * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)1089        #[weight = <T as Config>::WeightInfo::transfer()]1090        pub fn transfer(origin, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {1091            let sender = ensure_signed(origin)?;1092            Self::transfer_internal(sender, recipient, collection_id, item_id, value)1093        }10941095        /// Set, change, or remove approved address to transfer the ownership of the NFT.1096        /// 1097        /// # Permissions1098        /// 1099        /// * Collection Owner1100        /// * Collection Admin1101        /// * Current NFT owner1102        /// 1103        /// # Arguments1104        /// 1105        /// * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).1106        /// 1107        /// * collection_id.1108        /// 1109        /// * item_id: ID of the item.1110        #[weight = <T as Config>::WeightInfo::approve()]1111        pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {11121113            let sender = ensure_signed(origin)?;11141115            Self::collection_exists(collection_id)?;1116            Self::token_exists(collection_id, item_id, &sender)?;11171118            // Transfer permissions check1119            let target_collection = <Collection<T>>::get(collection_id);11201121            let bypasses_limits = target_collection.limits.owner_can_transfer &&1122                Self::is_owner_or_admin_permissions(1123                    collection_id,1124                    sender.clone(),1125                );11261127            let allowance_limit = if bypasses_limits {1128                None1129            } else if let Some(amount) = Self::owned_amount(1130                sender.clone(),1131                collection_id,1132                item_id,1133            ) {1134                Some(amount)1135            } else {1136                fail!(Error::<T>::NoPermission);1137            };11381139            if target_collection.access == AccessMode::WhiteList {1140                Self::check_white_list(collection_id, &sender)?;1141                Self::check_white_list(collection_id, &spender)?;1142            }11431144            let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));1145            let mut allowance: u128 = amount;1146            if allowance_exists {1147                allowance += <Allowances<T>>::get(collection_id, (item_id, &sender, &spender));1148            }1149            if let Some(limit) = allowance_limit {1150                ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1151            }1152            <Allowances<T>>::insert(collection_id, (item_id, sender.clone(), spender.clone()), allowance);11531154            Ok(())1155        }1156        1157        /// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.1158        /// 1159        /// # Permissions1160        /// * Collection Owner1161        /// * Collection Admin1162        /// * Current NFT owner1163        /// * Address approved by current NFT owner1164        /// 1165        /// # Arguments1166        /// 1167        /// * from: Address that owns token.1168        /// 1169        /// * recipient: Address of token recipient.1170        /// 1171        /// * collection_id.1172        /// 1173        /// * item_id: ID of the item.1174        /// 1175        /// * value: Amount to transfer.1176        #[weight = <T as Config>::WeightInfo::transfer_from()]1177        pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {11781179            let sender = ensure_signed(origin)?;1180            let mut appoved_transfer = false;11811182            // Check approval1183            let mut approval: u128 = 0;1184            if <Allowances<T>>::contains_key(collection_id, (item_id, &from, &sender)) {1185                approval = <Allowances<T>>::get(collection_id, (item_id, &from, &sender));1186                ensure!(approval >= value, Error::<T>::TokenValueNotEnough);1187                appoved_transfer = true;1188            }11891190            let target_collection = <Collection<T>>::get(collection_id);11911192            // Limits check1193            Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;11941195            // Transfer permissions check         1196            ensure!(1197                appoved_transfer || 1198                (1199                    target_collection.limits.owner_can_transfer &&1200                    Self::is_owner_or_admin_permissions(collection_id, sender.clone())1201                ),1202                Error::<T>::NoPermission1203            );12041205            if target_collection.access == AccessMode::WhiteList {1206                Self::check_white_list(collection_id, &sender)?;1207                Self::check_white_list(collection_id, &recipient)?;1208            }12091210            // Reduce approval by transferred amount or remove if remaining approval drops to 01211            if approval.checked_sub(value).unwrap_or(0) > 0 {1212                <Allowances<T>>::insert(collection_id, (item_id, &from, &sender), approval - value);1213            }1214            else {1215                <Allowances<T>>::remove(collection_id, (item_id, &from, &sender));1216            }12171218            match target_collection.mode1219            {1220                CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,1221                CollectionMode::Fungible(_)  => Self::transfer_fungible(collection_id, value, &from, &recipient)?,1222                CollectionMode::ReFungible  => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,1223                _ => ()1224            };12251226            Ok(())1227        }12281229        // #[weight = 0]1230        // pub fn safe_transfer_from(origin, collection_id: CollectionId, item_id: TokenId, new_owner: T::AccountId) -> DispatchResult {12311232        //     // let no_perm_mes = "You do not have permissions to modify this collection";1233        //     // ensure!(<ApprovedList<T>>::contains_key((collection_id, item_id)), no_perm_mes);1234        //     // let list_itm = <ApprovedList<T>>::get((collection_id, item_id));1235        //     // ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes);12361237        //     // // on_nft_received  call12381239        //     // Self::transfer(origin, collection_id, item_id, new_owner)?;12401241        //     Ok(())1242        // }12431244        /// Set off-chain data schema.1245        /// 1246        /// # Permissions1247        /// 1248        /// * Collection Owner1249        /// * Collection Admin1250        /// 1251        /// # Arguments1252        /// 1253        /// * collection_id.1254        /// 1255        /// * schema: String representing the offchain data schema.1256        #[weight = <T as Config>::WeightInfo::set_variable_meta_data()]1257        pub fn set_variable_meta_data (1258            origin,1259            collection_id: CollectionId,1260            item_id: TokenId,1261            data: Vec<u8>1262        ) -> DispatchResult {1263            let sender = ensure_signed(origin)?;1264            1265            Self::collection_exists(collection_id)?;1266            Self::token_exists(collection_id, item_id, &sender)?;12671268            ensure!(ChainLimit::get().custom_data_limit >= data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);12691270            // Modify permissions check1271            let target_collection = <Collection<T>>::get(collection_id);1272            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1273                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1274                Error::<T>::NoPermission);12751276            match target_collection.mode1277            {1278                CollectionMode::NFT => Self::set_nft_variable_data(collection_id, item_id, data)?,1279                CollectionMode::ReFungible  => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,1280                CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),1281                _ => fail!(Error::<T>::UnexpectedCollectionType)1282            };12831284            Ok(())1285        }1286 1287        /// Set schema standard1288        /// ImageURL1289        /// Unique1290        /// 1291        /// # Permissions1292        /// 1293        /// * Collection Owner1294        /// * Collection Admin1295        /// 1296        /// # Arguments1297        /// 1298        /// * collection_id.1299        /// 1300        /// * schema: SchemaVersion: enum1301        #[weight = <T as Config>::WeightInfo::set_schema_version()]1302        pub fn set_schema_version(1303            origin,1304            collection_id: CollectionId,1305            version: SchemaVersion1306        ) -> DispatchResult {1307            let sender = ensure_signed(origin)?;1308            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1309            let mut target_collection = <Collection<T>>::get(collection_id);1310            target_collection.schema_version = version;1311            <Collection<T>>::insert(collection_id, target_collection);13121313            Ok(())1314        }13151316        /// Set off-chain data schema.1317        /// 1318        /// # Permissions1319        /// 1320        /// * Collection Owner1321        /// * Collection Admin1322        /// 1323        /// # Arguments1324        /// 1325        /// * collection_id.1326        /// 1327        /// * schema: String representing the offchain data schema.1328        #[weight = <T as Config>::WeightInfo::set_offchain_schema()]1329        pub fn set_offchain_schema(1330            origin,1331            collection_id: CollectionId,1332            schema: Vec<u8>1333        ) -> DispatchResult {1334            let sender = ensure_signed(origin)?;1335            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13361337            // check schema limit1338            ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");13391340            let mut target_collection = <Collection<T>>::get(collection_id);1341            target_collection.offchain_schema = schema;1342            <Collection<T>>::insert(collection_id, target_collection);13431344            Ok(())1345        }13461347        /// Set const on-chain data schema.1348        /// 1349        /// # Permissions1350        /// 1351        /// * Collection Owner1352        /// * Collection Admin1353        /// 1354        /// # Arguments1355        /// 1356        /// * collection_id.1357        /// 1358        /// * schema: String representing the const on-chain data schema.1359        #[weight = <T as Config>::WeightInfo::set_const_on_chain_schema()]1360        pub fn set_const_on_chain_schema (1361            origin,1362            collection_id: CollectionId,1363            schema: Vec<u8>1364        ) -> DispatchResult {1365            let sender = ensure_signed(origin)?;1366            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13671368            // check schema limit1369            ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");13701371            let mut target_collection = <Collection<T>>::get(collection_id);1372            target_collection.const_on_chain_schema = schema;1373            <Collection<T>>::insert(collection_id, target_collection);13741375            Ok(())1376        }13771378        /// Set variable on-chain data schema.1379        /// 1380        /// # Permissions1381        /// 1382        /// * Collection Owner1383        /// * Collection Admin1384        /// 1385        /// # Arguments1386        /// 1387        /// * collection_id.1388        /// 1389        /// * schema: String representing the variable on-chain data schema.1390        #[weight = <T as Config>::WeightInfo::set_const_on_chain_schema()]1391        pub fn set_variable_on_chain_schema (1392            origin,1393            collection_id: CollectionId,1394            schema: Vec<u8>1395        ) -> DispatchResult {1396            let sender = ensure_signed(origin)?;1397            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13981399            // check schema limit1400            ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");14011402            let mut target_collection = <Collection<T>>::get(collection_id);1403            target_collection.variable_on_chain_schema = schema;1404            <Collection<T>>::insert(collection_id, target_collection);14051406            Ok(())1407        }14081409        // Sudo permissions function1410        #[weight = <T as Config>::WeightInfo::set_chain_limits()]1411        pub fn set_chain_limits(1412            origin,1413            limits: ChainLimits1414        ) -> DispatchResult {14151416            #[cfg(not(feature = "runtime-benchmarks"))]1417            ensure_root(origin)?;14181419            <ChainLimit>::put(limits);1420            Ok(())1421        }14221423        /// Enable smart contract self-sponsoring.1424        /// 1425        /// # Permissions1426        /// 1427        /// * Contract Owner1428        /// 1429        /// # Arguments1430        /// 1431        /// * contract address1432        /// * enable flag1433        /// 1434        #[weight = <T as Config>::WeightInfo::enable_contract_sponsoring()]1435        pub fn enable_contract_sponsoring(1436            origin,1437            contract_address: T::AccountId,1438            enable: bool1439        ) -> DispatchResult {14401441            let sender = ensure_signed(origin)?;14421443            #[cfg(feature = "runtime-benchmarks")]1444            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14451446            Self::ensure_contract_owned(sender, &contract_address)?;14471448            <ContractSelfSponsoring<T>>::insert(contract_address, enable);1449            Ok(())1450        }14511452        /// Set the rate limit for contract sponsoring to specified number of blocks.1453        /// 1454        /// If not set (has the default value of 0 blocks), the sponsoring will be disabled. 1455        /// If set to the number B (for blocks), the transactions will be sponsored with a rate 1456        /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid 1457        /// from contract endowment if there are at least B blocks between such transactions. 1458        /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.1459        /// 1460        /// # Permissions1461        /// 1462        /// * Contract Owner1463        /// 1464        /// # Arguments1465        /// 1466        /// -`contract_address`: Address of the contract to sponsor1467        /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed1468        /// 1469        #[weight = <T as Config>::WeightInfo::set_contract_sponsoring_rate_limit()]1470        pub fn set_contract_sponsoring_rate_limit(1471            origin,1472            contract_address: T::AccountId,1473            rate_limit: T::BlockNumber1474        ) -> DispatchResult {1475            let sender = ensure_signed(origin)?;14761477            #[cfg(feature = "runtime-benchmarks")]1478            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14791480            Self::ensure_contract_owned(sender, &contract_address)?;1481            <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);1482            Ok(())1483        }14841485        /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.1486        /// 1487        /// # Permissions1488        /// 1489        /// * Address that deployed smart contract.1490        /// 1491        /// # Arguments1492        /// 1493        /// -`contract_address`: Address of the contract.1494        /// 1495        /// - `enable`: .  1496        #[weight = <T as Config>::WeightInfo::toggle_contract_white_list()]1497        pub fn toggle_contract_white_list(1498            origin,1499            contract_address: T::AccountId,1500            enable: bool1501        ) -> DispatchResult {1502            let sender = ensure_signed(origin)?;15031504            #[cfg(feature = "runtime-benchmarks")]1505            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());15061507            Self::ensure_contract_owned(sender, &contract_address)?;1508            <ContractWhiteListEnabled<T>>::insert(contract_address, enable);1509            Ok(())1510        }1511        1512        /// Add an address to smart contract white list.1513        /// 1514        /// # Permissions1515        /// 1516        /// * Address that deployed smart contract.1517        /// 1518        /// # Arguments1519        /// 1520        /// -`contract_address`: Address of the contract.1521        ///1522        /// -`account_address`: Address to add.1523        #[weight = <T as Config>::WeightInfo::add_to_contract_white_list()]1524        pub fn add_to_contract_white_list(1525            origin,1526            contract_address: T::AccountId,1527            account_address: T::AccountId1528        ) -> DispatchResult {1529            let sender = ensure_signed(origin)?;15301531            #[cfg(feature = "runtime-benchmarks")]1532            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());1533            1534            Self::ensure_contract_owned(sender, &contract_address)?;      1535            <ContractWhiteList<T>>::insert(contract_address, account_address, true);1536            Ok(())1537        }15381539        /// Remove an address from smart contract white list.1540        /// 1541        /// # Permissions1542        /// 1543        /// * Address that deployed smart contract.1544        /// 1545        /// # Arguments1546        /// 1547        /// -`contract_address`: Address of the contract.1548        ///1549        /// -`account_address`: Address to remove.1550        #[weight = <T as Config>::WeightInfo::remove_from_contract_white_list()]1551        pub fn remove_from_contract_white_list(1552            origin,1553            contract_address: T::AccountId,1554            account_address: T::AccountId1555        ) -> DispatchResult {1556            let sender = ensure_signed(origin)?;15571558            #[cfg(feature = "runtime-benchmarks")]1559            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());15601561            Self::ensure_contract_owned(sender, &contract_address)?;1562            <ContractWhiteList<T>>::remove(contract_address, account_address);1563            Ok(())1564        }15651566        #[weight = <T as Config>::WeightInfo::set_collection_limits()]1567        pub fn set_collection_limits(1568            origin,1569            collection_id: u32,1570            new_limits: CollectionLimits,1571        ) -> DispatchResult {1572            let sender = ensure_signed(origin)?;1573            Self::check_owner_permissions(collection_id, sender.clone())?;1574            let mut target_collection = <Collection<T>>::get(collection_id);1575            let old_limits = target_collection.limits;1576            let chain_limits = ChainLimit::get();15771578            // collection bounds1579            ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&1580                new_limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP && 1581                new_limits.sponsored_data_size <= chain_limits.custom_data_limit,1582                Error::<T>::CollectionLimitBoundsExceeded);15831584            // token_limit   check  prev1585            ensure!(old_limits.token_limit >= new_limits.token_limit, Error::<T>::CollectionTokenLimitExceeded);1586            ensure!(new_limits.token_limit > 0, Error::<T>::CollectionTokenLimitExceeded);15871588            ensure!(1589                (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&1590                (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),1591                Error::<T>::OwnerPermissionsCantBeReverted,1592            );15931594            target_collection.limits = new_limits;1595            <Collection<T>>::insert(collection_id, target_collection);15961597            Ok(())1598        } 1599    }1600}16011602impl<T: Config> Module<T> {16031604    pub fn transfer_internal(sender: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {16051606        let target_collection = <Collection<T>>::get(collection_id);16071608        // Limits check1609        Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;16101611        // Transfer permissions check1612        ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1613            Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1614            Error::<T>::NoPermission);16151616        if target_collection.access == AccessMode::WhiteList {1617            Self::check_white_list(collection_id, &sender)?;1618            Self::check_white_list(collection_id, &recipient)?;1619        }16201621        match target_collection.mode1622        {1623            CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient.clone())?,1624            CollectionMode::Fungible(_)  => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,1625            CollectionMode::ReFungible  => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient.clone())?,1626            _ => ()1627        };16281629        Self::deposit_event(RawEvent::Transfer(collection_id, item_id, sender, recipient, value));16301631        Ok(())1632    }163316341635    fn is_correct_transfer(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, recipient: &T::AccountId) -> DispatchResult {16361637        // check token limit and account token limit1638        let account_items: u32 = <AddressTokens<T>>::get(collection_id, recipient).len() as u32;1639        ensure!(collection.limits.account_token_ownership_limit > account_items,  Error::<T>::AccountTokenLimitExceeded);1640        1641        Ok(())1642    }16431644    fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {16451646        // check token limit and account token limit1647        let total_items: u32 = ItemListIndex::get(collection_id);1648        let account_items: u32 = <AddressTokens<T>>::get(collection_id, owner).len() as u32;1649        ensure!(collection.limits.token_limit > total_items,  Error::<T>::CollectionTokenLimitExceeded);1650        ensure!(collection.limits.account_token_ownership_limit > account_items,  Error::<T>::AccountTokenLimitExceeded);16511652        if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {1653            ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);1654            Self::check_white_list(collection_id, owner)?;1655            Self::check_white_list(collection_id, sender)?;1656        }16571658        Ok(())1659    }16601661    fn validate_create_item_args(target_collection: &CollectionType<T::AccountId>, data: &CreateItemData) -> DispatchResult {1662        match target_collection.mode1663        {1664            CollectionMode::NFT => {1665                if let CreateItemData::NFT(data) = data {1666                    // check sizes1667                    ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);1668                    ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);1669                } else {1670                    fail!(Error::<T>::NotNftDataUsedToMintNftCollectionToken);1671                }1672            },1673            CollectionMode::Fungible(_) => {1674                if let CreateItemData::Fungible(_) = data {1675                } else {1676                    fail!(Error::<T>::NotFungibleDataUsedToMintFungibleCollectionToken);1677                }1678            },1679            CollectionMode::ReFungible => {1680                if let CreateItemData::ReFungible(data) = data {16811682                    // check sizes1683                    ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);1684                    ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);16851686                    // Check refungibility limits1687                    ensure!(data.pieces <= MAX_REFUNGIBLE_PIECES, Error::<T>::WrongRefungiblePieces);1688                    ensure!(data.pieces > 0, Error::<T>::WrongRefungiblePieces);1689                } else {1690                    fail!(Error::<T>::NotReFungibleDataUsedToMintReFungibleCollectionToken);1691                }1692            },1693            _ => { fail!(Error::<T>::UnexpectedCollectionType); }1694        };16951696        Ok(())1697    }16981699    fn create_item_no_validation(collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1700        match data1701        {1702            CreateItemData::NFT(data) => {1703                let item = NftItemType {1704                    owner: owner.clone(),1705                    const_data: data.const_data,1706                    variable_data: data.variable_data1707                };17081709                Self::add_nft_item(collection_id, item)?;1710            },1711            CreateItemData::Fungible(data) => {1712                Self::add_fungible_item(collection_id, &owner, data.value)?;1713            },1714            CreateItemData::ReFungible(data) => {1715                let mut owner_list = Vec::new();1716                owner_list.push(Ownership {owner: owner.clone(), fraction: data.pieces});17171718                let item = ReFungibleItemType {1719                    owner: owner_list,1720                    const_data: data.const_data,1721                    variable_data: data.variable_data1722                };17231724                Self::add_refungible_item(collection_id, item)?;1725            }1726        };17271728        // call event1729        Self::deposit_event(RawEvent::ItemCreated(collection_id, <ItemListIndex>::get(collection_id), owner));17301731        Ok(())1732    }17331734    fn add_fungible_item(collection_id: CollectionId, owner: &T::AccountId, value: u128) -> DispatchResult {17351736        // Does new owner already have an account?1737        let mut balance: u128 = 0;1738        if <FungibleItemList<T>>::contains_key(collection_id, owner) {1739            balance = <FungibleItemList<T>>::get(collection_id, owner).value;1740        } 17411742        // Mint 1743        let item = FungibleItemType {1744            value: balance + value1745        };1746        <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), item);17471748        // Update balance1749        let new_balance = <Balance<T>>::get(collection_id, owner)1750            .checked_add(value)1751            .ok_or(Error::<T>::NumOverflow)?;1752        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);17531754        Ok(())1755    }17561757    fn add_refungible_item(collection_id: CollectionId, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {1758        let current_index = <ItemListIndex>::get(collection_id)1759            .checked_add(1)1760            .ok_or(Error::<T>::NumOverflow)?;1761        let itemcopy = item.clone();17621763        let value = item.owner.first().unwrap().fraction;1764        let owner = item.owner.first().unwrap().owner.clone();17651766        Self::add_token_index(collection_id, current_index, &owner)?;17671768        <ItemListIndex>::insert(collection_id, current_index);1769        <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);17701771        // Update balance1772        let new_balance = <Balance<T>>::get(collection_id, &owner)1773            .checked_add(value)1774            .ok_or(Error::<T>::NumOverflow)?;1775        <Balance<T>>::insert(collection_id, owner.clone(), new_balance);17761777        Ok(())1778    }17791780    fn add_nft_item(collection_id: CollectionId, item: NftItemType<T::AccountId>) -> DispatchResult {1781        let current_index = <ItemListIndex>::get(collection_id)1782            .checked_add(1)1783            .ok_or(Error::<T>::NumOverflow)?;17841785        let item_owner = item.owner.clone();1786        Self::add_token_index(collection_id, current_index, &item.owner)?;17871788        <ItemListIndex>::insert(collection_id, current_index);1789        <NftItemList<T>>::insert(collection_id, current_index, item);17901791        // Update balance1792        let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())1793            .checked_add(1)1794            .ok_or(Error::<T>::NumOverflow)?;1795        <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);17961797        Ok(())1798    }17991800    fn burn_refungible_item(1801        collection_id: CollectionId,1802        item_id: TokenId,1803        owner: &T::AccountId,1804    ) -> DispatchResult {1805        ensure!(1806            <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1807            Error::<T>::TokenNotFound1808        );1809        let mut token = <ReFungibleItemList<T>>::get(collection_id, item_id);1810        let rft_balance = token1811            .owner1812            .iter()1813            .filter(|&i| i.owner == *owner)1814            .next()1815            .unwrap();1816        Self::remove_token_index(collection_id, item_id, owner)?;18171818        // update balance1819        let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.clone())1820            .checked_sub(rft_balance.fraction)1821            .ok_or(Error::<T>::NumOverflow)?;1822        <Balance<T>>::insert(collection_id, rft_balance.owner.clone(), new_balance);18231824        // Re-create owners list with sender removed1825        let index = token1826            .owner1827            .iter()1828            .position(|i| i.owner == *owner)1829            .unwrap();1830        token.owner.remove(index);1831        let owner_count = token.owner.len();18321833        // Burn the token completely if this was the last (only) owner1834        if owner_count == 0 {1835            <ReFungibleItemList<T>>::remove(collection_id, item_id);1836        }1837        else {1838            <ReFungibleItemList<T>>::insert(collection_id, item_id, token);1839        }18401841        Ok(())1842    }18431844    fn burn_nft_item(collection_id: CollectionId, item_id: TokenId) -> DispatchResult {1845        ensure!(1846            <NftItemList<T>>::contains_key(collection_id, item_id),1847            Error::<T>::TokenNotFound1848        );1849        let item = <NftItemList<T>>::get(collection_id, item_id);1850        Self::remove_token_index(collection_id, item_id, &item.owner)?;18511852        // update balance1853        let new_balance = <Balance<T>>::get(collection_id, &item.owner)1854            .checked_sub(1)1855            .ok_or(Error::<T>::NumOverflow)?;1856        <Balance<T>>::insert(collection_id, item.owner.clone(), new_balance);1857        <NftItemList<T>>::remove(collection_id, item_id);18581859        Ok(())1860    }18611862    fn burn_fungible_item(owner: &T::AccountId, collection_id: CollectionId, value: u128) -> DispatchResult {1863        ensure!(1864            <FungibleItemList<T>>::contains_key(collection_id, owner),1865            Error::<T>::TokenNotFound1866        );1867        let mut balance = <FungibleItemList<T>>::get(collection_id, owner);1868        ensure!(balance.value >= value, Error::<T>::TokenValueNotEnough);18691870        // update balance1871        let new_balance = <Balance<T>>::get(collection_id, owner)1872            .checked_sub(value)1873            .ok_or(Error::<T>::NumOverflow)?;1874        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);18751876        if balance.value - value > 0 {1877            balance.value -= value;1878            <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);1879        }1880        else {1881            <FungibleItemList<T>>::remove(collection_id, owner);1882        }18831884        Ok(())1885    }18861887    fn collection_exists(collection_id: CollectionId) -> DispatchResult {1888        ensure!(1889            <Collection<T>>::contains_key(collection_id),1890            Error::<T>::CollectionNotFound1891        );1892        Ok(())1893    }18941895    fn check_owner_permissions(collection_id: CollectionId, subject: T::AccountId) -> DispatchResult {1896        Self::collection_exists(collection_id)?;18971898        let target_collection = <Collection<T>>::get(collection_id);1899        ensure!(1900            subject == target_collection.owner,1901            Error::<T>::NoPermission1902        );19031904        Ok(())1905    }19061907    fn is_owner_or_admin_permissions(collection_id: CollectionId, subject: T::AccountId) -> bool {1908        let target_collection = <Collection<T>>::get(collection_id);1909        let mut result: bool = subject == target_collection.owner;1910        let exists = <AdminList<T>>::contains_key(collection_id);19111912        if !result & exists {1913            if <AdminList<T>>::get(collection_id).contains(&subject) {1914                result = true1915            }1916        }19171918        result1919    }19201921    fn check_owner_or_admin_permissions(1922        collection_id: CollectionId,1923        subject: T::AccountId,1924    ) -> DispatchResult {1925        Self::collection_exists(collection_id)?;1926        let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());19271928        ensure!(1929            result,1930            Error::<T>::NoPermission1931        );1932        Ok(())1933    }19341935    fn owned_amount(1936        subject: T::AccountId,1937        collection_id: CollectionId,1938        item_id: TokenId,1939    ) -> Option<u128> {1940        let target_collection = <Collection<T>>::get(collection_id);19411942        match target_collection.mode {1943            CollectionMode::NFT => {1944                if <NftItemList<T>>::get(collection_id, item_id).owner == subject {1945                    return Some(1)1946                }1947                None1948            },1949            CollectionMode::Fungible(_) => {1950                if <FungibleItemList<T>>::contains_key(collection_id, &subject) {1951                    return Some(<FungibleItemList<T>>::get(collection_id, &subject)1952                        .value);1953                }1954                None1955            },1956            CollectionMode::ReFungible => <ReFungibleItemList<T>>::get(collection_id, item_id)1957                .owner1958                .iter()1959                .find(|i| i.owner == subject)1960                .map(|i| i.fraction),1961            CollectionMode::Invalid => None,1962        }1963    }19641965    fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool {1966        let target_collection = <Collection<T>>::get(collection_id);19671968        match target_collection.mode {1969            CollectionMode::NFT => {1970                <NftItemList<T>>::get(collection_id, item_id).owner == subject1971            }1972            CollectionMode::Fungible(_) => {1973                <FungibleItemList<T>>::contains_key(collection_id, &subject)1974            }1975            CollectionMode::ReFungible => {1976                <ReFungibleItemList<T>>::get(collection_id, item_id)1977                    .owner1978                    .iter()1979                    .any(|i| i.owner == subject)1980            }1981            CollectionMode::Invalid => false,1982        }1983    }19841985    fn check_white_list(collection_id: CollectionId, address: &T::AccountId) -> DispatchResult {1986        let mes = Error::<T>::AddresNotInWhiteList;1987        ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);19881989        Ok(())1990    }19911992    /// Check if token exists. In case of Fungible, check if there is an entry for 1993    /// the owner in fungible balances double map1994    fn token_exists(1995        collection_id: CollectionId,1996        item_id: TokenId,1997        owner: &T::AccountId1998    ) -> DispatchResult {1999        let target_collection = <Collection<T>>::get(collection_id);2000        let exists = match target_collection.mode2001        {2002            CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),2003            CollectionMode::Fungible(_)  => <FungibleItemList<T>>::contains_key(collection_id, owner),2004            CollectionMode::ReFungible  => <ReFungibleItemList<T>>::contains_key(collection_id, item_id),2005            _ => false2006        };20072008        ensure!(exists == true, Error::<T>::TokenNotFound);2009        Ok(())2010    }20112012    fn transfer_fungible(2013        collection_id: CollectionId,2014        value: u128,2015        owner: &T::AccountId,2016        recipient: &T::AccountId,2017    ) -> DispatchResult {2018        Self::token_exists(collection_id, 0, owner)?;20192020        let mut balance = <FungibleItemList<T>>::get(collection_id, owner);2021        ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);20222023        // Send balance to recipient (updates balanceOf of recipient)2024        Self::add_fungible_item(collection_id, recipient, value)?;20252026        // update balanceOf of sender2027        <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);20282029        // Reduce or remove sender2030        if balance.value == value {2031            <FungibleItemList<T>>::remove(collection_id, owner);2032        }2033        else {2034            balance.value -= value;2035            <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);2036        }20372038        Ok(())2039    }20402041    fn transfer_refungible(2042        collection_id: CollectionId,2043        item_id: TokenId,2044        value: u128,2045        owner: T::AccountId,2046        new_owner: T::AccountId,2047    ) -> DispatchResult {2048        Self::token_exists(collection_id, item_id, &owner)?;20492050        let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);2051        let item = full_item2052            .owner2053            .iter()2054            .filter(|i| i.owner == owner)2055            .next()2056            .ok_or(Error::<T>::NumOverflow)?;2057        let amount = item.fraction;20582059        ensure!(amount >= value, Error::<T>::TokenValueTooLow);20602061        // update balance2062        let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone())2063            .checked_sub(value)2064            .ok_or(Error::<T>::NumOverflow)?;2065        <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);20662067        let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())2068            .checked_add(value)2069            .ok_or(Error::<T>::NumOverflow)?;2070        <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);20712072        let old_owner = item.owner.clone();2073        let new_owner_has_account = full_item.owner.iter().any(|i| i.owner == new_owner);20742075        // transfer2076        if amount == value && !new_owner_has_account {2077            // change owner2078            // new owner do not have account2079            let mut new_full_item = full_item.clone();2080            new_full_item2081                .owner2082                .iter_mut()2083                .find(|i| i.owner == owner)2084                .unwrap()2085                .owner = new_owner.clone();2086            <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);20872088            // update index collection2089            Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;2090        } else {2091            let mut new_full_item = full_item.clone();2092            new_full_item2093                .owner2094                .iter_mut()2095                .find(|i| i.owner == owner)2096                .unwrap()2097                .fraction -= value;20982099            // separate amount2100            if new_owner_has_account {2101                // new owner has account2102                new_full_item2103                    .owner2104                    .iter_mut()2105                    .find(|i| i.owner == new_owner)2106                    .unwrap()2107                    .fraction += value;2108            } else {2109                // new owner do not have account2110                new_full_item.owner.push(Ownership {2111                    owner: new_owner.clone(),2112                    fraction: value,2113                });2114                Self::add_token_index(collection_id, item_id, &new_owner)?;2115            }21162117            <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2118        }21192120        Ok(())2121    }21222123    fn transfer_nft(2124        collection_id: CollectionId,2125        item_id: TokenId,2126        sender: T::AccountId,2127        new_owner: T::AccountId,2128    ) -> DispatchResult {2129        Self::token_exists(collection_id, item_id, &sender)?;21302131        let mut item = <NftItemList<T>>::get(collection_id, item_id);21322133        ensure!(2134            sender == item.owner,2135            Error::<T>::MustBeTokenOwner2136        );21372138        // update balance2139        let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone())2140            .checked_sub(1)2141            .ok_or(Error::<T>::NumOverflow)?;2142        <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);21432144        let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())2145            .checked_add(1)2146            .ok_or(Error::<T>::NumOverflow)?;2147        <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);21482149        // change owner2150        let old_owner = item.owner.clone();2151        item.owner = new_owner.clone();2152        <NftItemList<T>>::insert(collection_id, item_id, item);21532154        // update index collection2155        Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;21562157        Ok(())2158    }2159    2160    fn set_re_fungible_variable_data(2161        collection_id: CollectionId,2162        item_id: TokenId,2163        data: Vec<u8>2164    ) -> DispatchResult {2165        let mut item = <ReFungibleItemList<T>>::get(collection_id, item_id);21662167        item.variable_data = data;21682169        <ReFungibleItemList<T>>::insert(collection_id, item_id, item);21702171        Ok(())2172    }21732174    fn set_nft_variable_data(2175        collection_id: CollectionId,2176        item_id: TokenId,2177        data: Vec<u8>2178    ) -> DispatchResult {2179        let mut item = <NftItemList<T>>::get(collection_id, item_id);2180        2181        item.variable_data = data;21822183        <NftItemList<T>>::insert(collection_id, item_id, item);2184        2185        Ok(())2186    }21872188    fn init_collection(item: &CollectionType<T::AccountId>) {2189        // check params2190        assert!(2191            item.decimal_points <= MAX_DECIMAL_POINTS,2192            "decimal_points parameter must be lower than MAX_DECIMAL_POINTS"2193        );2194        assert!(2195            item.name.len() <= 64,2196            "Collection name can not be longer than 63 char"2197        );2198        assert!(2199            item.name.len() <= 256,2200            "Collection description can not be longer than 255 char"2201        );2202        assert!(2203            item.token_prefix.len() <= 16,2204            "Token prefix can not be longer than 15 char"2205        );22062207        // Generate next collection ID2208        let next_id = CreatedCollectionCount::get()2209            .checked_add(1)2210            .unwrap();22112212        CreatedCollectionCount::put(next_id);2213    }22142215    fn init_nft_token(collection_id: CollectionId, item: &NftItemType<T::AccountId>) {2216        let current_index = <ItemListIndex>::get(collection_id)2217            .checked_add(1)2218            .unwrap();22192220        let item_owner = item.owner.clone();2221        Self::add_token_index(collection_id, current_index, &item.owner).unwrap();22222223        <ItemListIndex>::insert(collection_id, current_index);22242225        // Update balance2226        let new_balance = <Balance<T>>::get(collection_id, &item_owner)2227            .checked_add(1)2228            .unwrap();2229        <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);2230    }22312232    fn init_fungible_token(collection_id: CollectionId, owner: &T::AccountId, item: &FungibleItemType) {2233        let current_index = <ItemListIndex>::get(collection_id)2234            .checked_add(1)2235            .unwrap();22362237        Self::add_token_index(collection_id, current_index, owner).unwrap();22382239        <ItemListIndex>::insert(collection_id, current_index);22402241        // Update balance2242        let new_balance = <Balance<T>>::get(collection_id, owner)2243            .checked_add(item.value)2244            .unwrap();2245        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);2246    }22472248    fn init_refungible_token(collection_id: CollectionId, item: &ReFungibleItemType<T::AccountId>) {2249        let current_index = <ItemListIndex>::get(collection_id)2250            .checked_add(1)2251            .unwrap();22522253        let value = item.owner.first().unwrap().fraction;2254        let owner = item.owner.first().unwrap().owner.clone();22552256        Self::add_token_index(collection_id, current_index, &owner).unwrap();22572258        <ItemListIndex>::insert(collection_id, current_index);22592260        // Update balance2261        let new_balance = <Balance<T>>::get(collection_id, &owner)2262            .checked_add(value)2263            .unwrap();2264        <Balance<T>>::insert(collection_id, owner.clone(), new_balance);2265    }22662267    fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: &T::AccountId) -> DispatchResult {22682269        // add to account limit2270        if <AccountItemCount<T>>::contains_key(owner) {22712272            // bound Owned tokens by a single address2273            let count = <AccountItemCount<T>>::get(owner);2274            ensure!(count < ChainLimit::get().account_token_ownership_limit, Error::<T>::AddressOwnershipLimitExceeded);22752276            <AccountItemCount<T>>::insert(owner.clone(), count2277                .checked_add(1)2278                .ok_or(Error::<T>::NumOverflow)?);2279        }2280        else {2281            <AccountItemCount<T>>::insert(owner.clone(), 1);2282        }22832284        let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner);2285        if list_exists {2286            let mut list = <AddressTokens<T>>::get(collection_id, owner);2287            let item_contains = list.contains(&item_index.clone());22882289            if !item_contains {2290                list.push(item_index.clone());2291            }22922293            <AddressTokens<T>>::insert(collection_id, owner.clone(), list);2294        } else {2295            let mut itm = Vec::new();2296            itm.push(item_index.clone());2297            <AddressTokens<T>>::insert(collection_id, owner.clone(), itm);2298        }22992300        Ok(())2301    }23022303    fn remove_token_index(2304        collection_id: CollectionId,2305        item_index: TokenId,2306        owner: &T::AccountId,2307    ) -> DispatchResult {23082309        // update counter2310        <AccountItemCount<T>>::insert(owner.clone(), 2311            <AccountItemCount<T>>::get(owner)2312            .checked_sub(1)2313            .ok_or(Error::<T>::NumOverflow)?);231423152316        let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner);2317        if list_exists {2318            let mut list = <AddressTokens<T>>::get(collection_id, owner);2319            let item_contains = list.contains(&item_index.clone());23202321            if item_contains {2322                list.retain(|&item| item != item_index);2323                <AddressTokens<T>>::insert(collection_id, owner.clone(), list);2324            }2325        }23262327        Ok(())2328    }23292330    fn move_token_index(2331        collection_id: CollectionId,2332        item_index: TokenId,2333        old_owner: &T::AccountId,2334        new_owner: &T::AccountId,2335    ) -> DispatchResult {2336        Self::remove_token_index(collection_id, item_index, old_owner)?;2337        Self::add_token_index(collection_id, item_index, new_owner)?;23382339        Ok(())2340    }2341    2342    fn ensure_contract_owned(account: T::AccountId, contract: &T::AccountId) -> DispatchResult {2343        if <ContractOwner<T>>::contains_key(contract.clone()) {2344            let owner = <ContractOwner<T>>::get(contract);2345            ensure!(account == owner, Error::<T>::NoPermission);2346        } else {2347            fail!(Error::<T>::NoPermission);2348        }23492350        Ok(())2351    }2352}23532354////////////////////////////////////////////////////////////////////////////////////////////////////2355// Economic models2356// #region23572358/// Fee multiplier.2359pub type Multiplier = FixedU128;23602361type BalanceOf<T> = <<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::Balance;23622363/// Require the transactor pay for themselves and maybe include a tip to gain additional priority2364/// in the queue.2365#[derive(Encode, Decode, Clone, Eq, PartialEq)]2366pub struct ChargeTransactionPayment<T: Config>(#[codec(compact)] BalanceOf<T>);23672368impl<T: Config + Send + Sync> sp_std::fmt::Debug 2369    for ChargeTransactionPayment<T>2370{2371	#[cfg(feature = "std")]2372	fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {2373		write!(f, "ChargeTransactionPayment<{:?}>", self.0)2374	}2375	#[cfg(not(feature = "std"))]2376	fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {2377		Ok(())2378	}2379}23802381impl<T: Config> ChargeTransactionPayment<T>2382where2383    T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,2384    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,2385    T::AccountId: AsRef<[u8]>,2386    T::AccountId: UncheckedFrom<T::Hash>,2387{2388    fn traditional_fee(2389        len: usize,2390        info: &DispatchInfoOf<T::Call>,2391        tip: BalanceOf<T>,2392    ) -> BalanceOf<T>2393    where2394        T::Call: Dispatchable<Info = DispatchInfo>,2395    {2396        <transaction_payment::Module<T>>::compute_fee(len as u32, info, tip)2397    }23982399	fn get_priority(len: usize, info: &DispatchInfoOf<T::Call>, final_fee: BalanceOf<T>) -> TransactionPriority {2400        let weight_saturation = T::BlockWeights::get().max_block / info.weight.max(1);2401        let max_block_length = *T::BlockLength::get().max.get(DispatchClass::Normal);2402        let len_saturation = max_block_length as u64 / (len as u64).max(1);2403        let coefficient: BalanceOf<T> = weight_saturation2404            .min(len_saturation)2405            .saturated_into::<BalanceOf<T>>();2406        final_fee2407            .saturating_mul(coefficient)2408            .saturated_into::<TransactionPriority>()2409    }24102411    fn withdraw_fee(2412        &self,2413        who: &T::AccountId,2414        call: &T::Call,2415        info: &DispatchInfoOf<T::Call>,2416        len: usize,2417	) -> Result<2418		(2419			BalanceOf<T>,2420			<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::LiquidityInfo,2421		),2422		TransactionValidityError,2423	> {2424        let tip = self.0;24252426        // Set fee based on call type. Creating collection costs 1 Unique.2427        // All other transactions have traditional fees so far2428        // let fee = match call.is_sub_type() {2429        //     Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),2430        //     _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes2431        //                                                 // _ => <BalanceOf<T>>::from(100)2432        // };2433        let fee = Self::traditional_fee(len, info, tip);24342435        // Only mess with balances if fee is not zero.2436        if fee.is_zero() {2437            return <<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(who, call, info, fee, tip)2438			.map(|i| (fee, i));2439        }24402441        // Determine who is paying transaction fee based on ecnomic model2442        // Parse call to extract collection ID and access collection sponsor2443        let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {2444            Some(Call::create_item(collection_id, _owner, _properties)) => {24452446                // sponsor timeout2447                let block_number = <system::Module<T>>::block_number() as T::BlockNumber;24482449                let limit = <Collection<T>>::get(collection_id).limits.sponsor_transfer_timeout;2450                let mut sponsored = true;2451                if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {2452                    let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));2453                    let limit_time = last_tx_block + limit.into();2454                    if block_number <= limit_time {2455                        sponsored = false;2456                    }2457                }2458                if sponsored {2459                    <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);2460                }24612462                // check free create limit2463                if (<Collection<T>>::get(collection_id).limits.sponsored_data_size >= (_properties.len() as u32)) &&2464                   (<Collection<T>>::get(collection_id).sponsor_confirmed) &&2465                   (sponsored)2466                {2467                    <Collection<T>>::get(collection_id).sponsor2468                } else {2469                    T::AccountId::default()2470                }2471            }2472            Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {2473                2474                let mut sponsor_transfer = false;2475                if <Collection<T>>::get(collection_id).sponsor_confirmed {24762477                    let collection_limits = <Collection<T>>::get(collection_id).limits;2478                    let collection_mode = <Collection<T>>::get(collection_id).mode;2479    2480                    // sponsor timeout2481                    let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2482                    sponsor_transfer = match collection_mode {2483                        CollectionMode::NFT => {2484    2485                            // get correct limit2486                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2487                                collection_limits.sponsor_transfer_timeout2488                            } else {2489                                ChainLimit::get().nft_sponsor_transfer_timeout2490                            };2491    2492                            let mut sponsored = true;2493                            if <NftTransferBasket<T>>::contains_key(collection_id, item_id) {2494                                let last_tx_block = <NftTransferBasket<T>>::get(collection_id, item_id);2495                                let limit_time = last_tx_block + limit.into();2496                                if block_number <= limit_time {2497                                    sponsored = false;2498                                }2499                            }2500                            if sponsored {2501                                <NftTransferBasket<T>>::insert(collection_id, item_id, block_number);2502                            }25032504                            sponsored2505                        }2506                        CollectionMode::Fungible(_) => {2507    2508                            // get correct limit2509                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2510                                collection_limits.sponsor_transfer_timeout2511                            } else {2512                                ChainLimit::get().fungible_sponsor_transfer_timeout2513                            };2514    2515                            let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2516                            let mut sponsored = true;2517                            if <FungibleTransferBasket<T>>::contains_key(collection_id, who) {2518                                let last_tx_block = <FungibleTransferBasket<T>>::get(collection_id, who);2519                                let limit_time = last_tx_block + limit.into();2520                                if block_number <= limit_time {2521                                    sponsored = false;2522                                }2523                            }2524                            if sponsored {2525                                <FungibleTransferBasket<T>>::insert(collection_id, who, block_number);2526                            }25272528                            sponsored2529                        }2530                        CollectionMode::ReFungible => {2531    2532                            // get correct limit2533                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2534                                collection_limits.sponsor_transfer_timeout2535                            } else {2536                                ChainLimit::get().refungible_sponsor_transfer_timeout2537                            };2538    2539                            let mut sponsored = true;2540                            if <ReFungibleTransferBasket<T>>::contains_key(collection_id, item_id) {2541                                let last_tx_block = <ReFungibleTransferBasket<T>>::get(collection_id, item_id);2542                                let limit_time = last_tx_block + limit.into();2543                                if block_number <= limit_time {2544                                    sponsored = false;2545                                }2546                            }2547                            if sponsored {2548                                <ReFungibleTransferBasket<T>>::insert(collection_id, item_id, block_number);2549                            }25502551                            sponsored2552                        }2553                        _ => {2554                            false2555                        },2556                    };2557                }25582559                if !sponsor_transfer {2560                    T::AccountId::default()2561                } else {2562                    <Collection<T>>::get(collection_id).sponsor2563                }2564            }25652566            _ => T::AccountId::default(),2567        };25682569        // Sponsor smart contracts2570        sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {25712572            // On instantiation: set the contract owner2573            Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, _data, salt)) => {25742575                let new_contract_address = <pallet_contracts::Module<T>>::contract_address(2576                    &who,2577                    code_hash,2578                    salt,2579                );2580                <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());25812582                T::AccountId::default()2583            },25842585            // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2586            Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {25872588                let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());25892590                let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())2591                  && <ContractOwner<T>>::get(called_contract.clone()) == *who;2592                let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());2593                  2594                if !owned_contract && white_list_enabled {2595                    if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {2596                        return Err(InvalidTransaction::Call.into());2597                    }2598                }25992600                let mut sponsor_transfer = false;2601                if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {2602                    let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));2603                    let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2604                    let rate_limit = <ContractSponsoringRateLimit<T>>::get(&called_contract);2605                    let limit_time = last_tx_block + rate_limit;26062607                    if block_number >= limit_time {2608                        <ContractSponsorBasket<T>>::insert((called_contract.clone(), who.clone()), block_number);2609                        sponsor_transfer = true;2610                    }2611                } else {2612                    sponsor_transfer = false;2613                }2614               2615                2616                let mut sp = T::AccountId::default();2617                if sponsor_transfer {2618                    if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2619                        if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2620                            sp = called_contract;2621                        }2622                    }2623                }26242625                sp2626            },26272628            _ => sponsor,2629        };26302631        let mut who_pays_fee: T::AccountId = sponsor.clone();2632        if sponsor == T::AccountId::default() {2633            who_pays_fee = who.clone();2634        }26352636		<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(&who_pays_fee, call, info, fee, tip)2637			.map(|i| (fee, i))2638    }2639}264026412642impl<T: Config + Send + Sync> SignedExtension2643    for ChargeTransactionPayment<T>2644where2645    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,2646    T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,2647    T::AccountId: AsRef<[u8]>,2648    T::AccountId: UncheckedFrom<T::Hash>,2649{2650    const IDENTIFIER: &'static str = "ChargeTransactionPayment";2651    type AccountId = T::AccountId;2652    type Call = T::Call;2653    type AdditionalSigned = ();2654    type Pre = (2655        // tip2656        BalanceOf<T>,2657        // who pays fee2658        Self::AccountId,2659		// imbalance resulting from withdrawing the fee2660		<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::LiquidityInfo,2661    );2662    fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {2663        Ok(())2664    }26652666    fn validate(2667        &self,2668        who: &Self::AccountId,2669        call: &Self::Call,2670        info: &DispatchInfoOf<Self::Call>,2671        len: usize,2672    ) -> TransactionValidity {2673		let (fee, _) = self.withdraw_fee(who, call, info, len)?;2674		Ok(ValidTransaction {2675			priority: Self::get_priority(len, info, fee),2676			..Default::default()2677		})2678    }26792680    fn pre_dispatch(2681        self,2682        who: &Self::AccountId,2683        call: &Self::Call,2684        info: &DispatchInfoOf<Self::Call>,2685        len: usize,2686    ) -> Result<Self::Pre, TransactionValidityError> {2687        let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;2688        Ok((self.0, who.clone(), imbalance))2689    }26902691    fn post_dispatch(2692        pre: Self::Pre,2693        info: &DispatchInfoOf<Self::Call>,2694        post_info: &PostDispatchInfoOf<Self::Call>,2695        len: usize,2696        _result: &DispatchResult,2697    ) -> Result<(), TransactionValidityError> {2698		let (tip, who, imbalance) = pre;2699		let actual_fee = transaction_payment::Module::<T>::compute_actual_fee(2700			len as u32,2701			info,2702			post_info,2703			tip,2704		);2705		<T as transaction_payment::Config>::OnChargeTransaction::correct_and_deposit_fee(&who, info, post_info, actual_fee, tip, imbalance)?;2706		Ok(())2707    }2708}27092710// #endregion
modifiedruntime/Cargo.tomldiffbeforeafterboth
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -5,60 +5,60 @@
 license = 'All Rights Reserved'
 name = 'nft-runtime'
 repository = 'https://github.com/usetech-llc/nft_parachain/'
-version = '2.1.0'
+version = '3.0.0'
 
 [package.metadata.docs.rs]
 targets = ['x86_64-unknown-linux-gnu']
 
 [build-dependencies]
-wasm-builder-runner = { package = 'substrate-wasm-builder-runner', version = '1.0.5' }
+substrate-wasm-builder = '4.0.0'
 
 # alias "parity-scale-code" to "codec"
 [dependencies.codec]
 default-features = false
 features = ['derive']
 package = 'parity-scale-codec'
-version = '1.3.4'
+version = '2.0.0'
 
 [dependencies]
 hex-literal = { optional = true, version = '0.3.1' }
-serde = { features = ['derive'], optional = true, version = '1.0.101' }
+serde = { features = ['derive'], optional = true, version = '1.0.119' }
 
 # local dependencies
-pallet-nft = { path = '../pallets/nft', default-features = false, version = '2.1.0' }
+pallet-nft = { path = '../pallets/nft', default-features = false, version = '3.0.0' }
 
 # Substrate dependencies
-frame-benchmarking = { default-features = false, optional = true, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-frame-executive = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-frame-support = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-frame-system = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-frame-system-benchmarking = { default-features = false, optional = true, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-frame-system-rpc-runtime-api = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-aura = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-balances = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-contracts = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-contracts-primitives = { default-features = false, version = '2.0.1', git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-contracts-rpc-runtime-api = { default-features = false, version = '0.8.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-grandpa = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-randomness-collective-flip = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-sudo = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-timestamp = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-transaction-payment = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-transaction-payment-rpc-runtime-api = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-treasury = { version = "2.0.1", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-pallet-vesting = { version = "2.0.1", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-api = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-arithmetic = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-block-builder = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-consensus-aura = { default-features = false, version = '0.8.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-core = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-inherents = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-offchain = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-runtime = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-session = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-std = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-transaction-pool = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
-sp-version = { default-features = false, version = '2.0.1' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'unique' }
+frame-benchmarking = { default-features = false, optional = true, version = '3.0.0' }
+frame-executive = { default-features = false, version = '3.0.0' }
+frame-support = { default-features = false, version = '3.0.0' }
+frame-system = { default-features = false, version = '3.0.0' }
+frame-system-benchmarking = { default-features = false, optional = true, version = '3.0.0' }
+frame-system-rpc-runtime-api = { default-features = false, version = '3.0.0' }
+pallet-aura = { default-features = false, version = '3.0.0' }
+pallet-balances = { default-features = false, version = '3.0.0' }
+pallet-contracts = { default-features = false, version = '3.0.0' }
+pallet-contracts-primitives = { default-features = false, version = '3.0.0' }
+pallet-contracts-rpc-runtime-api = { default-features = false, version = '3.0.0' }
+pallet-grandpa = { default-features = false, version = '3.0.0' }
+pallet-randomness-collective-flip = { default-features = false, version = '3.0.0' }
+pallet-sudo = { default-features = false, version = '3.0.0' }
+pallet-timestamp = { default-features = false, version = '3.0.0' }
+pallet-transaction-payment = { default-features = false, version = '3.0.0' }
+pallet-transaction-payment-rpc-runtime-api = { default-features = false, version = '3.0.0' }
+pallet-treasury = { default-features = false, version = "3.0.0" }
+pallet-vesting = {  default-features = false, version = "3.0.0" }
+sp-arithmetic = { default-features = false, version = '3.0.0' }
+sp-api = { default-features = false, version = '3.0.0' }
+sp-block-builder = { default-features = false, version = '3.0.0' }
+sp-consensus-aura = { default-features = false, version = '0.9.0' }
+sp-core = { default-features = false, version = '3.0.0' }
+sp-inherents = { default-features = false, version = '3.0.0' }
+sp-offchain = { default-features = false, version = '3.0.0' }
+sp-runtime = { default-features = false, version = '3.0.0' }
+sp-session = { default-features = false, version = '3.0.0' }
+sp-std = { default-features = false, version = '3.0.0' }
+sp-transaction-pool = { default-features = false, version = '3.0.0' }
+sp-version = { default-features = false, version = '3.0.0' }
 smallvec = "1.4.1"
 
 [features]
modifiedruntime/build.rsdiffbeforeafterboth
--- a/runtime/build.rs
+++ b/runtime/build.rs
@@ -1,10 +1,9 @@
-use wasm_builder_runner::WasmBuilder;
+use substrate_wasm_builder::WasmBuilder;
 
 fn main() {
     WasmBuilder::new()
         .with_current_project()
-        .with_wasm_builder_from_crates("2.0.0")
-        .export_heap_base()
         .import_memory()
+        .export_heap_base()
         .build()
-}
+}
\ No newline at end of file
modifiedruntime/src/chain_extension.rsdiffbeforeafterboth
--- a/runtime/src/chain_extension.rs
+++ b/runtime/src/chain_extension.rs
@@ -33,7 +33,7 @@
 /// The chain Extension of NFT pallet
 pub struct NFTExtension;
 
-impl ChainExtension for NFTExtension {
+impl<C: Config> ChainExtension<C> for NFTExtension {
     fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>
     where
         <E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,
@@ -71,4 +71,3 @@
         }
     }
 }
-
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -35,7 +35,7 @@
 pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, CurrencyAdapter, FeeDetails, RuntimeDispatchInfo};
 // A few exports that help ease life for downstream crates.
 pub use pallet_balances::Call as BalancesCall;
-pub use pallet_contracts::{Schedule as ContractsSchedule, WeightInfo};
+pub use pallet_contracts::{Schedule as ContractsSchedule };
 pub use frame_support::{
     construct_runtime,
     dispatch::DispatchResult,
@@ -47,10 +47,11 @@
     },
     weights::{
         constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
-        DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight,
+        DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight,
         WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients
     },
 };
+use pallet_contracts::weights::WeightInfo;
 // #[cfg(any(feature = "std", test))]
 use frame_system::{
     self as system,
@@ -64,7 +65,7 @@
 pub use pallet_timestamp::Call as TimestampCall;
 
 mod chain_extension;
-use crate::chain_extension::NFTExtension;
+use crate::chain_extension::{ NFTExtension, Imbalance };
 
 /// Struct that handles the conversion of Balance -> `u64`. This is used for
 /// staking's election calculation.
@@ -229,6 +230,21 @@
 	}
 }
 
+// impl OnUnbalanced<NegativeImbalance> for DealWithFees {
+// 	fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance>) {
+// 		if let Some(fees) = fees_then_tips.next() {
+// 			// for fees, 100% to treasury
+// 			let mut split = fees.ration(100, 0);
+// 			if let Some(tips) = fees_then_tips.next() {
+// 				// for tips, if any, 100% to treasury
+// 				tips.ration_merge_into(100, 0, &mut split);
+// 			}
+// 			Treasury::on_unbalanced(split.0);
+// 			// Author::on_unbalanced(split.1);
+// 		}
+// 	}
+// }
+
 /// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
 /// This is used to limit the maximal weight of a single extrinsic.
 const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
@@ -388,6 +404,7 @@
 	pub const SignedClaimHandicap: u32 = 2;
 	pub const MaxDepth: u32 = 32;
 	pub const MaxValueSize: u32 = 16 * 1024;
+	pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb 
 	// The lazy deletion runs inside on_initialize.
 	pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
 		RuntimeBlockWeights::get().max_block;
@@ -420,6 +437,7 @@
 	type ChainExtension = NFTExtension;
 	type DeletionQueueDepth = DeletionQueueDepth;
 	type DeletionWeightLimit = DeletionWeightLimit;
+	type MaxCodeSize = MaxCodeSize;
 }
 
 parameter_types! {
@@ -518,7 +536,7 @@
         RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
         Contracts: pallet_contracts::{Module, Call, Config<T>, Storage, Event<T>},
         Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
-        Aura: pallet_aura::{Module, Config<T>, Inherent},
+        Aura: pallet_aura::{Module, Config<T> },
         Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
         Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
         TransactionPayment: pallet_transaction_payment::{Module, Storage},
@@ -738,4 +756,4 @@
 			Ok(batches)
 		}
 	}
-}
+}
\ No newline at end of file
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -11,7 +11,9 @@
 import {
   createCollectionExpectSuccess,
   destroyCollectionExpectSuccess,
+  getGenericResult,
   IReFungibleTokenDataType,
+  setCollectionLimitsExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -92,6 +94,25 @@
       expect(token3Data.VariableData.toString()).to.be.equal('0x33');
     });
   });
+
+  it('Can mint amount of items equals to collection limits', async () => {
+    await usingApi(async (api) => {
+      const alice = privateKey('//Alice');
+
+      const collectionId = await createCollectionExpectSuccess();
+      await setCollectionLimitsExpectSuccess(alice, collectionId, {
+        TokenLimit: 2,
+      });
+      const args = [
+        { nft: ['A', 'A'] },
+        { nft: ['B', 'B'] },
+      ];
+      const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, alice.address, args);
+      const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+      const result = getGenericResult(events);
+      expect(result.success).to.be.true;
+    });
+  });
 });
 
 describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
@@ -175,4 +196,21 @@
       await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;
     });
   });
+
+  it('Fails when minting tokens exceeds collectionLimits amount', async () => {
+    await usingApi(async (api) => {
+      const alice = privateKey('//Alice');
+
+      const collectionId = await createCollectionExpectSuccess();
+      await setCollectionLimitsExpectSuccess(alice, collectionId, {
+        TokenLimit: 1,
+      });
+      const args = [
+        { nft: ['A', 'A'] },
+        { nft: ['B', 'B'] },
+      ];
+      const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, alice.address, args);
+      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
+    });
+  });
 });
modifiedtests/src/util/contracthelpers.tsdiffbeforeafterboth
--- a/tests/src/util/contracthelpers.ts
+++ b/tests/src/util/contracthelpers.ts
@@ -20,35 +20,20 @@
 const gasLimit = '200000000000';
 const endowment = '100000000000000000';
 
-function deployBlueprint(alice: IKeyringPair, code: CodePromise): Promise<Blueprint> {
-  return new Promise<Blueprint>(async (resolve, reject) => {
+function deployContract(alice: IKeyringPair, code: CodePromise, constructor: string = 'default', ...args: any[]): Promise<Contract> {
+  return new Promise<Contract>(async (resolve, reject) => {
     const unsub = await code
-      .createBlueprint()
+      .tx[constructor]({value: endowment, gasLimit}, ...args)
       .signAndSend(alice, (result) => {
         if (result.status.isInBlock || result.status.isFinalized) {
           // here we have an additional field in the result, containing the blueprint
-          resolve(result.blueprint);
+          resolve((result as any).contract);
           unsub();
         }
       })
   });
 }
 
-function deployContract(alice: IKeyringPair, blueprint: Blueprint) : Promise<any> {
-  return new Promise<any>(async (resolve, reject) => {
-    const initValue = true;
-
-    const unsub = await blueprint.tx
-    .new(endowment, gasLimit, initValue)
-    .signAndSend(alice, (result) => {
-      if (result.status.isInBlock || result.status.isFinalized) {
-        unsub();
-        resolve(result);
-      }
-    });    
-  });
-}
-
 async function prepareDeployer(api: ApiPromise) {
   // Find unused address
   const deployer = await findUnusedAddress(api);
@@ -74,8 +59,7 @@
 
   const code = new CodePromise(api, abi, wasm);
 
-  const blueprint = await deployBlueprint(deployer, code);
-  const contract = (await deployContract(deployer, blueprint))['contract'] as Contract;
+  const contract = (await deployContract(deployer, code, 'new', true)) as Contract;
 
   const initialGetResponse = await getFlipValue(contract, deployer);
   expect(initialGetResponse).to.be.true;
@@ -128,8 +112,7 @@
 
   const code = new CodePromise(api, abi, wasm);
 
-  const blueprint = await deployBlueprint(deployer, code);
-  const contract = (await instantiateTransferContract(deployer, blueprint))['contract'] as Contract;
+  const contract = await deployContract(deployer, code);
 
   return [contract, deployer];
 }