git.delta.rocks / unique-network / refs/commits / 13bdc4a404c1

difftreelog

Chain extensions - changes in substrate

Greg Zaitsev2021-01-25parent: #e2c3f45.patch.diff
in: master

10 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,9 +12,9 @@
 
 [[package]]
 name = "addr2line"
-version = "0.14.0"
+version = "0.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
+checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
 dependencies = [
  "gimli 0.23.0",
 ]
@@ -65,7 +65,7 @@
 checksum = "63dd91889c49327ad7ef3b500fd1109dbd3c509a03db0d4a9ce413b79f575cb6"
 dependencies = [
  "block-cipher",
- "byteorder 1.3.4",
+ "byteorder",
  "opaque-debug 0.3.0",
 ]
 
@@ -78,21 +78,6 @@
  "block-cipher",
  "opaque-debug 0.3.0",
 ]
-
-[[package]]
-name = "ahash"
-version = "0.2.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29661b60bec623f0586702976ff4d0c9942dcb6723161c2df0eea78455cfedfb"
-dependencies = [
- "const-random",
-]
-
-[[package]]
-name = "ahash"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
 
 [[package]]
 name = "ahash"
@@ -110,17 +95,6 @@
 ]
 
 [[package]]
-name = "alga"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2"
-dependencies = [
- "approx",
- "num-complex",
- "num-traits",
-]
-
-[[package]]
 name = "ansi_term"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -140,9 +114,9 @@
 
 [[package]]
 name = "anyhow"
-version = "1.0.35"
+version = "1.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
+checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
 
 [[package]]
 name = "approx"
@@ -152,12 +126,6 @@
 dependencies = [
  "num-traits",
 ]
-
-[[package]]
-name = "arc-swap"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8"
 
 [[package]]
 name = "arrayref"
@@ -220,21 +188,24 @@
  "concurrent-queue",
  "fastrand",
  "futures-lite",
- "once_cell 1.5.2",
+ "once_cell",
  "vec-arena",
 ]
 
 [[package]]
 name = "async-global-executor"
-version = "1.4.3"
+version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04"
+checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6"
 dependencies = [
+ "async-channel",
  "async-executor",
  "async-io",
+ "async-mutex",
+ "blocking",
  "futures-lite",
  "num_cpus",
- "once_cell 1.5.2",
+ "once_cell",
 ]
 
 [[package]]
@@ -249,7 +220,7 @@
  "libc",
  "log",
  "nb-connect",
- "once_cell 1.5.2",
+ "once_cell",
  "parking",
  "polling",
  "vec-arena",
@@ -258,6 +229,15 @@
 ]
 
 [[package]]
+name = "async-lock"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1996609732bde4a9988bc42125f55f2af5f3c36370e27c778d5191a4a1b63bfb"
+dependencies = [
+ "event-listener",
+]
+
+[[package]]
 name = "async-mutex"
 version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -277,23 +257,22 @@
  "cfg-if 0.1.10",
  "event-listener",
  "futures-lite",
- "once_cell 1.5.2",
+ "once_cell",
  "signal-hook",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "async-std"
-version = "1.8.0"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f9f84f1280a2b436a2c77c2582602732b6c2f4321d5494d6e799e6c367859a8"
+checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341"
 dependencies = [
  "async-channel",
  "async-global-executor",
  "async-io",
- "async-mutex",
+ "async-lock",
  "async-process",
- "blocking",
  "crossbeam-utils 0.8.1",
  "futures-channel",
  "futures-core",
@@ -304,8 +283,8 @@
  "log",
  "memchr",
  "num_cpus",
- "once_cell 1.5.2",
- "pin-project-lite 0.2.0",
+ "once_cell",
+ "pin-project-lite 0.2.4",
  "pin-utils",
  "slab",
  "wasm-bindgen-futures",
@@ -318,18 +297,6 @@
 checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
 
 [[package]]
-name = "async-tls"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df097e3f506bec0e1a24f06bb3c962c228f36671de841ff579cb99f371772634"
-dependencies = [
- "futures 0.3.8",
- "rustls",
- "webpki",
- "webpki-roots 0.19.0",
-]
-
-[[package]]
 name = "async-trait"
 version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -341,10 +308,26 @@
 ]
 
 [[package]]
+name = "asynchronous-codec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb4401f0a3622dad2e0763fa79e0eb328bc70fb7dccfdd645341f00d671247d6"
+dependencies = [
+ "bytes 1.0.1",
+ "futures-sink",
+ "futures-util",
+ "memchr",
+ "pin-project-lite 0.2.4",
+]
+
+[[package]]
 name = "atomic"
-version = "0.4.6"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64f46ca51dca4837f1520754d1c8c36636356b81553d928dc9c177025369a06e"
+checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281"
+dependencies = [
+ "autocfg",
+]
 
 [[package]]
 name = "atomic-waker"
@@ -362,12 +345,6 @@
  "libc",
  "winapi 0.3.9",
 ]
-
-[[package]]
-name = "autocfg"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
 
 [[package]]
 name = "autocfg"
@@ -377,15 +354,15 @@
 
 [[package]]
 name = "backtrace"
-version = "0.3.55"
+version = "0.3.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598"
+checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
 dependencies = [
  "addr2line",
  "cfg-if 1.0.0",
  "libc",
  "miniz_oxide",
- "object 0.22.0",
+ "object 0.23.0",
  "rustc-demangle",
 ]
 
@@ -394,12 +371,6 @@
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
-
-[[package]]
-name = "base64"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 
 [[package]]
 name = "base64"
@@ -419,7 +390,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "serde",
 ]
 
@@ -444,22 +415,7 @@
  "regex",
  "rustc-hash",
  "shlex",
- "which",
-]
-
-[[package]]
-name = "bip39"
-version = "0.6.0-beta.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7059804e226b3ac116519a252d7f5fb985a5ccc0e93255e036a5f7e7283323f4"
-dependencies = [
- "failure",
- "hashbrown 0.1.8",
- "hmac",
- "once_cell 0.1.8",
- "pbkdf2",
- "rand 0.6.5",
- "sha2 0.8.2",
+ "which 3.1.1",
 ]
 
 [[package]]
@@ -467,12 +423,6 @@
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-
-[[package]]
-name = "bitmask"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead"
 
 [[package]]
 name = "bitvec"
@@ -510,17 +460,6 @@
 version = "0.5.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "constant_time_eq",
-]
-
-[[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",
@@ -535,7 +474,7 @@
 dependencies = [
  "block-padding 0.1.5",
  "byte-tools",
- "byteorder 1.3.4",
+ "byteorder",
  "generic-array 0.12.3",
 ]
 
@@ -584,17 +523,11 @@
  "atomic-waker",
  "fastrand",
  "futures-lite",
- "once_cell 1.5.2",
+ "once_cell",
 ]
 
 [[package]]
 name = "bs58"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
-
-[[package]]
-name = "bs58"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
@@ -628,15 +561,9 @@
 
 [[package]]
 name = "byteorder"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
-
-[[package]]
-name = "byteorder"
-version = "1.3.4"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
 
 [[package]]
 name = "bytes"
@@ -644,7 +571,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "either",
  "iovec",
 ]
@@ -656,10 +583,10 @@
 checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
 
 [[package]]
-name = "c_linked_list"
-version = "1.1.1"
+name = "bytes"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b"
+checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
 
 [[package]]
 name = "cache-padded"
@@ -734,6 +661,15 @@
 ]
 
 [[package]]
+name = "cipher"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
+dependencies = [
+ "generic-array 0.14.4",
+]
+
+[[package]]
 name = "clang-sys"
 version = "0.29.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -778,32 +714,10 @@
 ]
 
 [[package]]
-name = "const-random"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4"
-dependencies = [
- "const-random-macro",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "const-random-macro"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40"
-dependencies = [
- "getrandom 0.2.0",
- "lazy_static",
- "proc-macro-hack",
- "tiny-keccak",
-]
-
-[[package]]
 name = "const_fn"
-version = "0.4.4"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
+checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
 
 [[package]]
 name = "constant_time_eq"
@@ -854,7 +768,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9d9badfe36176cb653506091693bc2bb1970c9bddfcd6ec7fac404f7eaec6f38"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "cranelift-bforest",
  "cranelift-codegen-meta",
  "cranelift-codegen-shared",
@@ -863,7 +777,7 @@
  "log",
  "regalloc",
  "serde",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "target-lexicon",
  "thiserror",
 ]
@@ -901,7 +815,7 @@
 dependencies = [
  "cranelift-codegen",
  "log",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "target-lexicon",
 ]
 
@@ -978,13 +892,13 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "cfg-if 0.1.10",
  "crossbeam-utils 0.7.2",
  "lazy_static",
  "maybe-uninit",
  "memoffset 0.5.6",
- "scopeguard 1.1.0",
+ "scopeguard",
 ]
 
 [[package]]
@@ -998,7 +912,7 @@
  "crossbeam-utils 0.8.1",
  "lazy_static",
  "memoffset 0.6.1",
- "scopeguard 1.1.0",
+ "scopeguard",
 ]
 
 [[package]]
@@ -1018,7 +932,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "cfg-if 0.1.10",
  "lazy_static",
 ]
@@ -1029,7 +943,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "cfg-if 1.0.0",
  "lazy_static",
 ]
@@ -1071,21 +985,22 @@
 
 [[package]]
 name = "cuckoofilter"
-version = "0.3.2"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f"
+checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18"
 dependencies = [
- "byteorder 0.5.3",
- "rand 0.3.23",
+ "byteorder",
+ "fnv",
+ "rand 0.7.3",
 ]
 
 [[package]]
 name = "curve25519-dalek"
-version = "2.1.0"
+version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5"
+checksum = "434e1720189a637d44fe464f4df1e6eb900b4835255b14354497c78af37d9bb8"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "digest 0.8.1",
  "rand_core 0.5.1",
  "subtle 2.4.0",
@@ -1094,11 +1009,11 @@
 
 [[package]]
 name = "curve25519-dalek"
-version = "3.0.0"
+version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8492de420e9e60bc9a1d66e2dbb91825390b738a388606600663fc529b4b307"
+checksum = "f627126b946c25a4638eec0ea634fc52506dea98db118aae985118ce7c3d723f"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "digest 0.9.0",
  "rand_core 0.5.1",
  "subtle 2.4.0",
@@ -1151,6 +1066,15 @@
 ]
 
 [[package]]
+name = "directories"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
 name = "dirs-sys"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1167,8 +1091,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea"
 dependencies = [
- "byteorder 1.3.4",
- "quick-error",
+ "byteorder",
+ "quick-error 1.2.3",
 ]
 
 [[package]]
@@ -1194,9 +1118,9 @@
 
 [[package]]
 name = "dyn-clone"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804"
+checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf"
 
 [[package]]
 name = "ed25519"
@@ -1213,7 +1137,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
 dependencies = [
- "curve25519-dalek 3.0.0",
+ "curve25519-dalek 3.0.2",
  "ed25519",
  "rand 0.7.3",
  "serde",
@@ -1268,9 +1192,9 @@
 
 [[package]]
 name = "erased-serde"
-version = "0.3.12"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ca8b296792113e1500fd935ae487be6e00ce318952a6880555554824d6ebf38"
+checksum = "0465971a8cc1fa2455c8465aaa377131e1f1cf4983280f474a13e68793aa770c"
 dependencies = [
  "serde",
 ]
@@ -1308,7 +1232,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
 ]
 
 [[package]]
@@ -1380,7 +1304,7 @@
 checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b"
 dependencies = [
  "either",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 2.0.2",
  "log",
  "num-traits",
@@ -1390,12 +1314,12 @@
 
 [[package]]
 name = "fixed-hash"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c"
+checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c"
 dependencies = [
- "byteorder 1.3.4",
- "rand 0.7.3",
+ "byteorder",
+ "rand 0.8.2",
  "rustc-hex",
  "static_assertions",
 ]
@@ -1443,8 +1367,8 @@
 
 [[package]]
 name = "fork-tree"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
 ]
@@ -1461,8 +1385,8 @@
 
 [[package]]
 name = "frame-benchmarking"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -1479,17 +1403,22 @@
 
 [[package]]
 name = "frame-benchmarking-cli"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "Inflector",
+ "chrono",
  "frame-benchmarking",
+ "handlebars",
  "parity-scale-codec",
  "sc-cli",
  "sc-client-db",
  "sc-executor",
  "sc-service",
+ "serde",
  "sp-core",
  "sp-externalities",
+ "sp-keystore",
  "sp-runtime",
  "sp-state-machine",
  "structopt",
@@ -1497,8 +1426,8 @@
 
 [[package]]
 name = "frame-executive"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -1513,8 +1442,8 @@
 
 [[package]]
 name = "frame-metadata"
-version = "12.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "12.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "serde",
@@ -1524,19 +1453,19 @@
 
 [[package]]
 name = "frame-support"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "bitmask",
+ "bitflags",
  "frame-metadata",
  "frame-support-procedural",
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "log",
- "once_cell 1.5.2",
+ "once_cell",
  "parity-scale-codec",
  "paste",
  "serde",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "sp-arithmetic",
  "sp-core",
  "sp-inherents",
@@ -1549,9 +1478,10 @@
 
 [[package]]
 name = "frame-support-procedural"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "Inflector",
  "frame-support-procedural-tools",
  "proc-macro2",
  "quote",
@@ -1560,8 +1490,8 @@
 
 [[package]]
 name = "frame-support-procedural-tools"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support-procedural-tools-derive",
  "proc-macro-crate",
@@ -1572,8 +1502,8 @@
 
 [[package]]
 name = "frame-support-procedural-tools-derive"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1582,11 +1512,11 @@
 
 [[package]]
 name = "frame-system"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "serde",
  "sp-core",
@@ -1598,8 +1528,8 @@
 
 [[package]]
 name = "frame-system-benchmarking"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -1612,8 +1542,8 @@
 
 [[package]]
 name = "frame-system-rpc-runtime-api"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -1661,9 +1591,9 @@
 
 [[package]]
 name = "futures"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0"
+checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1676,34 +1606,19 @@
 
 [[package]]
 name = "futures-channel"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64"
+checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
 dependencies = [
  "futures-core",
  "futures-sink",
 ]
 
 [[package]]
-name = "futures-channel-preview"
-version = "0.3.0-alpha.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a"
-dependencies = [
- "futures-core-preview",
-]
-
-[[package]]
 name = "futures-core"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
-
-[[package]]
-name = "futures-core-preview"
-version = "0.3.0-alpha.19"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a"
+checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
 
 [[package]]
 name = "futures-cpupool"
@@ -1722,7 +1637,7 @@
 checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9"
 dependencies = [
  "futures 0.1.30",
- "futures 0.3.8",
+ "futures 0.3.12",
  "lazy_static",
  "log",
  "parking_lot 0.9.0",
@@ -1733,9 +1648,9 @@
 
 [[package]]
 name = "futures-executor"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65"
+checksum = "e9e59fdc009a4b3096bf94f740a0f2424c082521f20a9b08c5c07c48d90fd9b9"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -1745,30 +1660,30 @@
 
 [[package]]
 name = "futures-io"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb"
+checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
 
 [[package]]
 name = "futures-lite"
-version = "1.11.2"
+version = "1.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658"
+checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb"
 dependencies = [
  "fastrand",
  "futures-core",
  "futures-io",
  "memchr",
  "parking",
- "pin-project-lite 0.1.11",
+ "pin-project-lite 0.2.4",
  "waker-fn",
 ]
 
 [[package]]
 name = "futures-macro"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
+checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd"
 dependencies = [
  "proc-macro-hack",
  "proc-macro2",
@@ -1777,18 +1692,29 @@
 ]
 
 [[package]]
+name = "futures-rustls"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a1387e07917c711fb4ee4f48ea0adb04a3c9739e53ef85bf43ae1edc2937a8b"
+dependencies = [
+ "futures-io",
+ "rustls 0.19.0",
+ "webpki",
+]
+
+[[package]]
 name = "futures-sink"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
+checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
 
 [[package]]
 name = "futures-task"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
+checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"
 dependencies = [
- "once_cell 1.5.2",
+ "once_cell",
 ]
 
 [[package]]
@@ -1805,9 +1731,9 @@
 
 [[package]]
 name = "futures-util"
-version = "0.3.8"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
+checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
 dependencies = [
  "futures 0.1.30",
  "futures-channel",
@@ -1817,35 +1743,11 @@
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project 1.0.2",
+ "pin-project-lite 0.2.4",
  "pin-utils",
  "proc-macro-hack",
  "proc-macro-nested",
- "slab",
-]
-
-[[package]]
-name = "futures-util-preview"
-version = "0.3.0-alpha.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
-dependencies = [
- "futures-channel-preview",
- "futures-core-preview",
- "pin-utils",
  "slab",
-]
-
-[[package]]
-name = "futures_codec"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b"
-dependencies = [
- "bytes 0.5.6",
- "futures 0.3.8",
- "memchr",
- "pin-project 0.4.27",
 ]
 
 [[package]]
@@ -1855,23 +1757,19 @@
 checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
 
 [[package]]
-name = "generator"
-version = "0.6.23"
+name = "generic-array"
+version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc"
+checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
 dependencies = [
- "cc",
- "libc",
- "log",
- "rustc_version",
- "winapi 0.3.9",
+ "typenum",
 ]
 
 [[package]]
 name = "generic-array"
-version = "0.12.3"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
 dependencies = [
  "typenum",
 ]
@@ -1884,58 +1782,37 @@
 dependencies = [
  "typenum",
  "version_check",
-]
-
-[[package]]
-name = "get_if_addrs"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7"
-dependencies = [
- "c_linked_list",
- "get_if_addrs-sys",
- "libc",
- "winapi 0.2.8",
 ]
 
 [[package]]
-name = "get_if_addrs-sys"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48"
-dependencies = [
- "gcc",
- "libc",
-]
-
-[[package]]
 name = "getrandom"
-version = "0.1.15"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "libc",
  "wasi 0.9.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.2.0"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
+checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
+ "wasi 0.10.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "ghash"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6e27f0689a6e15944bdce7e45425efb87eaa8ab0c6e87f11d0987a9133e2531"
+checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375"
 dependencies = [
+ "opaque-debug 0.3.0",
  "polyval",
 ]
 
@@ -1994,7 +1871,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "bytes 0.4.12",
  "fnv",
  "futures 0.1.30",
@@ -2017,7 +1894,7 @@
  "futures-core",
  "futures-sink",
  "futures-util",
- "http 0.2.2",
+ "http 0.2.3",
  "indexmap",
  "slab",
  "tokio 0.2.24",
@@ -2027,6 +1904,20 @@
 ]
 
 [[package]]
+name = "handlebars"
+version = "3.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "964d0e99a61fe9b1b347389b77ebf8b7e1587b70293676aaca7d27e59b9073b2"
+dependencies = [
+ "log",
+ "pest",
+ "pest_derive",
+ "quick-error 2.0.0",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
 name = "hash-db"
 version = "0.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2039,61 +1930,31 @@
 checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2"
 dependencies = [
  "crunchy",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
-dependencies = [
- "byteorder 1.3.4",
- "scopeguard 0.3.3",
 ]
 
 [[package]]
 name = "hashbrown"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
-dependencies = [
- "ahash 0.2.19",
- "autocfg 0.1.7",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
-dependencies = [
- "ahash 0.3.8",
- "autocfg 1.0.1",
-]
-
-[[package]]
-name = "hashbrown"
 version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
 dependencies = [
- "ahash 0.4.7",
+ "ahash",
 ]
 
 [[package]]
 name = "heck"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
 dependencies = [
  "unicode-segmentation",
 ]
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.17"
+version = "0.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
 dependencies = [
  "libc",
 ]
@@ -2127,6 +1988,16 @@
 ]
 
 [[package]]
+name = "hmac"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
+dependencies = [
+ "crypto-mac 0.8.0",
+ "digest 0.9.0",
+]
+
+[[package]]
 name = "hmac-drbg"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2134,7 +2005,7 @@
 dependencies = [
  "digest 0.8.1",
  "generic-array 0.12.3",
- "hmac",
+ "hmac 0.7.1",
 ]
 
 [[package]]
@@ -2150,11 +2021,11 @@
 
 [[package]]
 name = "http"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26"
+checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
 dependencies = [
- "bytes 0.5.6",
+ "bytes 1.0.1",
  "fnv",
  "itoa",
 ]
@@ -2178,7 +2049,7 @@
 checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
 dependencies = [
  "bytes 0.5.6",
- "http 0.2.2",
+ "http 0.2.3",
 ]
 
 [[package]]
@@ -2199,7 +2070,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
 dependencies = [
- "quick-error",
+ "quick-error 1.2.3",
 ]
 
 [[package]]
@@ -2223,7 +2094,7 @@
  "time",
  "tokio 0.1.22",
  "tokio-buf",
- "tokio-executor 0.1.10",
+ "tokio-executor",
  "tokio-io",
  "tokio-reactor",
  "tokio-tcp",
@@ -2243,12 +2114,12 @@
  "futures-core",
  "futures-util",
  "h2 0.2.7",
- "http 0.2.2",
+ "http 0.2.3",
  "http-body 0.3.1",
  "httparse",
  "httpdate",
  "itoa",
- "pin-project 1.0.2",
+ "pin-project 1.0.4",
  "socket2",
  "tokio 0.2.24",
  "tower-service",
@@ -2267,7 +2138,7 @@
  "futures-util",
  "hyper 0.13.9",
  "log",
- "rustls",
+ "rustls 0.18.1",
  "rustls-native-certs",
  "tokio 0.2.24",
  "tokio-rustls",
@@ -2297,6 +2168,43 @@
 ]
 
 [[package]]
+name = "if-addrs"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28538916eb3f3976311f5dfbe67b5362d0add1293d0a9cad17debf86f8e3aa48"
+dependencies = [
+ "if-addrs-sys",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "if-addrs-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de74b9dd780476e837e5eb5ab7c88b49ed304126e412030a0adba99c8efe79ea"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "if-watch"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16d7c5e361e6b05c882b4847dd98992534cebc6fcde7f4bc98225bcf10fd6d0d"
+dependencies = [
+ "async-io",
+ "futures 0.3.12",
+ "futures-lite",
+ "if-addrs",
+ "ipnet",
+ "libc",
+ "log",
+ "winapi 0.3.9",
+]
+
+[[package]]
 name = "impl-codec"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2326,13 +2234,24 @@
 ]
 
 [[package]]
+name = "impl-trait-for-tuples"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f65a8ecf74feeacdab8d38cb129e550ca871cccaa7d1921d8636ecd75534903"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "indexmap"
 version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
 dependencies = [
- "autocfg 1.0.1",
- "hashbrown 0.9.1",
+ "autocfg",
+ "hashbrown",
  "serde",
 ]
 
@@ -2360,7 +2279,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 2.0.2",
 ]
 
@@ -2387,15 +2306,6 @@
 
 [[package]]
 name = "itertools"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itertools"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
@@ -2405,9 +2315,9 @@
 
 [[package]]
 name = "itoa"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
 
 [[package]]
 name = "jobserver"
@@ -2576,30 +2486,30 @@
 
 [[package]]
 name = "kvdb"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0315ef2f688e33844400b31f11c263f2b3dc21d8b9355c6891c5f185fae43f9a"
+checksum = "92312348daade49976a6dc59263ad39ed54f840aacb5664874f7c9aa16e5f848"
 dependencies = [
  "parity-util-mem",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
 ]
 
 [[package]]
 name = "kvdb-memorydb"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73de822b260a3bdfb889dbbb65bb2d473eee2253973d6fa4a5d149a2a4a7c66e"
+checksum = "986052a8d16c692eaebe775391f9a3ac26714f3907132658500b601dec94c8c2"
 dependencies = [
  "kvdb",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
 ]
 
 [[package]]
 name = "kvdb-rocksdb"
-version = "0.9.1"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44947dd392f09475af614d740fe0320b66d01cb5b977f664bbbb5e45a70ea4c1"
+checksum = "8d92c36be64baba5ea549116ff0d7ffd445456a7be8aaee21ec05882b980cd11"
 dependencies = [
  "fs-swap",
  "kvdb",
@@ -2607,10 +2517,10 @@
  "num_cpus",
  "owning_ref",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "regex",
  "rocksdb",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
 ]
 
 [[package]]
@@ -2633,9 +2543,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.81"
+version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
+checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
 
 [[package]]
 name = "libloading"
@@ -2655,13 +2565,13 @@
 
 [[package]]
 name = "libp2p"
-version = "0.28.1"
+version = "0.34.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "571f5a4604c1a40d75651da141dfde29ad15329f537a779528803297d2220274"
+checksum = "d5133112ce42be9482f6a87be92a605dd6bbc9e93c297aee77d172ff06908f3a"
 dependencies = [
  "atomic",
- "bytes 0.5.6",
- "futures 0.3.8",
+ "bytes 1.0.1",
+ "futures 0.3.12",
  "lazy_static",
  "libp2p-core",
  "libp2p-core-derive",
@@ -2684,26 +2594,25 @@
  "libp2p-wasm-ext",
  "libp2p-websocket",
  "libp2p-yamux",
- "multihash",
  "parity-multiaddr",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "smallvec 1.5.1",
+ "parking_lot 0.11.1",
+ "pin-project 1.0.4",
+ "smallvec 1.6.1",
  "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-core"
-version = "0.22.1"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52f13ba8c7df0768af2eb391696d562c7de88cc3a35122531aaa6a7d77754d25"
+checksum = "dad04d3cef6c1df366a6ab58c9cf8b06497699e335d83ac2174783946ff847d6"
 dependencies = [
  "asn1_der",
- "bs58 0.3.1",
+ "bs58",
  "ed25519-dalek",
  "either",
  "fnv",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "lazy_static",
  "libsecp256k1",
@@ -2711,26 +2620,26 @@
  "multihash",
  "multistream-select",
  "parity-multiaddr",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
+ "parking_lot 0.11.1",
+ "pin-project 1.0.4",
  "prost",
  "prost-build",
  "rand 0.7.3",
  "ring",
  "rw-stream-sink",
- "sha2 0.8.2",
- "smallvec 1.5.1",
+ "sha2 0.9.2",
+ "smallvec 1.6.1",
  "thiserror",
- "unsigned-varint 0.4.0",
+ "unsigned-varint 0.6.0",
  "void",
  "zeroize",
 ]
 
 [[package]]
 name = "libp2p-core-derive"
-version = "0.20.2"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213"
+checksum = "f4bc40943156e42138d22ed3c57ff0e1a147237742715937622a99b10fbe0156"
 dependencies = [
  "quote",
  "syn",
@@ -2738,179 +2647,180 @@
 
 [[package]]
 name = "libp2p-deflate"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74029ae187f35f4b8ddf26b9779a68b340045d708528a103917cdca49a296db5"
+checksum = "935893c0e5b6ca6ef60d5225aab9182f97c8c5671df2fa9dee8f4ed72a90e6eb"
 dependencies = [
  "flate2",
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
 ]
 
 [[package]]
 name = "libp2p-dns"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cf319822e08dd65c8e060d2354e9f952895bbc433f5706c75ed010c152aee5e"
+checksum = "5153b6db68fd4baa3b304e377db744dd8fea8ff4e4504509ee636abcde88d3e3"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "log",
 ]
 
 [[package]]
 name = "libp2p-floodsub"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a9acb43a3e4a4e413e0c4abe0fa49308df7c6335c88534757b647199cb8a51"
+checksum = "b3c63dfa06581b24b1d12bf9815b43689a784424be217d6545c800c7c75a207f"
 dependencies = [
  "cuckoofilter",
  "fnv",
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "libp2p-swarm",
+ "log",
  "prost",
  "prost-build",
  "rand 0.7.3",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
 ]
 
 [[package]]
 name = "libp2p-gossipsub"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab20fcb60edebe3173bbb708c6ac3444afdf1e3152dc2866b10c4f5497f17467"
+checksum = "12451ba9493e87c91baf2a6dffce9ddf1fbc807a0861532d7cf477954f8ebbee"
 dependencies = [
- "base64 0.11.0",
- "byteorder 1.3.4",
- "bytes 0.5.6",
+ "asynchronous-codec",
+ "base64 0.13.0",
+ "byteorder",
+ "bytes 1.0.1",
  "fnv",
- "futures 0.3.8",
- "futures_codec",
+ "futures 0.3.12",
  "hex_fmt",
  "libp2p-core",
  "libp2p-swarm",
  "log",
- "lru_time_cache",
  "prost",
  "prost-build",
  "rand 0.7.3",
- "sha2 0.8.2",
- "smallvec 1.5.1",
- "unsigned-varint 0.4.0",
+ "regex",
+ "sha2 0.9.2",
+ "smallvec 1.6.1",
+ "unsigned-varint 0.6.0",
  "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-identify"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56396ee63aa9164eacf40c2c5d2bda8c4133c2f57e1b0425d51d3a4e362583b1"
+checksum = "b40fb36a059b7a8cce1514bd8b546fa612e006c9937caa7f5950cb20021fe91e"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "libp2p-swarm",
  "log",
  "prost",
  "prost-build",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-kad"
-version = "0.23.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7fa9047f8b8f544278a35c2d9d45d3b2c1785f2d86d4e1629d6edf97be3955"
+checksum = "456f5de8e283d7800ca848b9b9a4e2a578b790bd8ae582b885e831353cf0e5df"
 dependencies = [
  "arrayvec 0.5.2",
- "bytes 0.5.6",
+ "asynchronous-codec",
+ "bytes 1.0.1",
  "either",
  "fnv",
- "futures 0.3.8",
- "futures_codec",
+ "futures 0.3.12",
  "libp2p-core",
  "libp2p-swarm",
  "log",
- "multihash",
  "prost",
  "prost-build",
  "rand 0.7.3",
- "sha2 0.8.2",
- "smallvec 1.5.1",
+ "sha2 0.9.2",
+ "smallvec 1.6.1",
  "uint",
- "unsigned-varint 0.4.0",
+ "unsigned-varint 0.6.0",
  "void",
  "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-mdns"
-version = "0.22.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3173b5a6b2f690c29ae07798d85b9441a131ac76ddae9015ef22905b623d0c69"
+checksum = "b974db63233fc0e199f4ede7794294aae285c96f4b6010f853eac4099ef08590"
 dependencies = [
- "async-std",
+ "async-io",
  "data-encoding",
  "dns-parser",
- "either",
- "futures 0.3.8",
+ "futures 0.3.12",
+ "if-watch",
  "lazy_static",
  "libp2p-core",
  "libp2p-swarm",
  "log",
- "net2",
  "rand 0.7.3",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
+ "socket2",
  "void",
- "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-mplex"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a73a799cc8410b36e40b8f4c4b6babbcb9efd3727111bf517876e4acfa612d3"
+checksum = "2705dc94b01ab9e3779b42a09bbf3712e637ed213e875c30face247291a85af0"
 dependencies = [
- "bytes 0.5.6",
- "fnv",
- "futures 0.3.8",
- "futures_codec",
+ "asynchronous-codec",
+ "bytes 1.0.1",
+ "futures 0.3.12",
  "libp2p-core",
  "log",
- "parking_lot 0.10.2",
- "unsigned-varint 0.4.0",
+ "nohash-hasher",
+ "parking_lot 0.11.1",
+ "rand 0.7.3",
+ "smallvec 1.6.1",
+ "unsigned-varint 0.6.0",
 ]
 
 [[package]]
 name = "libp2p-noise"
-version = "0.24.0"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef6c490042f549fb1025f2892dfe6083d97a77558f450c1feebe748ca9eb15a"
+checksum = "4aca322b52a0c5136142a7c3971446fb1e9964923a526c9cc6ef3b7c94e57778"
 dependencies = [
- "bytes 0.5.6",
- "curve25519-dalek 2.1.0",
- "futures 0.3.8",
+ "bytes 1.0.1",
+ "curve25519-dalek 3.0.2",
+ "futures 0.3.12",
  "lazy_static",
  "libp2p-core",
  "log",
  "prost",
  "prost-build",
  "rand 0.7.3",
- "sha2 0.8.2",
+ "sha2 0.9.2",
  "snow",
  "static_assertions",
- "x25519-dalek 0.6.0",
+ "x25519-dalek",
  "zeroize",
 ]
 
 [[package]]
 name = "libp2p-ping"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad063c21dfcea4518ac9e8bd4119d33a5b26c41e674f602f41f05617a368a5c8"
+checksum = "6f3813276d0708c8db0f500d8beda1bda9ad955723b9cb272c41f4727256f73c"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "libp2p-swarm",
  "log",
@@ -2921,31 +2831,30 @@
 
 [[package]]
 name = "libp2p-plaintext"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "903a12e99c72dbebefea258de887982adeacc7025baa1ceb10b7fa9928f54791"
+checksum = "48e8c1ec305c9949351925cdc7196b9570f4330477f5e47fbf5bb340b57e26ed"
 dependencies = [
- "bytes 0.5.6",
- "futures 0.3.8",
- "futures_codec",
+ "asynchronous-codec",
+ "bytes 1.0.1",
+ "futures 0.3.12",
  "libp2p-core",
  "log",
  "prost",
  "prost-build",
- "rw-stream-sink",
- "unsigned-varint 0.4.0",
+ "unsigned-varint 0.6.0",
  "void",
 ]
 
 [[package]]
 name = "libp2p-pnet"
-version = "0.19.2"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96b3c2d5d26a9500e959a0e19743897239a6c4be78dadf99b70414301a70c006"
+checksum = "6ce3374f3b28162db9d3442c9347c4f14cb01e8290052615c7d341d40eae0599"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "log",
- "pin-project 0.4.27",
+ "pin-project 1.0.4",
  "rand 0.7.3",
  "salsa20",
  "sha3",
@@ -2953,51 +2862,52 @@
 
 [[package]]
 name = "libp2p-request-response"
-version = "0.3.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c0c9e8a4cd69d97e9646c54313d007512f411aba8c5226cfcda16df6a6e84a3"
+checksum = "d37637a4b33b5390322ccc068a33897d0aa541daf4fec99f6a7efbf37295346e"
 dependencies = [
  "async-trait",
- "bytes 0.5.6",
- "futures 0.3.8",
+ "bytes 1.0.1",
+ "futures 0.3.12",
  "libp2p-core",
  "libp2p-swarm",
  "log",
- "lru 0.6.2",
+ "lru",
  "minicbor",
  "rand 0.7.3",
- "smallvec 1.5.1",
- "unsigned-varint 0.5.1",
+ "smallvec 1.6.1",
+ "unsigned-varint 0.6.0",
  "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-swarm"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7193e444210132237b81b755ec7fe53f1c4bd2f53cf719729b94c0c72eb6eaa1"
+checksum = "22ea8c69839a0e593c8c6a24282cb234d48ac37be4153183f4914e00f5303e75"
 dependencies = [
  "either",
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "log",
  "rand 0.7.3",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "void",
  "wasm-timer",
 ]
 
 [[package]]
 name = "libp2p-tcp"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44f42ec130d7a37a7e47bf4398026b7ad9185c08ed26972e2720f8b94112796f"
+checksum = "3dbd3d7076a478ac5a6aca55e74bdc250ac539b95de09b9d09915e0b8d01a6b2"
 dependencies = [
- "async-std",
- "futures 0.3.8",
+ "async-io",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
- "get_if_addrs",
+ "if-watch",
  "ipnet",
+ "libc",
  "libp2p-core",
  "log",
  "socket2",
@@ -3005,23 +2915,23 @@
 
 [[package]]
 name = "libp2p-uds"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dea7acb0a034f70d7db94c300eba3f65c0f6298820105624088a9609c9974d77"
+checksum = "80ac51ce419f60be966e02103c17f67ff5dc4422ba83ba54d251d6c62a4ed487"
 dependencies = [
  "async-std",
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "log",
 ]
 
 [[package]]
 name = "libp2p-wasm-ext"
-version = "0.22.0"
+version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34c1faac6f92c21fbe155417957863ea822fba9e9fd5eb24c0912336a100e63f"
+checksum = "6149c46cb76935c80bc8be6ec6e3ebd5f5e1679765a255fb34331d54610f15dd"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "js-sys",
  "libp2p-core",
  "parity-send-wrapper",
@@ -3031,31 +2941,29 @@
 
 [[package]]
 name = "libp2p-websocket"
-version = "0.23.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d650534ebd99f48f6fa292ed5db10d30df2444943afde4407ceeddab8e513fca"
+checksum = "d3b1c6a3431045da8b925ed83384e4c5163e14b990572307fca9c507435d4d22"
 dependencies = [
- "async-tls",
  "either",
- "futures 0.3.8",
+ "futures 0.3.12",
+ "futures-rustls",
  "libp2p-core",
  "log",
  "quicksink",
- "rustls",
  "rw-stream-sink",
  "soketto",
  "url 2.2.0",
- "webpki",
- "webpki-roots 0.18.0",
+ "webpki-roots",
 ]
 
 [[package]]
 name = "libp2p-yamux"
-version = "0.25.0"
+version = "0.30.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "781d9b9f043dcdabc40640807125368596b849fd4d96cdca2dcf052fdf6f33fd"
+checksum = "490b8b27fc40fe35212df1b6a3d14bffaa4117cbff956fdc2892168a371102ad"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p-core",
  "parking_lot 0.11.1",
  "thiserror",
@@ -3103,9 +3011,9 @@
 
 [[package]]
 name = "linked-hash-map"
-version = "0.5.3"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
+checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
 
 [[package]]
 name = "linked_hash_set"
@@ -3118,31 +3026,21 @@
 
 [[package]]
 name = "linregress"
-version = "0.1.7"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9290cf6f928576eeb9c096c6fad9d8d452a0a1a70a2bbffa6e36064eedc0aac9"
+checksum = "0d0ad4b5cc8385a881c561fac3501353d63d2a2b7a357b5064d71815c9a92724"
 dependencies = [
- "failure",
  "nalgebra",
  "statrs",
 ]
 
 [[package]]
 name = "lock_api"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
-dependencies = [
- "scopeguard 0.3.3",
-]
-
-[[package]]
-name = "lock_api"
 version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
 dependencies = [
- "scopeguard 1.1.0",
+ "scopeguard",
 ]
 
 [[package]]
@@ -3151,56 +3049,28 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
 dependencies = [
- "scopeguard 1.1.0",
+ "scopeguard",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
-dependencies = [
- "cfg-if 0.1.10",
-]
-
-[[package]]
-name = "loom"
-version = "0.3.6"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed"
+checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
 dependencies = [
  "cfg-if 0.1.10",
- "generator",
- "scoped-tls",
- "serde",
- "serde_json",
 ]
 
 [[package]]
 name = "lru"
-version = "0.4.3"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237"
+checksum = "3aae342b73d57ad0b8b364bd12584819f2c1fe9114285dfcf8b0722607671635"
 dependencies = [
- "hashbrown 0.6.3",
-]
-
-[[package]]
-name = "lru"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3abe07af102235a56ac9a6dd904aab1e05483e2e8afdfffec3598be55b1b7606"
-dependencies = [
- "hashbrown 0.9.1",
+ "hashbrown",
 ]
 
 [[package]]
-name = "lru_time_cache"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb241df5c4caeb888755363fc95f8a896618dc0d435e9e775f7930cb099beab"
-
-[[package]]
 name = "mach"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3210,6 +3080,12 @@
 ]
 
 [[package]]
+name = "maplit"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
+
+[[package]]
 name = "matchers"
 version = "0.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3261,7 +3137,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
 ]
 
 [[package]]
@@ -3270,17 +3146,17 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
 ]
 
 [[package]]
 name = "memory-db"
-version = "0.24.1"
+version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36f36ddb0b2cdc25d38babba472108798e3477f02be5165f038c5e393e50c57a"
+checksum = "6cbd2a22f201c03cc1706a727842490abfea17b7b53260358239828208daba3c"
 dependencies = [
  "hash-db",
- "hashbrown 0.8.2",
+ "hashbrown",
  "parity-util-mem",
 ]
 
@@ -3292,11 +3168,11 @@
 
 [[package]]
 name = "merlin"
-version = "2.0.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78"
+checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "keccak",
  "rand_core 0.5.1",
  "zeroize",
@@ -3304,18 +3180,18 @@
 
 [[package]]
 name = "minicbor"
-version = "0.5.1"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fc03ad6f8f548db7194a5ff5a6f96342ecae4e3ef67d2bf18bacc0e245cd041"
+checksum = "3265a9f5210bb726f81ef9c456ae0aff5321cd95748c0e71889b0e19d8f0332b"
 dependencies = [
  "minicbor-derive",
 ]
 
 [[package]]
 name = "minicbor-derive"
-version = "0.4.1"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c214bf3d90099b52f3e4b328ae0fe34837fd0fab683ad1e10fceb4629106df48"
+checksum = "130b9455e28a3f308f6579671816a6f2621e2e0cbf55dc2f886345bef699481e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3329,7 +3205,7 @@
 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
 dependencies = [
  "adler",
- "autocfg 1.0.1",
+ "autocfg",
 ]
 
 [[package]]
@@ -3416,20 +3292,32 @@
 
 [[package]]
 name = "multihash"
-version = "0.11.4"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567122ab6492f49b59def14ecc36e13e64dca4188196dd0cd41f9f3f979f3df6"
+checksum = "4dac63698b887d2d929306ea48b63760431ff8a24fac40ddb22f9c7f49fb7cab"
 dependencies = [
- "blake2b_simd",
- "blake2s_simd",
  "digest 0.9.0",
- "sha-1 0.9.2",
+ "generic-array 0.14.4",
+ "multihash-derive",
  "sha2 0.9.2",
- "sha3",
  "unsigned-varint 0.5.1",
 ]
 
 [[package]]
+name = "multihash-derive"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85ee3c48cb9d9b275ad967a0e96715badc13c6029adb92f34fa17b9ff28fd81f"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
 name = "multimap"
 version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3437,32 +3325,33 @@
 
 [[package]]
 name = "multistream-select"
-version = "0.8.5"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93faf2e41f9ee62fb01680ed48f3cc26652352327aa2e59869070358f6b7dd75"
+checksum = "10ddc0eb0117736f19d556355464fc87efc8ad98b29e3fd84f02531eb6e90840"
 dependencies = [
- "bytes 0.5.6",
- "futures 0.3.8",
+ "bytes 1.0.1",
+ "futures 0.3.12",
  "log",
- "pin-project 1.0.2",
- "smallvec 1.5.1",
- "unsigned-varint 0.5.1",
+ "pin-project 1.0.4",
+ "smallvec 1.6.1",
+ "unsigned-varint 0.6.0",
 ]
 
 [[package]]
 name = "nalgebra"
-version = "0.18.1"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2"
+checksum = "d6b6147c3d50b4f3cdabfe2ecc94a0191fd3d6ad58aefd9664cf396285883486"
 dependencies = [
- "alga",
  "approx",
- "generic-array 0.12.3",
+ "generic-array 0.13.2",
  "matrixmultiply",
  "num-complex",
  "num-rational",
  "num-traits",
- "rand 0.6.5",
+ "rand 0.7.3",
+ "rand_distr",
+ "simba",
  "typenum",
 ]
 
@@ -3498,12 +3387,12 @@
 
 [[package]]
 name = "nft"
-version = "2.0.0"
+version = "2.0.1"
 dependencies = [
  "flexi_logger",
  "frame-benchmarking",
  "frame-benchmarking-cli",
- "futures 0.3.8",
+ "futures 0.3.12",
  "jsonrpc-core",
  "log",
  "nft-runtime",
@@ -3517,10 +3406,12 @@
  "sc-consensus-aura",
  "sc-executor",
  "sc-finality-grandpa",
+ "sc-keystore",
  "sc-network",
  "sc-rpc",
  "sc-rpc-api",
  "sc-service",
+ "sc-telemetry",
  "sc-transaction-pool",
  "serde",
  "serde_json",
@@ -3541,7 +3432,7 @@
 
 [[package]]
 name = "nft-runtime"
-version = "2.0.0"
+version = "2.0.1"
 dependencies = [
  "frame-benchmarking",
  "frame-executive",
@@ -3581,19 +3472,6 @@
 ]
 
 [[package]]
-name = "nix"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
-dependencies = [
- "bitflags",
- "cc",
- "cfg-if 0.1.10",
- "libc",
- "void",
-]
-
-[[package]]
 name = "nodrop"
 version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3621,7 +3499,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-integer",
  "num-traits",
 ]
@@ -3632,7 +3510,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-traits",
 ]
 
@@ -3642,7 +3520,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-traits",
 ]
 
@@ -3652,7 +3530,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "num-bigint",
  "num-integer",
  "num-traits",
@@ -3664,7 +3542,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "libm",
 ]
 
@@ -3697,18 +3575,9 @@
 
 [[package]]
 name = "object"
-version = "0.22.0"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
-
-[[package]]
-name = "once_cell"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37"
-dependencies = [
- "parking_lot 0.7.1",
-]
+checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
 
 [[package]]
 name = "once_cell"
@@ -3748,8 +3617,8 @@
 
 [[package]]
 name = "pallet-aura"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3767,12 +3636,12 @@
 
 [[package]]
 name = "pallet-authorship"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "sp-authorship",
  "sp-inherents",
@@ -3782,8 +3651,8 @@
 
 [[package]]
 name = "pallet-balances"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -3796,16 +3665,16 @@
 
 [[package]]
 name = "pallet-contracts"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "bitflags",
  "frame-support",
  "frame-system",
  "pallet-contracts-primitives",
+ "pallet-contracts-proc-macro",
  "parity-scale-codec",
  "parity-wasm",
- "pwasm-utils",
+ "pwasm-utils 0.16.0",
  "serde",
  "sp-core",
  "sp-io",
@@ -3817,18 +3686,29 @@
 
 [[package]]
 name = "pallet-contracts-primitives"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "bitflags",
  "parity-scale-codec",
  "sp-runtime",
  "sp-std",
 ]
 
 [[package]]
+name = "pallet-contracts-proc-macro"
+version = "0.1.0"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "pallet-contracts-rpc"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "jsonrpc-core",
  "jsonrpc-core-client",
@@ -3846,8 +3726,8 @@
 
 [[package]]
 name = "pallet-contracts-rpc-runtime-api"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "pallet-contracts-primitives",
  "parity-scale-codec",
@@ -3857,31 +3737,14 @@
 ]
 
 [[package]]
-name = "pallet-finality-tracker"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
-dependencies = [
- "frame-support",
- "frame-system",
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "serde",
- "sp-finality-tracker",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
 name = "pallet-grandpa"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-authorship",
- "pallet-finality-tracker",
  "pallet-session",
  "parity-scale-codec",
  "serde",
@@ -3896,7 +3759,7 @@
 
 [[package]]
 name = "pallet-nft"
-version = "2.0.0"
+version = "2.0.1"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -3917,8 +3780,8 @@
 
 [[package]]
 name = "pallet-randomness-collective-flip"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3930,12 +3793,12 @@
 
 [[package]]
 name = "pallet-session"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.1.3",
  "pallet-timestamp",
  "parity-scale-codec",
  "serde",
@@ -3950,8 +3813,8 @@
 
 [[package]]
 name = "pallet-sudo"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -3964,13 +3827,13 @@
 
 [[package]]
 name = "pallet-timestamp"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "serde",
  "sp-inherents",
@@ -3982,15 +3845,14 @@
 
 [[package]]
 name = "pallet-transaction-payment"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
- "pallet-transaction-payment-rpc-runtime-api",
  "parity-scale-codec",
  "serde",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -3999,15 +3861,14 @@
 
 [[package]]
 name = "pallet-transaction-payment-rpc"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "jsonrpc-core",
  "jsonrpc-core-client",
  "jsonrpc-derive",
  "pallet-transaction-payment-rpc-runtime-api",
  "parity-scale-codec",
- "serde",
  "sp-api",
  "sp-blockchain",
  "sp-core",
@@ -4017,24 +3878,23 @@
 
 [[package]]
 name = "pallet-transaction-payment-rpc-runtime-api"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "frame-support",
+ "pallet-transaction-payment",
  "parity-scale-codec",
- "serde",
  "sp-api",
  "sp-runtime",
- "sp-std",
 ]
 
 [[package]]
 name = "pallet-treasury"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-support",
  "frame-system",
+ "impl-trait-for-tuples 0.2.0",
  "pallet-balances",
  "parity-scale-codec",
  "serde",
@@ -4044,8 +3904,8 @@
 
 [[package]]
 name = "pallet-vesting"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "enumflags2",
  "frame-support",
@@ -4072,27 +3932,27 @@
 
 [[package]]
 name = "parity-multiaddr"
-version = "0.9.6"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43244a26dc1ddd3097216bb12eaa6cf8a07b060c72718d9ebd60fd297d6401df"
+checksum = "8bfda2e46fc5e14122649e2645645a81ee5844e0fb2e727ef560cc71a8b2d801"
 dependencies = [
  "arrayref",
- "bs58 0.4.0",
- "byteorder 1.3.4",
+ "bs58",
+ "byteorder",
  "data-encoding",
  "multihash",
  "percent-encoding 2.1.0",
  "serde",
  "static_assertions",
- "unsigned-varint 0.5.1",
+ "unsigned-varint 0.6.0",
  "url 2.2.0",
 ]
 
 [[package]]
 name = "parity-scale-codec"
-version = "1.3.5"
+version = "1.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c740e5fbcb6847058b40ac7e5574766c6388f585e184d769910fe0d3a2ca861"
+checksum = "79602888a81ace83e3d1d4b2873286c1f5f906c84db667594e8db8da3506c383"
 dependencies = [
  "arrayvec 0.5.2",
  "bitvec",
@@ -4140,17 +4000,17 @@
 
 [[package]]
 name = "parity-util-mem"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c"
+checksum = "8f17f15cb05897127bf36a240085a1f0bbef7bce3024849eccf7f93f6171bc27"
 dependencies = [
- "cfg-if 0.1.10",
- "hashbrown 0.8.2",
- "impl-trait-for-tuples",
+ "cfg-if 1.0.0",
+ "hashbrown",
+ "impl-trait-for-tuples 0.2.0",
  "parity-util-mem-derive",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "primitive-types",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "winapi 0.3.9",
 ]
 
@@ -4177,7 +4037,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "bytes 0.4.12",
  "httparse",
  "log",
@@ -4194,16 +4054,6 @@
 version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
-
-[[package]]
-name = "parking_lot"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
-dependencies = [
- "lock_api 0.1.5",
- "parking_lot_core 0.4.0",
-]
 
 [[package]]
 name = "parking_lot"
@@ -4234,20 +4084,7 @@
 dependencies = [
  "instant",
  "lock_api 0.4.2",
- "parking_lot_core 0.8.1",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
-dependencies = [
- "libc",
- "rand 0.6.5",
- "rustc_version",
- "smallvec 0.6.13",
- "winapi 0.3.9",
+ "parking_lot_core 0.8.2",
 ]
 
 [[package]]
@@ -4259,9 +4096,9 @@
  "cfg-if 0.1.10",
  "cloudabi",
  "libc",
- "redox_syscall",
+ "redox_syscall 0.1.57",
  "rustc_version",
- "smallvec 0.6.13",
+ "smallvec 0.6.14",
  "winapi 0.3.9",
 ]
 
@@ -4274,22 +4111,22 @@
  "cfg-if 0.1.10",
  "cloudabi",
  "libc",
- "redox_syscall",
- "smallvec 1.5.1",
+ "redox_syscall 0.1.57",
+ "smallvec 1.6.1",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.8.1"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7c6d9b8427445284a09c55be860a15855ab580a417ccad9da88f5a06787ced0"
+checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
 dependencies = [
  "cfg-if 1.0.0",
  "instant",
  "libc",
- "redox_syscall",
- "smallvec 1.5.1",
+ "redox_syscall 0.1.57",
+ "smallvec 1.6.1",
  "winapi 0.3.9",
 ]
 
@@ -4318,12 +4155,26 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "crypto-mac 0.7.0",
- "rayon",
 ]
 
 [[package]]
+name = "pbkdf2"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd"
+dependencies = [
+ "crypto-mac 0.8.0",
+]
+
+[[package]]
+name = "pdqselect"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27"
+
+[[package]]
 name = "peeking_take_while"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4342,6 +4193,49 @@
 checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 
 [[package]]
+name = "pest"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+dependencies = [
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
+dependencies = [
+ "maplit",
+ "pest",
+ "sha-1 0.8.2",
+]
+
+[[package]]
 name = "petgraph"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4362,11 +4256,11 @@
 
 [[package]]
 name = "pin-project"
-version = "1.0.2"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7"
+checksum = "95b70b68509f17aa2857863b6fa00bf21fc93674c7a8893de2f469f6aa7ca2f2"
 dependencies = [
- "pin-project-internal 1.0.2",
+ "pin-project-internal 1.0.4",
 ]
 
 [[package]]
@@ -4382,9 +4276,9 @@
 
 [[package]]
 name = "pin-project-internal"
-version = "1.0.2"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f"
+checksum = "caa25a6393f22ce819b0f50e0be89287292fda8d425be38ee0ca14c4931d9e71"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4399,9 +4293,9 @@
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.0"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
+checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
 
 [[package]]
 name = "pin-utils"
@@ -4446,11 +4340,12 @@
 
 [[package]]
 name = "polyval"
-version = "0.4.3"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4fd92d8e0c06d08525d2e2643cc2b5c80c69ae8eb12c18272d501cd7079ccc0"
+checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd"
 dependencies = [
  "cpuid-bool 0.2.0",
+ "opaque-debug 0.3.0",
  "universal-hash",
 ]
 
@@ -4462,9 +4357,9 @@
 
 [[package]]
 name = "primitive-types"
-version = "0.7.3"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809"
+checksum = "b3824ae2c5e27160113b9e029a10ec9e3f0237bad8029f69c7724393c9fdefd8"
 dependencies = [
  "fixed-hash",
  "impl-codec",
@@ -4513,9 +4408,9 @@
 
 [[package]]
 name = "proc-macro-nested"
-version = "0.1.6"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
+checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
 
 [[package]]
 name = "proc-macro2"
@@ -4542,40 +4437,40 @@
 
 [[package]]
 name = "prost"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
+checksum = "9e6984d2f1a23009bd270b8bb56d0926810a3d483f59c987d77969e9d8e840b2"
 dependencies = [
- "bytes 0.5.6",
+ "bytes 1.0.1",
  "prost-derive",
 ]
 
 [[package]]
 name = "prost-build"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26"
+checksum = "32d3ebd75ac2679c2af3a92246639f9fcc8a442ee420719cc4fe195b98dd5fa3"
 dependencies = [
- "bytes 0.5.6",
+ "bytes 1.0.1",
  "heck",
- "itertools 0.8.2",
+ "itertools",
  "log",
  "multimap",
  "petgraph",
  "prost",
  "prost-types",
  "tempfile",
- "which",
+ "which 4.0.2",
 ]
 
 [[package]]
 name = "prost-derive"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
+checksum = "169a15f3008ecb5160cba7d37bcd690a7601b6d30cfb87a117d45e59d52af5d4"
 dependencies = [
  "anyhow",
- "itertools 0.8.2",
+ "itertools",
  "proc-macro2",
  "quote",
  "syn",
@@ -4583,11 +4478,11 @@
 
 [[package]]
 name = "prost-types"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
+checksum = "b518d7cdd93dab1d1122cf07fa9a60771836c668dde9d9e2a139f957f0d9f1bb"
 dependencies = [
- "bytes 0.5.6",
+ "bytes 1.0.1",
  "prost",
 ]
 
@@ -4597,7 +4492,18 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f53bc2558e8376358ebdc28301546471d67336584f6438ed4b7c7457a055fd7"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
+ "log",
+ "parity-wasm",
+]
+
+[[package]]
+name = "pwasm-utils"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c8ac87af529432d3a4f0e2b3bbf08af49f28f09cc73ed7e551161bdaef5f78d"
+dependencies = [
+ "byteorder",
  "log",
  "parity-wasm",
 ]
@@ -4609,6 +4515,12 @@
 checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
+name = "quick-error"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda"
+
+[[package]]
 name = "quicksink"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4621,9 +4533,9 @@
 
 [[package]]
 name = "quote"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
 dependencies = [
  "proc-macro2",
 ]
@@ -4654,38 +4566,6 @@
  "libc",
  "rand_core 0.3.1",
  "rdrand",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
-dependencies = [
- "cloudabi",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.3.1",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
-dependencies = [
- "autocfg 0.1.7",
- "libc",
- "rand_chacha 0.1.1",
- "rand_core 0.4.2",
- "rand_hc 0.1.0",
- "rand_isaac",
- "rand_jitter",
- "rand_os",
- "rand_pcg 0.1.2",
- "rand_xorshift",
  "winapi 0.3.9",
 ]
 
@@ -4695,22 +4575,24 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
- "getrandom 0.1.15",
+ "getrandom 0.1.16",
  "libc",
  "rand_chacha 0.2.2",
  "rand_core 0.5.1",
  "rand_hc 0.2.0",
- "rand_pcg 0.2.1",
+ "rand_pcg",
 ]
 
 [[package]]
-name = "rand_chacha"
-version = "0.1.1"
+name = "rand"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+checksum = "18519b42a40024d661e1714153e9ad0c3de27cd495760ceb09710920f1098b1e"
 dependencies = [
- "autocfg 0.1.7",
- "rand_core 0.3.1",
+ "libc",
+ "rand_chacha 0.3.0",
+ "rand_core 0.6.1",
+ "rand_hc 0.3.0",
 ]
 
 [[package]]
@@ -4724,6 +4606,16 @@
 ]
 
 [[package]]
+name = "rand_chacha"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.1",
+]
+
+[[package]]
 name = "rand_core"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4744,69 +4636,43 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
 dependencies = [
- "getrandom 0.1.15",
+ "getrandom 0.1.16",
 ]
 
 [[package]]
-name = "rand_hc"
-version = "0.1.0"
+name = "rand_core"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5"
 dependencies = [
- "rand_core 0.3.1",
+ "getrandom 0.2.2",
 ]
 
 [[package]]
-name = "rand_hc"
-version = "0.2.0"
+name = "rand_distr"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
 dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_isaac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
-dependencies = [
- "rand_core 0.3.1",
+ "rand 0.7.3",
 ]
 
 [[package]]
-name = "rand_jitter"
-version = "0.1.4"
+name = "rand_hc"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
 dependencies = [
- "libc",
- "rand_core 0.4.2",
- "winapi 0.3.9",
+ "rand_core 0.5.1",
 ]
 
 [[package]]
-name = "rand_os"
-version = "0.1.3"
+name = "rand_hc"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
 dependencies = [
- "cloudabi",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.4.2",
- "rdrand",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
-dependencies = [
- "autocfg 0.1.7",
- "rand_core 0.4.2",
+ "rand_core 0.6.1",
 ]
 
 [[package]]
@@ -4819,19 +4685,10 @@
 ]
 
 [[package]]
-name = "rand_xorshift"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
 name = "raw-cpuid"
-version = "7.0.3"
+version = "7.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf"
+checksum = "beb71f708fe39b2c5e98076204c3cc094ee5a4c12c4cdb119a2b72dc34164f41"
 dependencies = [
  "bitflags",
  "cc",
@@ -4850,7 +4707,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
 dependencies = [
- "autocfg 1.0.1",
+ "autocfg",
  "crossbeam-deque 0.8.0",
  "either",
  "rayon-core",
@@ -4885,30 +4742,39 @@
 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
 
 [[package]]
+name = "redox_syscall"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
 name = "redox_users"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
 dependencies = [
- "getrandom 0.1.15",
- "redox_syscall",
+ "getrandom 0.1.16",
+ "redox_syscall 0.1.57",
  "rust-argon2",
 ]
 
 [[package]]
 name = "ref-cast"
-version = "1.0.3"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece"
+checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da"
 dependencies = [
  "ref-cast-impl",
 ]
 
 [[package]]
 name = "ref-cast-impl"
-version = "1.0.3"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72"
+checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4923,14 +4789,14 @@
 dependencies = [
  "log",
  "rustc-hash",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
 ]
 
 [[package]]
 name = "regex"
-version = "1.4.2"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
+checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -4944,15 +4810,15 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "regex-syntax",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.21"
+version = "0.6.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
+checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
 
 [[package]]
 name = "region"
@@ -4977,9 +4843,9 @@
 
 [[package]]
 name = "retain_mut"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e005d658ad26eacc2b6c506dfde519f4e277e328d0eb3379ca61647d70a8f531"
+checksum = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1"
 
 [[package]]
 name = "ring"
@@ -4989,7 +4855,7 @@
 dependencies = [
  "cc",
  "libc",
- "once_cell 1.5.2",
+ "once_cell",
  "spin",
  "untrusted",
  "web-sys",
@@ -5008,9 +4874,9 @@
 
 [[package]]
 name = "rpassword"
-version = "4.0.5"
+version = "5.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f"
+checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb"
 dependencies = [
  "libc",
  "winapi 0.3.9",
@@ -5069,13 +4935,26 @@
 ]
 
 [[package]]
+name = "rustls"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b"
+dependencies = [
+ "base64 0.13.0",
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
+[[package]]
 name = "rustls-native-certs"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "629d439a7672da82dd955498445e496ee2096fe2117b9f796558a43fdb9e59b8"
 dependencies = [
  "openssl-probe",
- "rustls",
+ "rustls 0.18.1",
  "schannel",
  "security-framework",
 ]
@@ -5086,7 +4965,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "pin-project 0.4.27",
  "static_assertions",
 ]
@@ -5108,19 +4987,19 @@
 
 [[package]]
 name = "salsa20"
-version = "0.6.0"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7f47b10fa80f6969bbbd9c8e7cc998f082979d402a9e10579e2303a87955395"
+checksum = "399f290ffc409596022fce5ea5d4138184be4784f2b28c62c59f0d8389059a15"
 dependencies = [
- "stream-cipher",
+ "cipher",
 ]
 
 [[package]]
 name = "sc-basic-authorship"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "log",
  "parity-scale-codec",
@@ -5136,13 +5015,12 @@
  "sp-runtime",
  "sp-transaction-pool",
  "substrate-prometheus-endpoint",
- "tokio-executor 0.2.0-alpha.6",
 ]
 
 [[package]]
 name = "sc-block-builder"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sc-client-api",
@@ -5158,25 +5036,29 @@
 
 [[package]]
 name = "sc-chain-spec"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "sc-chain-spec-derive",
+ "sc-consensus-babe",
+ "sc-consensus-epochs",
+ "sc-finality-grandpa",
  "sc-network",
  "sc-telemetry",
  "serde",
  "serde_json",
  "sp-chain-spec",
+ "sp-consensus-babe",
  "sp-core",
  "sp-runtime",
 ]
 
 [[package]]
 name = "sc-chain-spec-derive"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -5186,30 +5068,21 @@
 
 [[package]]
 name = "sc-cli"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "ansi_term 0.12.1",
- "atty",
- "bip39",
  "chrono",
- "derive_more",
  "fdlimit",
- "flexi_logger",
- "futures 0.3.8",
+ "futures 0.3.12",
  "hex",
- "lazy_static",
  "libp2p",
  "log",
  "names",
- "nix",
  "parity-scale-codec",
- "parity-util-mem",
  "rand 0.7.3",
  "regex",
  "rpassword",
  "sc-client-api",
- "sc-informant",
  "sc-keystore",
  "sc-network",
  "sc-service",
@@ -5220,37 +5093,32 @@
  "sp-blockchain",
  "sp-core",
  "sp-keyring",
+ "sp-keystore",
  "sp-panic-handler",
  "sp-runtime",
- "sp-state-machine",
  "sp-utils",
  "sp-version",
  "structopt",
- "substrate-prometheus-endpoint",
- "time",
+ "thiserror",
+ "tiny-bip39",
  "tokio 0.2.24",
- "tracing",
- "tracing-log",
- "tracing-subscriber",
 ]
 
 [[package]]
 name = "sc-client-api"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
  "fnv",
- "futures 0.3.8",
+ "futures 0.3.12",
  "hash-db",
- "hex-literal",
  "kvdb",
  "lazy_static",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-executor",
- "sc-telemetry",
  "sp-api",
  "sp-blockchain",
  "sp-consensus",
@@ -5258,7 +5126,7 @@
  "sp-database",
  "sp-externalities",
  "sp-inherents",
- "sp-keyring",
+ "sp-keystore",
  "sp-runtime",
  "sp-state-machine",
  "sp-std",
@@ -5272,8 +5140,8 @@
 
 [[package]]
 name = "sc-client-db"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "blake2-rfc",
  "hash-db",
@@ -5285,7 +5153,7 @@
  "parity-db",
  "parity-scale-codec",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-client-api",
  "sc-executor",
  "sc-state-db",
@@ -5302,8 +5170,8 @@
 
 [[package]]
 name = "sc-consensus"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "sc-client-api",
  "sp-blockchain",
@@ -5313,19 +5181,18 @@
 
 [[package]]
 name = "sc-consensus-aura"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-block-builder",
  "sc-client-api",
  "sc-consensus-slots",
- "sc-keystore",
  "sc-telemetry",
  "sp-api",
  "sp-application-crypto",
@@ -5336,26 +5203,86 @@
  "sp-core",
  "sp-inherents",
  "sp-io",
+ "sp-keystore",
+ "sp-runtime",
+ "sp-timestamp",
+ "sp-version",
+ "substrate-prometheus-endpoint",
+]
+
+[[package]]
+name = "sc-consensus-babe"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "derive_more",
+ "fork-tree",
+ "futures 0.3.12",
+ "futures-timer 3.0.2",
+ "log",
+ "merlin",
+ "num-bigint",
+ "num-rational",
+ "num-traits",
+ "parity-scale-codec",
+ "parking_lot 0.11.1",
+ "pdqselect",
+ "rand 0.7.3",
+ "retain_mut",
+ "sc-client-api",
+ "sc-consensus-epochs",
+ "sc-consensus-slots",
+ "sc-consensus-uncles",
+ "sc-keystore",
+ "sc-telemetry",
+ "schnorrkel",
+ "serde",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-babe",
+ "sp-consensus-vrf",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-keystore",
  "sp-runtime",
  "sp-timestamp",
+ "sp-utils",
  "sp-version",
  "substrate-prometheus-endpoint",
 ]
 
 [[package]]
+name = "sc-consensus-epochs"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "fork-tree",
+ "parity-scale-codec",
+ "parking_lot 0.11.1",
+ "sc-client-api",
+ "sp-blockchain",
+ "sp-runtime",
+]
+
+[[package]]
 name = "sc-consensus-slots"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-client-api",
  "sc-telemetry",
  "sp-api",
  "sp-application-crypto",
+ "sp-arithmetic",
  "sp-blockchain",
  "sp-consensus",
  "sp-consensus-slots",
@@ -5363,12 +5290,28 @@
  "sp-inherents",
  "sp-runtime",
  "sp-state-machine",
+ "sp-trie",
+ "thiserror",
 ]
 
 [[package]]
+name = "sc-consensus-uncles"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "log",
+ "sc-client-api",
+ "sp-authorship",
+ "sp-consensus",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+]
+
+[[package]]
 name = "sc-executor"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
  "lazy_static",
@@ -5376,7 +5319,7 @@
  "log",
  "parity-scale-codec",
  "parity-wasm",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-executor-common",
  "sc-executor-wasmi",
  "sc-executor-wasmtime",
@@ -5387,6 +5330,7 @@
  "sp-panic-handler",
  "sp-runtime-interface",
  "sp-serializer",
+ "sp-tasks",
  "sp-trie",
  "sp-version",
  "sp-wasm-interface",
@@ -5395,25 +5339,24 @@
 
 [[package]]
 name = "sc-executor-common"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
- "log",
  "parity-scale-codec",
  "parity-wasm",
  "sp-allocator",
  "sp-core",
- "sp-runtime-interface",
  "sp-serializer",
  "sp-wasm-interface",
+ "thiserror",
  "wasmi",
 ]
 
 [[package]]
 name = "sc-executor-wasmi"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "log",
  "parity-scale-codec",
@@ -5427,13 +5370,13 @@
 
 [[package]]
 name = "sc-executor-wasmtime"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "log",
  "parity-scale-codec",
  "parity-wasm",
- "pwasm-utils",
+ "pwasm-utils 0.14.0",
  "sc-executor-common",
  "scoped-tls",
  "sp-allocator",
@@ -5445,17 +5388,17 @@
 
 [[package]]
 name = "sc-finality-grandpa"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
  "finality-grandpa",
  "fork-tree",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "pin-project 0.4.27",
  "rand 0.7.3",
  "sc-block-builder",
@@ -5473,8 +5416,8 @@
  "sp-consensus",
  "sp-core",
  "sp-finality-grandpa",
- "sp-finality-tracker",
  "sp-inherents",
+ "sp-keystore",
  "sp-runtime",
  "sp-utils",
  "substrate-prometheus-endpoint",
@@ -5482,11 +5425,11 @@
 
 [[package]]
 name = "sc-informant"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "ansi_term 0.12.1",
- "futures 0.3.8",
+ "futures 0.3.12",
  "log",
  "parity-util-mem",
  "sc-client-api",
@@ -5500,29 +5443,33 @@
 
 [[package]]
 name = "sc-keystore"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "async-trait",
  "derive_more",
+ "futures 0.3.12",
+ "futures-util",
  "hex",
  "merlin",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "rand 0.7.3",
  "serde_json",
  "sp-application-crypto",
  "sp-core",
+ "sp-keystore",
  "subtle 2.4.0",
 ]
 
 [[package]]
 name = "sc-light"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "hash-db",
  "lazy_static",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-client-api",
  "sc-executor",
  "sp-api",
@@ -5535,32 +5482,32 @@
 
 [[package]]
 name = "sc-network"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "async-std",
  "async-trait",
+ "asynchronous-codec",
  "bitflags",
- "bs58 0.3.1",
- "bytes 0.5.6",
+ "bs58",
+ "bytes 1.0.1",
  "derive_more",
  "either",
  "erased-serde",
  "fnv",
  "fork-tree",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
- "futures_codec",
  "hex",
  "ip_network",
  "libp2p",
  "linked-hash-map",
  "linked_hash_set",
  "log",
- "lru 0.4.3",
+ "lru",
  "nohash-hasher",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "pin-project 0.4.27",
  "prost",
  "prost-build",
@@ -5570,9 +5517,7 @@
  "sc-peerset",
  "serde",
  "serde_json",
- "slog",
- "slog_derive",
- "smallvec 0.6.13",
+ "smallvec 1.6.1",
  "sp-arithmetic",
  "sp-blockchain",
  "sp-consensus",
@@ -5581,7 +5526,7 @@
  "sp-utils",
  "substrate-prometheus-endpoint",
  "thiserror",
- "unsigned-varint 0.4.0",
+ "unsigned-varint 0.6.0",
  "void",
  "wasm-timer",
  "zeroize",
@@ -5589,34 +5534,35 @@
 
 [[package]]
 name = "sc-network-gossip"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "libp2p",
  "log",
- "lru 0.4.3",
+ "lru",
  "sc-network",
  "sp-runtime",
+ "substrate-prometheus-endpoint",
  "wasm-timer",
 ]
 
 [[package]]
 name = "sc-offchain"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "bytes 0.5.6",
  "fnv",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "hyper 0.13.9",
  "hyper-rustls",
  "log",
  "num_cpus",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "rand 0.7.3",
  "sc-client-api",
  "sc-keystore",
@@ -5631,10 +5577,10 @@
 
 [[package]]
 name = "sc-peerset"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "libp2p",
  "log",
  "serde_json",
@@ -5644,8 +5590,8 @@
 
 [[package]]
 name = "sc-proposer-metrics"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "log",
  "substrate-prometheus-endpoint",
@@ -5653,26 +5599,28 @@
 
 [[package]]
 name = "sc-rpc"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "hash-db",
  "jsonrpc-core",
  "jsonrpc-pubsub",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-block-builder",
  "sc-client-api",
  "sc-executor",
  "sc-keystore",
  "sc-rpc-api",
+ "sc-tracing",
  "serde_json",
  "sp-api",
  "sp-blockchain",
  "sp-chain-spec",
  "sp-core",
+ "sp-keystore",
  "sp-offchain",
  "sp-rpc",
  "sp-runtime",
@@ -5685,18 +5633,18 @@
 
 [[package]]
 name = "sc-rpc-api"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
- "futures 0.3.8",
+ "futures 0.3.12",
  "jsonrpc-core",
  "jsonrpc-core-client",
  "jsonrpc-derive",
  "jsonrpc-pubsub",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "serde",
  "serde_json",
  "sp-chain-spec",
@@ -5709,8 +5657,8 @@
 
 [[package]]
 name = "sc-rpc-server"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "futures 0.1.30",
  "jsonrpc-core",
@@ -5727,14 +5675,13 @@
 
 [[package]]
 name = "sc-service"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "derive_more",
- "directories",
+ "directories 3.0.1",
  "exit-future",
  "futures 0.1.30",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "hash-db",
  "jsonrpc-core",
@@ -5743,7 +5690,7 @@
  "log",
  "parity-scale-codec",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "pin-project 0.4.27",
  "rand 0.7.3",
  "sc-block-builder",
@@ -5763,7 +5710,6 @@
  "sc-transaction-pool",
  "serde",
  "serde_json",
- "slog",
  "sp-api",
  "sp-application-crypto",
  "sp-block-builder",
@@ -5773,6 +5719,7 @@
  "sp-externalities",
  "sp-inherents",
  "sp-io",
+ "sp-keystore",
  "sp-runtime",
  "sp-session",
  "sp-state-machine",
@@ -5783,75 +5730,99 @@
  "sp-version",
  "substrate-prometheus-endpoint",
  "tempfile",
+ "thiserror",
  "tracing",
+ "tracing-futures",
  "wasm-timer",
 ]
 
 [[package]]
 name = "sc-state-db"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "log",
  "parity-scale-codec",
  "parity-util-mem",
  "parity-util-mem-derive",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-client-api",
  "sp-core",
+ "thiserror",
 ]
 
 [[package]]
 name = "sc-telemetry"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
- "futures-timer 3.0.2",
+ "chrono",
+ "futures 0.3.12",
  "libp2p",
  "log",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "pin-project 0.4.27",
  "rand 0.7.3",
  "serde",
- "slog",
- "slog-json",
- "slog-scope",
+ "serde_json",
+ "sp-utils",
  "take_mut",
+ "tracing",
+ "tracing-subscriber",
  "void",
  "wasm-timer",
 ]
 
 [[package]]
 name = "sc-tracing"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "ansi_term 0.12.1",
+ "atty",
  "erased-serde",
+ "lazy_static",
  "log",
- "parking_lot 0.10.2",
+ "once_cell",
+ "parking_lot 0.11.1",
+ "regex",
  "rustc-hash",
  "sc-telemetry",
+ "sc-tracing-proc-macro",
  "serde",
  "serde_json",
- "slog",
  "sp-tracing",
+ "thiserror",
  "tracing",
  "tracing-core",
+ "tracing-log",
  "tracing-subscriber",
+ "wasm-bindgen",
+ "web-sys",
 ]
 
 [[package]]
-name = "sc-transaction-graph"
+name = "sc-tracing-proc-macro"
 version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "sc-transaction-graph"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
  "derive_more",
- "futures 0.3.8",
+ "futures 0.3.12",
  "linked-hash-map",
  "log",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "retain_mut",
  "serde",
  "sp-blockchain",
@@ -5859,22 +5830,22 @@
  "sp-runtime",
  "sp-transaction-pool",
  "sp-utils",
+ "thiserror",
  "wasm-timer",
 ]
 
 [[package]]
 name = "sc-transaction-pool"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "derive_more",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-diagnose",
  "intervalier",
  "log",
  "parity-scale-codec",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sc-client-api",
  "sc-transaction-graph",
  "sp-api",
@@ -5885,6 +5856,7 @@
  "sp-transaction-pool",
  "sp-utils",
  "substrate-prometheus-endpoint",
+ "thiserror",
  "wasm-timer",
 ]
 
@@ -5906,11 +5878,12 @@
 dependencies = [
  "arrayref",
  "arrayvec 0.5.2",
- "curve25519-dalek 2.1.0",
- "getrandom 0.1.15",
+ "curve25519-dalek 2.1.2",
+ "getrandom 0.1.16",
  "merlin",
  "rand 0.7.3",
  "rand_core 0.5.1",
+ "serde",
  "sha2 0.8.2",
  "subtle 2.4.0",
  "zeroize",
@@ -5921,12 +5894,6 @@
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
-
-[[package]]
-name = "scopeguard"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
 
 [[package]]
 name = "scopeguard"
@@ -5966,9 +5933,9 @@
 
 [[package]]
 name = "secrecy"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f"
+checksum = "0673d6a6449f5e7d12a1caf424fd9363e2af3a4953023ed455e3c4beef4597c0"
 dependencies = [
  "zeroize",
 ]
@@ -6013,18 +5980,18 @@
 
 [[package]]
 name = "serde"
-version = "1.0.118"
+version = "1.0.120"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
+checksum = "166b2349061381baf54a58e4b13c89369feb0ef2eaa57198899e2312aac30aab"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.118"
+version = "1.0.120"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
+checksum = "0ca2a8cb5805ce9e3b95435e3765b7b553cecc762d938d409434338386cb5775"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6033,9 +6000,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.60"
+version = "1.0.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
+checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a"
 dependencies = [
  "itoa",
  "ryu",
@@ -6106,12 +6073,11 @@
 
 [[package]]
 name = "sharded-slab"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127"
+checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
 dependencies = [
  "lazy_static",
- "loom",
 ]
 
 [[package]]
@@ -6122,9 +6088,9 @@
 
 [[package]]
 name = "signal-hook"
-version = "0.1.16"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed"
+checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
 dependencies = [
  "libc",
  "signal-hook-registry",
@@ -6132,83 +6098,51 @@
 
 [[package]]
 name = "signal-hook-registry"
-version = "1.2.2"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
+checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "signature"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210"
-
-[[package]]
-name = "slab"
-version = "0.4.2"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68"
 
 [[package]]
-name = "slog"
-version = "2.7.0"
+name = "simba"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
+checksum = "fb931b1367faadea6b1ab1c306a860ec17aaa5fa39f367d0c744e69d971a1fb2"
 dependencies = [
- "erased-serde",
+ "approx",
+ "num-complex",
+ "num-traits",
+ "paste",
 ]
 
 [[package]]
-name = "slog-json"
-version = "2.3.0"
+name = "slab"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a"
-dependencies = [
- "chrono",
- "erased-serde",
- "serde",
- "serde_json",
- "slog",
-]
+checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 
 [[package]]
-name = "slog-scope"
-version = "4.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6"
-dependencies = [
- "arc-swap",
- "lazy_static",
- "slog",
-]
-
-[[package]]
-name = "slog_derive"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
 name = "smallvec"
-version = "0.6.13"
+version = "0.6.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
+checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
 dependencies = [
  "maybe-uninit",
 ]
 
 [[package]]
 name = "smallvec"
-version = "1.5.1"
+version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75"
+checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
 
 [[package]]
 name = "snow"
@@ -6225,14 +6159,14 @@
  "rustc_version",
  "sha2 0.9.2",
  "subtle 2.4.0",
- "x25519-dalek 1.1.0",
+ "x25519-dalek",
 ]
 
 [[package]]
 name = "socket2"
-version = "0.3.18"
+version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97e0e9fd577458a4f61fb91fcb559ea2afecc54c934119421f9f5d3d5b1a1057"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
@@ -6248,7 +6182,7 @@
  "base64 0.12.3",
  "bytes 0.5.6",
  "flate2",
- "futures 0.3.8",
+ "futures 0.3.12",
  "httparse",
  "log",
  "rand 0.7.3",
@@ -6257,20 +6191,20 @@
 
 [[package]]
 name = "sp-allocator"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "derive_more",
  "log",
  "sp-core",
  "sp-std",
  "sp-wasm-interface",
+ "thiserror",
 ]
 
 [[package]]
 name = "sp-api"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "hash-db",
  "parity-scale-codec",
@@ -6280,12 +6214,13 @@
  "sp-state-machine",
  "sp-std",
  "sp-version",
+ "thiserror",
 ]
 
 [[package]]
 name = "sp-api-proc-macro"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "blake2-rfc",
  "proc-macro-crate",
@@ -6296,8 +6231,8 @@
 
 [[package]]
 name = "sp-application-crypto"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "serde",
@@ -6308,8 +6243,8 @@
 
 [[package]]
 name = "sp-arithmetic"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "integer-sqrt",
  "num-traits",
@@ -6321,8 +6256,8 @@
 
 [[package]]
 name = "sp-authorship"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-inherents",
@@ -6332,8 +6267,8 @@
 
 [[package]]
 name = "sp-block-builder"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -6344,25 +6279,26 @@
 
 [[package]]
 name = "sp-blockchain"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "derive_more",
+ "futures 0.3.12",
  "log",
- "lru 0.4.3",
+ "lru",
  "parity-scale-codec",
- "parking_lot 0.10.2",
- "sp-block-builder",
+ "parking_lot 0.11.1",
+ "sp-api",
  "sp-consensus",
  "sp-database",
  "sp-runtime",
  "sp-state-machine",
+ "thiserror",
 ]
 
 [[package]]
 name = "sp-chain-spec"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "serde",
  "serde_json",
@@ -6370,16 +6306,15 @@
 
 [[package]]
 name = "sp-consensus"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "derive_more",
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-timer 3.0.2",
  "libp2p",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "serde",
  "sp-api",
  "sp-core",
@@ -6391,13 +6326,14 @@
  "sp-utils",
  "sp-version",
  "substrate-prometheus-endpoint",
+ "thiserror",
  "wasm-timer",
 ]
 
 [[package]]
 name = "sp-consensus-aura"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -6409,26 +6345,57 @@
 ]
 
 [[package]]
+name = "sp-consensus-babe"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "merlin",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-consensus",
+ "sp-consensus-slots",
+ "sp-consensus-vrf",
+ "sp-core",
+ "sp-inherents",
+ "sp-keystore",
+ "sp-runtime",
+ "sp-std",
+ "sp-timestamp",
+]
+
+[[package]]
 name = "sp-consensus-slots"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-runtime",
 ]
 
 [[package]]
+name = "sp-consensus-vrf"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "parity-scale-codec",
+ "schnorrkel",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
 name = "sp-core"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "base58",
  "blake2-rfc",
- "byteorder 1.3.4",
- "derive_more",
+ "byteorder",
  "dyn-clonable",
  "ed25519-dalek",
- "futures 0.3.8",
+ "futures 0.3.12",
  "hash-db",
  "hash256-std-hasher",
  "hex",
@@ -6440,20 +6407,21 @@
  "num-traits",
  "parity-scale-codec",
  "parity-util-mem",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "primitive-types",
  "rand 0.7.3",
  "regex",
  "schnorrkel",
  "secrecy",
  "serde",
- "sha2 0.8.2",
+ "sha2 0.9.2",
  "sp-debug-derive",
  "sp-externalities",
  "sp-runtime-interface",
  "sp-std",
  "sp-storage",
  "substrate-bip39",
+ "thiserror",
  "tiny-bip39",
  "tiny-keccak",
  "twox-hash",
@@ -6463,17 +6431,17 @@
 
 [[package]]
 name = "sp-database"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "kvdb",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
 ]
 
 [[package]]
 name = "sp-debug-derive"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6482,8 +6450,8 @@
 
 [[package]]
 name = "sp-externalities"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "environmental",
  "parity-scale-codec",
@@ -6493,8 +6461,8 @@
 
 [[package]]
 name = "sp-finality-grandpa"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "finality-grandpa",
  "log",
@@ -6503,45 +6471,37 @@
  "sp-api",
  "sp-application-crypto",
  "sp-core",
+ "sp-keystore",
  "sp-runtime",
  "sp-std",
 ]
 
 [[package]]
-name = "sp-finality-tracker"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
-dependencies = [
- "parity-scale-codec",
- "sp-inherents",
- "sp-std",
-]
-
-[[package]]
 name = "sp-inherents"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "derive_more",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sp-core",
  "sp-std",
+ "thiserror",
 ]
 
 [[package]]
 name = "sp-io"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "hash-db",
  "libsecp256k1",
  "log",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "sp-core",
  "sp-externalities",
+ "sp-keystore",
  "sp-runtime-interface",
  "sp-state-machine",
  "sp-std",
@@ -6554,8 +6514,8 @@
 
 [[package]]
 name = "sp-keyring"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "lazy_static",
  "sp-core",
@@ -6564,9 +6524,26 @@
 ]
 
 [[package]]
+name = "sp-keystore"
+version = "0.8.0"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "async-trait",
+ "derive_more",
+ "futures 0.3.12",
+ "merlin",
+ "parity-scale-codec",
+ "parking_lot 0.11.1",
+ "schnorrkel",
+ "serde",
+ "sp-core",
+ "sp-externalities",
+]
+
+[[package]]
 name = "sp-offchain"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "sp-api",
  "sp-core",
@@ -6575,17 +6552,16 @@
 
 [[package]]
 name = "sp-panic-handler"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "backtrace",
- "log",
 ]
 
 [[package]]
 name = "sp-rpc"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "serde",
  "sp-core",
@@ -6593,12 +6569,12 @@
 
 [[package]]
 name = "sp-runtime"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "either",
  "hash256-std-hasher",
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "log",
  "parity-scale-codec",
  "parity-util-mem",
@@ -6608,16 +6584,16 @@
  "sp-application-crypto",
  "sp-arithmetic",
  "sp-core",
- "sp-inherents",
  "sp-io",
  "sp-std",
 ]
 
 [[package]]
 name = "sp-runtime-interface"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "primitive-types",
  "sp-externalities",
@@ -6631,8 +6607,8 @@
 
 [[package]]
 name = "sp-runtime-interface-proc-macro"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "Inflector",
  "proc-macro-crate",
@@ -6643,8 +6619,8 @@
 
 [[package]]
 name = "sp-sandbox"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-core",
@@ -6656,8 +6632,8 @@
 
 [[package]]
 name = "sp-serializer"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "serde",
  "serde_json",
@@ -6665,8 +6641,8 @@
 
 [[package]]
 name = "sp-session"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-api",
@@ -6678,8 +6654,8 @@
 
 [[package]]
 name = "sp-staking"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "parity-scale-codec",
  "sp-runtime",
@@ -6688,34 +6664,35 @@
 
 [[package]]
 name = "sp-state-machine"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "hash-db",
  "log",
  "num-traits",
  "parity-scale-codec",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "rand 0.7.3",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "sp-core",
  "sp-externalities",
  "sp-panic-handler",
  "sp-std",
  "sp-trie",
+ "thiserror",
  "trie-db",
  "trie-root",
 ]
 
 [[package]]
 name = "sp-std"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 
 [[package]]
 name = "sp-storage"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "impl-serde",
  "parity-scale-codec",
@@ -6726,11 +6703,24 @@
 ]
 
 [[package]]
-name = "sp-timestamp"
+name = "sp-tasks"
 version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "impl-trait-for-tuples",
+ "log",
+ "sp-core",
+ "sp-externalities",
+ "sp-io",
+ "sp-runtime-interface",
+ "sp-std",
+]
+
+[[package]]
+name = "sp-timestamp"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
+dependencies = [
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "sp-api",
  "sp-inherents",
@@ -6741,8 +6731,8 @@
 
 [[package]]
 name = "sp-tracing"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "log",
  "parity-scale-codec",
@@ -6754,23 +6744,24 @@
 
 [[package]]
 name = "sp-transaction-pool"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "derive_more",
- "futures 0.3.8",
+ "futures 0.3.12",
  "log",
  "parity-scale-codec",
  "serde",
  "sp-api",
  "sp-blockchain",
  "sp-runtime",
+ "thiserror",
 ]
 
 [[package]]
 name = "sp-trie"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "hash-db",
  "memory-db",
@@ -6783,10 +6774,10 @@
 
 [[package]]
 name = "sp-utils"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "futures-core",
  "futures-timer 3.0.2",
  "lazy_static",
@@ -6795,8 +6786,8 @@
 
 [[package]]
 name = "sp-version"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "impl-serde",
  "parity-scale-codec",
@@ -6807,10 +6798,10 @@
 
 [[package]]
 name = "sp-wasm-interface"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
- "impl-trait-for-tuples",
+ "impl-trait-for-tuples 0.2.0",
  "parity-scale-codec",
  "sp-std",
  "wasmi",
@@ -6836,11 +6827,11 @@
 
 [[package]]
 name = "statrs"
-version = "0.10.0"
+version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8"
+checksum = "cce16f6de653e88beca7bd13780d08e09d4489dbca1f9210e041bc4852481382"
 dependencies = [
- "rand 0.5.6",
+ "rand 0.7.3",
 ]
 
 [[package]]
@@ -6919,8 +6910,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236"
 dependencies = [
- "hmac",
- "pbkdf2",
+ "hmac 0.7.1",
+ "pbkdf2 0.3.0",
  "schnorrkel",
  "sha2 0.8.2",
  "zeroize",
@@ -6928,19 +6919,19 @@
 
 [[package]]
 name = "substrate-build-script-utils"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "platforms",
 ]
 
 [[package]]
 name = "substrate-frame-rpc-system"
-version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "2.0.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "frame-system-rpc-runtime-api",
- "futures 0.3.8",
+ "futures 0.3.12",
  "jsonrpc-core",
  "jsonrpc-core-client",
  "jsonrpc-derive",
@@ -6959,8 +6950,8 @@
 
 [[package]]
 name = "substrate-prometheus-endpoint"
-version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+version = "0.8.1"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=unique#a7fd1e5d59b12d0166da54d545e7e5826bc6f518"
 dependencies = [
  "async-std",
  "derive_more",
@@ -6991,9 +6982,9 @@
 
 [[package]]
 name = "syn"
-version = "1.0.54"
+version = "1.0.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
+checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -7026,14 +7017,14 @@
 
 [[package]]
 name = "tempfile"
-version = "3.1.0"
+version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "libc",
- "rand 0.7.3",
- "redox_syscall",
+ "rand 0.8.2",
+ "redox_syscall 0.2.4",
  "remove_dir_all",
  "winapi 0.3.9",
 ]
@@ -7058,18 +7049,18 @@
 
 [[package]]
 name = "thiserror"
-version = "1.0.22"
+version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
+checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.22"
+version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
+checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -7078,9 +7069,9 @@
 
 [[package]]
 name = "thread_local"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
 dependencies = [
  "lazy_static",
 ]
@@ -7107,18 +7098,20 @@
 
 [[package]]
 name = "tiny-bip39"
-version = "0.7.3"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2"
+checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8"
 dependencies = [
- "failure",
- "hmac",
- "once_cell 1.5.2",
- "pbkdf2",
+ "anyhow",
+ "hmac 0.8.1",
+ "once_cell",
+ "pbkdf2 0.4.0",
  "rand 0.7.3",
  "rustc-hash",
- "sha2 0.8.2",
+ "sha2 0.9.2",
+ "thiserror",
  "unicode-normalization",
+ "zeroize",
 ]
 
 [[package]]
@@ -7157,11 +7150,11 @@
  "num_cpus",
  "tokio-codec",
  "tokio-current-thread",
- "tokio-executor 0.1.10",
+ "tokio-executor",
  "tokio-fs",
  "tokio-io",
  "tokio-reactor",
- "tokio-sync 0.1.8",
+ "tokio-sync",
  "tokio-tcp",
  "tokio-threadpool",
  "tokio-timer",
@@ -7220,7 +7213,7 @@
 checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e"
 dependencies = [
  "futures 0.1.30",
- "tokio-executor 0.1.10",
+ "tokio-executor",
 ]
 
 [[package]]
@@ -7231,17 +7224,6 @@
 dependencies = [
  "crossbeam-utils 0.7.2",
  "futures 0.1.30",
-]
-
-[[package]]
-name = "tokio-executor"
-version = "0.2.0-alpha.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ee9ceecf69145923834ea73f32ba40c790fd877b74a7817dd0b089f1eb9c7c8"
-dependencies = [
- "futures-util-preview",
- "lazy_static",
- "tokio-sync 0.2.0-alpha.6",
 ]
 
 [[package]]
@@ -7293,9 +7275,9 @@
  "num_cpus",
  "parking_lot 0.9.0",
  "slab",
- "tokio-executor 0.1.10",
+ "tokio-executor",
  "tokio-io",
- "tokio-sync 0.1.8",
+ "tokio-sync",
 ]
 
 [[package]]
@@ -7305,7 +7287,7 @@
 checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
 dependencies = [
  "futures-core",
- "rustls",
+ "rustls 0.18.1",
  "tokio 0.2.24",
  "webpki",
 ]
@@ -7330,17 +7312,6 @@
 ]
 
 [[package]]
-name = "tokio-sync"
-version = "0.2.0-alpha.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f1aaeb685540f7407ea0e27f1c9757d258c7c6bf4e3eb19da6fc59b747239d2"
-dependencies = [
- "fnv",
- "futures-core-preview",
- "futures-util-preview",
-]
-
-[[package]]
 name = "tokio-tcp"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -7368,7 +7339,7 @@
  "log",
  "num_cpus",
  "slab",
- "tokio-executor 0.1.10",
+ "tokio-executor",
 ]
 
 [[package]]
@@ -7380,7 +7351,7 @@
  "crossbeam-utils 0.7.2",
  "futures 0.1.30",
  "slab",
- "tokio-executor 0.1.10",
+ "tokio-executor",
 ]
 
 [[package]]
@@ -7432,9 +7403,9 @@
 
 [[package]]
 name = "toml"
-version = "0.5.7"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
+checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
 dependencies = [
  "serde",
 ]
@@ -7453,7 +7424,7 @@
 dependencies = [
  "cfg-if 1.0.0",
  "log",
- "pin-project-lite 0.2.0",
+ "pin-project-lite 0.2.4",
  "tracing-attributes",
  "tracing-core",
 ]
@@ -7523,7 +7494,7 @@
  "serde",
  "serde_json",
  "sharded-slab",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "thread_local",
  "tracing",
  "tracing-core",
@@ -7533,15 +7504,15 @@
 
 [[package]]
 name = "trie-db"
-version = "0.22.1"
+version = "0.22.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e55f7ace33d6237e14137e386f4e1672e2a5c6bbc97fef9f438581a143971f0"
+checksum = "5cc176c377eb24d652c9c69c832c832019011b6106182bf84276c66b66d5c9a6"
 dependencies = [
  "hash-db",
- "hashbrown 0.8.2",
+ "hashbrown",
  "log",
  "rustc-hex",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
 ]
 
 [[package]]
@@ -7577,14 +7548,20 @@
 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
 
 [[package]]
+name = "ucd-trie"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+
+[[package]]
 name = "uint"
-version = "0.8.5"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177"
+checksum = "e11fe9a9348741cf134085ad57c249508345fe16411b3d7fb4ff2da2f1d6382e"
 dependencies = [
- "byteorder 1.3.4",
+ "byteorder",
  "crunchy",
- "rustc-hex",
+ "hex",
  "static_assertions",
 ]
 
@@ -7645,22 +7622,18 @@
 
 [[package]]
 name = "unsigned-varint"
-version = "0.4.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "669d776983b692a906c881fcd0cfb34271a48e197e4d6cb8df32b05bfc3d3fa5"
-dependencies = [
- "bytes 0.5.6",
- "futures-io",
- "futures-util",
- "futures_codec",
-]
+checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35"
 
 [[package]]
 name = "unsigned-varint"
-version = "0.5.1"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35"
+checksum = "35581ff83d4101e58b582e607120c7f5ffb17e632a980b1f38334d76b36908b2"
 dependencies = [
+ "asynchronous-codec",
+ "bytes 1.0.1",
  "futures-io",
  "futures-util",
 ]
@@ -7835,7 +7808,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "js-sys",
  "parking_lot 0.11.1",
  "pin-utils",
@@ -7893,7 +7866,7 @@
  "log",
  "region",
  "rustc-demangle",
- "smallvec 1.5.1",
+ "smallvec 1.6.1",
  "target-lexicon",
  "wasmparser 0.59.0",
  "wasmtime-environ",
@@ -7934,7 +7907,7 @@
  "cranelift-entity",
  "cranelift-frontend",
  "cranelift-wasm",
- "directories",
+ "directories 2.0.2",
  "errno",
  "file-per-thread-logger",
  "indexmap",
@@ -8036,18 +8009,18 @@
 
 [[package]]
 name = "wast"
-version = "30.0.0"
+version = "32.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b79907b22f740634810e882d8d1d9d0f9563095a8ab94e786e370242bff5cd2"
+checksum = "c24a3ee360d01d60ed0a0f960ab76a6acce64348cdb0bf8699c2a866fad57c7c"
 dependencies = [
  "leb128",
 ]
 
 [[package]]
 name = "wat"
-version = "1.0.31"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8279a02835bf12e61ed2b3c3cbc6ecf9918762fd97e036917c11a09ec20ca44"
+checksum = "5e8f7f34773fa6318e8897283abf7941c1f250faae4e1a52f82df09c3bad7cce"
 dependencies = [
  "wast",
 ]
@@ -8074,18 +8047,9 @@
 
 [[package]]
 name = "webpki-roots"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4"
-dependencies = [
- "webpki",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "0.19.0"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739"
+checksum = "82015b7e0b8bad8185994674a13a93306bea76cf5a16c5a181382fd3a5ec2376"
 dependencies = [
  "webpki",
 ]
@@ -8109,6 +8073,16 @@
 ]
 
 [[package]]
+name = "which"
+version = "4.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef"
+dependencies = [
+ "libc",
+ "thiserror",
+]
+
+[[package]]
 name = "winapi"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8159,17 +8133,6 @@
 dependencies = [
  "winapi 0.2.8",
  "winapi-build",
-]
-
-[[package]]
-name = "x25519-dalek"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217"
-dependencies = [
- "curve25519-dalek 2.1.0",
- "rand_core 0.5.1",
- "zeroize",
 ]
 
 [[package]]
@@ -8178,7 +8141,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088"
 dependencies = [
- "curve25519-dalek 3.0.0",
+ "curve25519-dalek 3.0.2",
  "rand_core 0.5.1",
  "zeroize",
 ]
@@ -8189,7 +8152,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9aeb8c4043cac71c3c299dff107171c220d179492350ea198e109a414981b83c"
 dependencies = [
- "futures 0.3.8",
+ "futures 0.3.12",
  "log",
  "nohash-hasher",
  "parking_lot 0.11.1",
@@ -8251,6 +8214,6 @@
 dependencies = [
  "cc",
  "glob",
- "itertools 0.9.0",
+ "itertools",
  "libc",
 ]
modifiednode/Cargo.tomldiffbeforeafterboth
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -1,7 +1,7 @@
 [build-dependencies.substrate-build-script-utils]
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [[bin]]
 name = 'nft'
@@ -15,7 +15,7 @@
 license = 'Unlicense'
 name = 'nft'
 repository = 'https://github.com/substrate-developer-hub/nft/'
-version = '2.0.0'
+version = '2.0.1'
 
 [package.metadata.docs.rs]
 targets = ['x86_64-unknown-linux-gnu']
@@ -29,34 +29,36 @@
 jsonrpc-core = '15.0.0'
 
 # Substrate dependencies
-nft-runtime = { path = '../runtime', version = '2.0.0' }
-frame-benchmarking = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-frame-benchmarking-cli = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-pallet-transaction-payment-rpc = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-basic-authorship = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-cli = { features = ['wasmtime'], version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sc-client-api = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-consensus = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-consensus-aura = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-executor = { features = ['wasmtime'], version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sc-finality-grandpa = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-rpc = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-rpc-api = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-service = { features = ['wasmtime'], version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sc-transaction-pool = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-api = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-block-builder = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-blockchain = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-consensus = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-consensus-aura = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-core = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-finality-grandpa = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-inherents = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-runtime = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sp-transaction-pool = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-sc-network = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'} 
-substrate-frame-rpc-system = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
-pallet-contracts-rpc = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'} 
+nft-runtime = { path = '../runtime', version = '2.0.1' }
+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'}
 
 serde = { version = "1.0.102", features = ["derive"] }
 serde_json = "1.0.41"
modifiednode/src/cli.rsdiffbeforeafterboth
--- a/node/src/cli.rs
+++ b/node/src/cli.rs
@@ -12,6 +12,8 @@
 
 #[derive(Debug, StructOpt)]
 pub enum Subcommand {
+	/// Key management cli utilities
+	Key(sc_cli::KeySubcommand),
 	/// Build a chain specification.
 	BuildSpec(sc_cli::BuildSpecCmd),
 
@@ -33,7 +35,7 @@
 	/// Revert the chain to a previous state.
 	Revert(sc_cli::RevertCmd),
 
-	// The custom benchmark subcommmand benchmarking runtime pallets.
+	/// The custom benchmark subcommmand benchmarking runtime pallets.
 	#[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]
 	Benchmark(frame_benchmarking_cli::BenchmarkCmd),
 }
modifiednode/src/command.rsdiffbeforeafterboth
--- a/node/src/command.rs
+++ b/node/src/command.rs
@@ -1,6 +1,6 @@
 // This file is part of Substrate.
 
-// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd.
+// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.
 // SPDX-License-Identifier: Apache-2.0
 
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,6 +66,7 @@
 	let cli = Cli::from_args();
 
 	match &cli.subcommand {
+		Some(Subcommand::Key(cmd)) => cmd.run(&cli),
 		Some(Subcommand::BuildSpec(cmd)) => {
 			let runner = cli.create_runner(cmd)?;
 			runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
@@ -126,9 +127,11 @@
 		},
 		None => {
 			let runner = cli.create_runner(&cli.run)?;
-			runner.run_node_until_exit(|config| match config.role {
-				Role::Light => service::new_light(config),
-				_ => service::new_full(config),
+			runner.run_node_until_exit(|config| async move {
+				match config.role {
+					Role::Light => service::new_light(config),
+					_ => service::new_full(config),
+				}.map_err(sc_cli::Error::Service)
 			})
 		}
 	}
modifiednode/src/service.rsdiffbeforeafterboth
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -14,13 +14,15 @@
 use sc_executor::native_executor_instance;
 pub use sc_executor::NativeExecutor;
 use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};
-use sc_finality_grandpa::{FinalityProofProvider as GrandpaFinalityProofProvider, SharedVoterState};
+use sc_finality_grandpa::SharedVoterState;
+use sc_keystore::LocalKeystore;
+use sc_telemetry::TelemetrySpan;
 
 // Our native executor instance.
 native_executor_instance!(
 	pub Executor,
-    nft_runtime::api::dispatch,
-    nft_runtime::native_version,
+	nft_runtime::api::dispatch,
+	nft_runtime::native_version,
 	frame_benchmarking::benchmarking::HostFunctions,
 );
 
@@ -39,12 +41,17 @@
 			sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,
 			AuraPair
 		>,
-		sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>
+		sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
+		Option<TelemetrySpan>,
 	)
 >, ServiceError> {
+	if config.keystore_remote.is_some() {
+		return Err(ServiceError::Other(
+			format!("Remote Keystores are not supported.")))
+	}
 	let inherent_data_providers = sp_inherents::InherentDataProviders::new();
 
-	let (client, backend, keystore, task_manager) =
+	let (client, backend, keystore_container, task_manager, telemetry_span) =
 		sc_service::new_full_parts::<Block, RuntimeApi, Executor>(&config)?;
 	let client = Arc::new(client);
 
@@ -69,7 +76,6 @@
 		sc_consensus_aura::slot_duration(&*client)?,
 		aura_block_import.clone(),
 		Some(Box::new(grandpa_block_import.clone())),
-		None,
 		client.clone(),
 		inherent_data_providers.clone(),
 		&task_manager.spawn_handle(),
@@ -78,22 +84,50 @@
 	)?;
 
 	Ok(sc_service::PartialComponents {
-		client, backend, task_manager, import_queue, keystore, 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),
+		other: (aura_block_import, grandpa_link, telemetry_span),
 	})
 }
 
+fn remote_keystore(_url: &String) -> Result<Arc<LocalKeystore>, &'static str> {
+	// FIXME: here would the concrete keystore be built,
+	//        must return a concrete type (NOT `LocalKeystore`) that
+	//        implements `CryptoStore` and `SyncCryptoStore`
+	Err("Remote Keystore not supported.")
+}
+
 /// Builds a new service for a full client.
-pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
+pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError> {
 	let sc_service::PartialComponents {
-		client, backend, mut task_manager, import_queue, keystore, 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),
+		other: (block_import, grandpa_link, telemetry_span),
 	} = new_partial(&config)?;
 
-	let finality_proof_provider =
-		GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
+	if let Some(url) = &config.keystore_remote {
+		match remote_keystore(url) {
+			Ok(k) => keystore_container.set_remote_keystore(k),
+			Err(e) => {
+				return Err(ServiceError::Other(
+					format!("Error hooking up remote keystore for {}: {}", url, e)))
+			}
+		};
+	}
+
+	config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());
 
 	let (network, network_status_sinks, system_rpc_tx, network_starter) =
 		sc_service::build_network(sc_service::BuildNetworkParams {
@@ -104,8 +138,6 @@
 			import_queue,
 			on_demand: None,
 			block_announce_validator_builder: None,
-			finality_proof_request_builder: None,
-			finality_proof_provider: Some(finality_proof_provider.clone()),
 		})?;
 
 	if config.offchain_worker.enabled {
@@ -116,10 +148,10 @@
 
 	let role = config.role.clone();
 	let force_authoring = config.force_authoring;
+	let backoff_authoring_blocks: Option<()> = None;
 	let name = config.network.node_name.clone();
 	let enable_grandpa = !config.disable_grandpa;
 	let prometheus_registry = config.prometheus_registry().cloned();
-	let telemetry_connection_sinks = sc_service::TelemetryConnectionSinks::default();
 
 	let rpc_extensions_builder = {
 		let client = client.clone();
@@ -136,21 +168,27 @@
 		})
 	};
 
-	sc_service::spawn_tasks(sc_service::SpawnTasksParams {
-		network: network.clone(),
-		client: client.clone(),
-		keystore: keystore.clone(),
-		task_manager: &mut task_manager,
-		transaction_pool: transaction_pool.clone(),
-		telemetry_connection_sinks: telemetry_connection_sinks.clone(),
-		rpc_extensions_builder: rpc_extensions_builder,
-		on_demand: None,
-		remote_blockchain: None,
-		backend, network_status_sinks, system_rpc_tx, config,
-	})?;
+	let (_rpc_handlers, telemetry_connection_notifier) = sc_service::spawn_tasks(
+		sc_service::SpawnTasksParams {
+			network: network.clone(),
+			client: client.clone(),
+			keystore: keystore_container.sync_keystore(),
+			task_manager: &mut task_manager,
+			transaction_pool: transaction_pool.clone(),
+			rpc_extensions_builder,
+			on_demand: None,
+			remote_blockchain: None,
+			backend,
+			network_status_sinks,
+			system_rpc_tx,
+			config,
+			telemetry_span,
+		},
+	)?;
 
 	if role.is_authority() {
 		let proposer = sc_basic_authorship::ProposerFactory::new(
+			task_manager.spawn_handle(),
 			client.clone(),
 			transaction_pool,
 			prometheus_registry.as_ref(),
@@ -159,7 +197,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,
@@ -168,7 +206,8 @@
 			network.clone(),
 			inherent_data_providers.clone(),
 			force_authoring,
-			keystore.clone(),
+			backoff_authoring_blocks,
+			keystore_container.sync_keystore(),
 			can_author_with,
 		)?;
 
@@ -180,7 +219,7 @@
 	// if the node isn't actively participating in consensus then it doesn't
 	// need a keystore, regardless of which protocol we use below.
 	let keystore = if role.is_authority() {
-		Some(keystore as sp_core::traits::BareCryptoStorePtr)
+		Some(keystore_container.sync_keystore())
 	} else {
 		None
 	};
@@ -206,8 +245,7 @@
 			config: grandpa_config,
 			link: grandpa_link,
 			network,
-			inherent_data_providers,
-			telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()),
+			telemetry_on_connect: telemetry_connection_notifier.map(|x| x.on_connect_stream()),
 			voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),
 			prometheus_registry,
 			shared_voter_state: SharedVoterState::empty(),
@@ -219,12 +257,6 @@
 			"grandpa-voter",
 			sc_finality_grandpa::run_grandpa_voter(grandpa_config)?
 		);
-	} else {
-		sc_finality_grandpa::setup_disabled_grandpa(
-			client,
-			&inherent_data_providers,
-			network,
-		)?;
 	}
 
 	network_starter.start_network();
@@ -232,10 +264,14 @@
 }
 
 /// Builds a new service for a light client.
-pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {
-	let (client, backend, keystore, mut task_manager, on_demand) =
+pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError> {
+	let (client, backend, keystore_container, mut task_manager, on_demand, telemetry_span) =
 		sc_service::new_light_parts::<Block, RuntimeApi, Executor>(&config)?;
 
+	config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());
+
+	let select_chain = sc_consensus::LongestChain::new(backend.clone());
+
 	let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(
 		config.transaction_pool.clone(),
 		config.prometheus_registry(),
@@ -244,28 +280,27 @@
 		on_demand.clone(),
 	));
 
-	let grandpa_block_import = sc_finality_grandpa::light_block_import(
-		client.clone(), backend.clone(), &(client.clone() as Arc<_>),
-		Arc::new(on_demand.checker().clone()) as Arc<_>,
+	let (grandpa_block_import, _) = sc_finality_grandpa::block_import(
+		client.clone(),
+		&(client.clone() as Arc<_>),
+		select_chain.clone(),
 	)?;
-	let finality_proof_import = grandpa_block_import.clone();
-	let finality_proof_request_builder =
-		finality_proof_import.create_finality_proof_request_builder();
 
+	let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(
+		grandpa_block_import.clone(),
+		client.clone(),
+	);
+
 	let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>(
 		sc_consensus_aura::slot_duration(&*client)?,
-		grandpa_block_import,
-		None,
-		Some(Box::new(finality_proof_import)),
+		aura_block_import,
+		Some(Box::new(grandpa_block_import)),
 		client.clone(),
 		InherentDataProviders::new(),
 		&task_manager.spawn_handle(),
 		config.prometheus_registry(),
 		sp_consensus::NeverCanAuthor,
 	)?;
-
-	let finality_proof_provider =
-		GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
 
 	let (network, network_status_sinks, system_rpc_tx, network_starter) =
 		sc_service::build_network(sc_service::BuildNetworkParams {
@@ -276,8 +311,6 @@
 			import_queue,
 			on_demand: Some(on_demand.clone()),
 			block_announce_validator_builder: None,
-			finality_proof_request_builder: Some(finality_proof_request_builder),
-			finality_proof_provider: Some(finality_proof_provider),
 		})?;
 
 	if config.offchain_worker.enabled {
@@ -292,17 +325,17 @@
 		task_manager: &mut task_manager,
 		on_demand: Some(on_demand),
 		rpc_extensions_builder: Box::new(|_, _| ()),
-		telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(),
 		config,
 		client,
-		keystore,
+		keystore: keystore_container.sync_keystore(),
 		backend,
 		network,
 		network_status_sinks,
 		system_rpc_tx,
-	 })?;
+		telemetry_span,
+	})?;
 
-	 network_starter.start_network();
+	network_starter.start_network();
 
-	 Ok(task_manager)
+	Ok(task_manager)
 }
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.0.0'
+version = '2.0.1'
 
 [package.metadata.docs.rs]
 targets = ['x86_64-unknown-linux-gnu']
@@ -16,37 +16,37 @@
 default-features = false
 features = ['derive']
 package = 'parity-scale-codec'
-version = '1.3.4'
+version = '1.3.6'
 
 [dependencies.frame-support]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dependencies.frame-system]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dev-dependencies.sp-core]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dev-dependencies.sp-io]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dependencies.sp-runtime]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 	
 [dependencies]
 # third-party dependencies
@@ -56,50 +56,50 @@
 [dependencies.sp-std]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
-version = '2.0.0'
+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 = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dependencies.frame-benchmarking]
-version = "2.0.0"
+version = "2.0.1"
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
-branch = 'release_flexi'
+branch = 'unique'
 optional = true
 
 [dependencies.pallet-contracts]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
 package = 'pallet-contracts'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dependencies.pallet-balances]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
 package = 'pallet-balances'
-branch = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [dependencies.pallet-timestamp]
 default-features = false
 git = 'https://github.com/usetech-llc/substrate.git'
 package = 'pallet-timestamp'
-branch = 'release_flexi'
-version = '2.0.0'
+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 = 'release_flexi'
-version = '2.0.0'
+branch = 'unique'
+version = '2.0.1'
 
 [features]
 default = ['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, WithdrawReason,24    },25    weights::{26        constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},27        DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,28        WeightToFeePolynomial,29    },30    IsSubType, 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 pallet_contracts::ContractAddressFor;45use sp_runtime::traits::StaticLookup;4647#[cfg(test)]48mod mock;4950#[cfg(test)]51mod tests;5253mod default_weights;5455pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;56pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;57pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;5859// Structs60// #region6162pub type CollectionId = u32;63pub type TokenId = u32;64pub type DecimalPoints = u8;6566#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]67#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]68pub enum CollectionMode {69    Invalid,70    NFT,71    // decimal points72    Fungible(DecimalPoints),73    // decimal points74    ReFungible(DecimalPoints),75}7677impl Default for CollectionMode {78    fn default() -> Self {79        Self::Invalid80    }81}8283impl Into<u8> for CollectionMode {84    fn into(self) -> u8 {85        match self {86            CollectionMode::Invalid => 0,87            CollectionMode::NFT => 1,88            CollectionMode::Fungible(_) => 2,89            CollectionMode::ReFungible(_) => 3,90        }91    }92}9394#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]95#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]96pub enum AccessMode {97    Normal,98    WhiteList,99}100impl Default for AccessMode {101    fn default() -> Self {102        Self::Normal103    }104}105106#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]107#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]108pub enum SchemaVersion {109    ImageURL,110    Unique,111}112impl Default for SchemaVersion {113    fn default() -> Self {114        Self::ImageURL115    }116}117118#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]119#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]120pub struct Ownership<AccountId> {121    pub owner: AccountId,122    pub fraction: u128,123}124125#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]126#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]127pub struct CollectionType<AccountId> {128    pub owner: AccountId,129    pub mode: CollectionMode,130    pub access: AccessMode,131    pub decimal_points: DecimalPoints,132    pub name: Vec<u16>,        // 64 include null escape char133    pub description: Vec<u16>, // 256 include null escape char134    pub token_prefix: Vec<u8>, // 16 include null escape char135    pub mint_mode: bool,136    pub offchain_schema: Vec<u8>,137    pub schema_version: SchemaVersion,138    pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender139    pub sponsor_confirmed: bool, // False if sponsor address has not yet confirmed sponsorship. True otherwise.140    pub limits: CollectionLimits, // Collection private restrictions 141    pub variable_on_chain_schema: Vec<u8>, //142    pub const_on_chain_schema: Vec<u8>, //143}144145#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]146#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]147pub struct NftItemType<AccountId> {148    pub owner: AccountId,149    pub const_data: Vec<u8>,150    pub variable_data: Vec<u8>,151}152153#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]154#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]155pub struct FungibleItemType {156    pub value: u128,157}158159#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]160#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]161pub struct ReFungibleItemType<AccountId> {162    pub owner: Vec<Ownership<AccountId>>,163    pub const_data: Vec<u8>,164    pub variable_data: Vec<u8>,165}166167// #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]168// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]169// pub struct VestingItem<AccountId, Moment> {170//     pub sender: AccountId,171//     pub recipient: AccountId,172//     pub collection_id: CollectionId,173//     pub item_id: TokenId,174//     pub amount: u64,175//     pub vesting_date: Moment,176// }177178#[derive(Encode, Decode, Debug, Clone, PartialEq)]179#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]180pub struct CollectionLimits {181    pub account_token_ownership_limit: u32,182    pub sponsored_data_size: u32,183    pub token_limit: u32,184185    // Timeouts for item types in passed blocks186    pub sponsor_transfer_timeout: u32,187}188189impl Default for CollectionLimits {190    fn default() -> CollectionLimits {191        CollectionLimits { 192            account_token_ownership_limit: 10_000_000, 193            token_limit: u32::max_value(),194            sponsored_data_size: u32::max_value(), 195            sponsor_transfer_timeout: 14400 }196    }197}198199#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]200#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]201pub struct ChainLimits {202    pub collection_numbers_limit: u32,203    pub account_token_ownership_limit: u32,204    pub collections_admins_limit: u64,205    pub custom_data_limit: u32,206207    // Timeouts for item types in passed blocks208    pub nft_sponsor_transfer_timeout: u32,209    pub fungible_sponsor_transfer_timeout: u32,210    pub refungible_sponsor_transfer_timeout: u32,211212    // Schema limits213    pub offchain_schema_limit: u32,214    pub variable_on_chain_schema_limit: u32,215    pub const_on_chain_schema_limit: u32,216}217218pub trait WeightInfo {219	fn create_collection() -> Weight;220	fn destroy_collection() -> Weight;221	fn add_to_white_list() -> Weight;222	fn remove_from_white_list() -> Weight;223    fn set_public_access_mode() -> Weight;224    fn set_mint_permission() -> Weight;225    fn change_collection_owner() -> Weight;226    fn add_collection_admin() -> Weight;227    fn remove_collection_admin() -> Weight;228    fn set_collection_sponsor() -> Weight;229    fn confirm_sponsorship() -> Weight;230    fn remove_collection_sponsor() -> Weight;231    fn create_item(s: usize) -> Weight;232    fn burn_item() -> Weight;233    fn transfer() -> Weight;234    fn approve() -> Weight;235    fn transfer_from() -> Weight;236    fn set_offchain_schema() -> Weight;237    fn set_const_on_chain_schema() -> Weight;238    fn set_variable_on_chain_schema() -> Weight;239    fn set_variable_meta_data() -> Weight;240    fn enable_contract_sponsoring() -> Weight;241    fn set_schema_version() -> Weight;242    fn set_chain_limits() -> Weight;243    fn set_contract_sponsoring_rate_limit() -> Weight;244    fn toggle_contract_white_list() -> Weight;245    fn add_to_contract_white_list() -> Weight;246    fn remove_from_contract_white_list() -> Weight;247    fn set_collection_limits() -> Weight;248}249250#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]251#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]252pub struct CreateNftData {253    pub const_data: Vec<u8>,254    pub variable_data: Vec<u8>,255}256257#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]258#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]259pub struct CreateFungibleData {260    pub value: u128,261}262263#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]264#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]265pub struct CreateReFungibleData {266    pub const_data: Vec<u8>,267    pub variable_data: Vec<u8>,268}269270#[derive(Encode, Decode, Debug, Clone, PartialEq)]271#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]272pub enum CreateItemData {273    NFT(CreateNftData),274    Fungible(CreateFungibleData),275    ReFungible(CreateReFungibleData),276}277278impl CreateItemData {279    pub fn len(&self) -> usize {280        let len = match self {281            CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),282            CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),283            _ => 0284        };285        286        return len;287    }288}289290impl From<CreateNftData> for CreateItemData {291    fn from(item: CreateNftData) -> Self {292        CreateItemData::NFT(item)293    }294}295296impl From<CreateReFungibleData> for CreateItemData {297    fn from(item: CreateReFungibleData) -> Self {298        CreateItemData::ReFungible(item)299    }300}301302impl From<CreateFungibleData> for CreateItemData {303    fn from(item: CreateFungibleData) -> Self {304        CreateItemData::Fungible(item)305    }306}307308309decl_error! {310	/// Error for non-fungible-token module.311	pub enum Error for Module<T: Trait> {312        /// Total collections bound exceeded.313        TotalCollectionsLimitExceeded,314		/// Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.315        CollectionDecimalPointLimitExceeded, 316        /// Collection name can not be longer than 63 char.317        CollectionNameLimitExceeded, 318        /// Collection description can not be longer than 255 char.319        CollectionDescriptionLimitExceeded, 320        /// Token prefix can not be longer than 15 char.321        CollectionTokenPrefixLimitExceeded,322        /// This collection does not exist.323        CollectionNotFound,324        /// Item not exists.325        TokenNotFound,326        /// Admin not found327        AdminNotFound,328        /// Arithmetic calculation overflow.329        NumOverflow,       330        /// Account already has admin role.331        AlreadyAdmin,  332        /// You do not own this collection.333        NoPermission,334        /// This address is not set as sponsor, use setCollectionSponsor first.335        ConfirmUnsetSponsorFail,336        /// Collection is not in mint mode.337        PublicMintingNotAllowed,338        /// Sender parameter and item owner must be equal.339        MustBeTokenOwner,340        /// Item balance not enough.341        TokenValueTooLow,342        /// Size of item is too large.343        NftSizeLimitExceeded,344        /// No approve found345        ApproveNotFound,346        /// Requested value more than approved.347        TokenValueNotEnough,348        /// Only approved addresses can call this method.349        ApproveRequired,350        /// Address is not in white list.351        AddresNotInWhiteList,352        /// Number of collection admins bound exceeded.353        CollectionAdminsLimitExceeded,354        /// Owned tokens by a single address bound exceeded.355        AddressOwnershipLimitExceeded,356        /// Length of items properties must be greater than 0.357        EmptyArgument,358        /// const_data exceeded data limit.359        TokenConstDataLimitExceeded,360        /// variable_data exceeded data limit.361        TokenVariableDataLimitExceeded,362        /// Not NFT item data used to mint in NFT collection.363        NotNftDataUsedToMintNftCollectionToken,364        /// Not Fungible item data used to mint in Fungible collection.365        NotFungibleDataUsedToMintFungibleCollectionToken,366        /// Not Re Fungible item data used to mint in Re Fungible collection.367        NotReFungibleDataUsedToMintReFungibleCollectionToken,368        /// Unexpected collection type.369        UnexpectedCollectionType,370        /// Can't store metadata in fungible tokens.371        CantStoreMetadataInFungibleTokens,372        /// Collection token limit exceeded373        CollectionTokenLimitExceeded,374        /// Account token limit exceeded per collection375        AccountTokenLimitExceeded,376        /// Collection limit bounds per collection exceeded377        CollectionLimitBoundsExceeded,378        /// Schema data size limit bound exceeded379        SchemaDataLimitExceeded380	}381}382383pub trait Trait: system::Trait + Sized + transaction_payment::Trait + pallet_contracts::Trait {384    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;385386    /// Weight information for extrinsics in this pallet.387	type WeightInfo: WeightInfo;388}389390#[cfg(feature = "runtime-benchmarks")]391mod benchmarking;392393// #endregion394395decl_storage! {396    trait Store for Module<T: Trait> as Nft {397398        // Private members399        NextCollectionID: CollectionId;400        CreatedCollectionCount: u32;401        ChainVersion: u64;402        ItemListIndex: map hasher(identity) CollectionId => TokenId;403404        // Chain limits struct405        pub ChainLimit get(fn chain_limit) config(): ChainLimits;406407        // Bound counters408        CollectionCount: u32;409        pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;410411        // Basic collections412        pub Collection get(fn collection) config(): map hasher(identity) CollectionId => CollectionType<T::AccountId>;413        pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;414        pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;415416        /// Balance owner per collection map417        pub Balance get(fn balance_count): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => u128;418419        /// second parameter: item id + owner account id + spender account id420        pub Allowances get(fn approved): double_map hasher(identity) CollectionId, hasher(twox_64_concat) (TokenId, T::AccountId, T::AccountId) => u128;421422        /// Item collections423        pub NftItemList get(fn nft_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => NftItemType<T::AccountId>;424        pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => FungibleItemType;425        pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => ReFungibleItemType<T::AccountId>;426427        /// Index list428        pub AddressTokens get(fn address_tokens): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => Vec<TokenId>;429430        /// Tokens transfer baskets431        pub CreateItemBasket get(fn create_item_basket): map hasher(twox_64_concat) (CollectionId, T::AccountId) => T::BlockNumber;432        pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;433        pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;434        pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;435436        // Contract Sponsorship and Ownership437        pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;438        pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;439        pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;440        pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;441        pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 442        pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId => bool; 443    }444    add_extra_genesis {445        build(|config: &GenesisConfig<T>| {446            // Modification of storage447            for (_num, _c) in &config.collection {448                <Module<T>>::init_collection(_c);449            }450451            for (_num, _c, _i) in &config.nft_item_id {452                <Module<T>>::init_nft_token(*_c, _i);453            }454455            for (collection_id, account_id, fungible_item) in &config.fungible_item_id {456                <Module<T>>::init_fungible_token(*collection_id, account_id, fungible_item);457            }458459            for (_num, _c, _i) in &config.refungible_item_id {460                <Module<T>>::init_refungible_token(*_c, _i);461            }462        })463    }464}465466decl_event!(467    pub enum Event<T>468    where469        AccountId = <T as system::Trait>::AccountId,470    {471        /// New collection was created472        /// 473        /// # Arguments474        /// 475        /// * collection_id: Globally unique identifier of newly created collection.476        /// 477        /// * mode: [CollectionMode] converted into u8.478        /// 479        /// * account_id: Collection owner.480        Created(CollectionId, u8, AccountId),481482        /// New item was created.483        /// 484        /// # Arguments485        /// 486        /// * collection_id: Id of the collection where item was created.487        /// 488        /// * item_id: Id of an item. Unique within the collection.489        ItemCreated(CollectionId, TokenId),490491        /// Collection item was burned.492        /// 493        /// # Arguments494        /// 495        /// collection_id.496        /// 497        /// item_id: Identifier of burned NFT.498        ItemDestroyed(CollectionId, TokenId),499    }500);501502decl_module! {503    pub struct Module<T: Trait> for enum Call where origin: T::Origin {504505        fn deposit_event() = default;506        type Error = Error<T>;507508        fn on_initialize(now: T::BlockNumber) -> Weight {509510            if ChainVersion::get() < 2511            {512                let value = NextCollectionID::get();513                CreatedCollectionCount::put(value);514                ChainVersion::put(2);515            }516517            0518        }519520        /// 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.521        /// 522        /// # Permissions523        /// 524        /// * Anyone.525        /// 526        /// # Arguments527        /// 528        /// * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.529        /// 530        /// * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.531        /// 532        /// * token_prefix: UTF-8 string with token prefix.533        /// 534        /// * mode: [CollectionMode] collection type and type dependent data.535        // returns collection ID536        #[weight = T::WeightInfo::create_collection()]537        pub fn create_collection(origin,538                                 collection_name: Vec<u16>,539                                 collection_description: Vec<u16>,540                                 token_prefix: Vec<u8>,541                                 mode: CollectionMode) -> DispatchResult {542543            // Anyone can create a collection544            let who = ensure_signed(origin)?;545546            let decimal_points = match mode {547                CollectionMode::Fungible(points) => points,548                CollectionMode::ReFungible(points) => points,549                _ => 0550            };551552            // bound Total number of collections553            ensure!(CollectionCount::get() < ChainLimit::get().collection_numbers_limit, Error::<T>::TotalCollectionsLimitExceeded);554555            // check params556            ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);557            ensure!(collection_name.len() <= 64, Error::<T>::CollectionNameLimitExceeded);558            ensure!(collection_description.len() <= 256, Error::<T>::CollectionDescriptionLimitExceeded);559            ensure!(token_prefix.len() <= 16, Error::<T>::CollectionTokenPrefixLimitExceeded);560561            // Generate next collection ID562            let next_id = CreatedCollectionCount::get()563                .checked_add(1)564                .ok_or(Error::<T>::NumOverflow)?;565566            // bound counter567            let total = CollectionCount::get()568                .checked_add(1)569                .ok_or(Error::<T>::NumOverflow)?;570571            CreatedCollectionCount::put(next_id);572            CollectionCount::put(total);573574            // Create new collection575            let new_collection = CollectionType {576                owner: who.clone(),577                name: collection_name,578                mode: mode.clone(),579                mint_mode: false,580                access: AccessMode::Normal,581                description: collection_description,582                decimal_points: decimal_points,583                token_prefix: token_prefix,584                offchain_schema: Vec::new(),585                schema_version: SchemaVersion::ImageURL,586                sponsor: T::AccountId::default(),587                sponsor_confirmed: false,588                variable_on_chain_schema: Vec::new(),589                const_on_chain_schema: Vec::new(),590                limits: CollectionLimits::default(),591            };592593            // Add new collection to map594            <Collection<T>>::insert(next_id, new_collection);595596            // call event597            Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));598599            Ok(())600        }601602        /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.603        /// 604        /// # Permissions605        /// 606        /// * Collection Owner.607        /// 608        /// # Arguments609        /// 610        /// * collection_id: collection to destroy.611        #[weight = T::WeightInfo::destroy_collection()]612        pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {613614            let sender = ensure_signed(origin)?;615            Self::check_owner_permissions(collection_id, sender)?;616617            <AddressTokens<T>>::remove_prefix(collection_id);618            <Allowances<T>>::remove_prefix(collection_id);619            <Balance<T>>::remove_prefix(collection_id);620            <ItemListIndex>::remove(collection_id);621            <AdminList<T>>::remove(collection_id);622            <Collection<T>>::remove(collection_id);623            <WhiteList<T>>::remove_prefix(collection_id);624625            <NftItemList<T>>::remove_prefix(collection_id);626            <FungibleItemList<T>>::remove_prefix(collection_id);627            <ReFungibleItemList<T>>::remove_prefix(collection_id);628629            <NftTransferBasket<T>>::remove_prefix(collection_id);630            <FungibleTransferBasket<T>>::remove_prefix(collection_id);631            <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);632633            if CollectionCount::get() > 0634            {635                // bound couter636                let total = CollectionCount::get()637                    .checked_sub(1)638                    .ok_or(Error::<T>::NumOverflow)?;639640                CollectionCount::put(total);641            }642643            Ok(())644        }645646        /// Add an address to white list.647        /// 648        /// # Permissions649        /// 650        /// * Collection Owner651        /// * Collection Admin652        /// 653        /// # Arguments654        /// 655        /// * collection_id.656        /// 657        /// * address.658        #[weight = T::WeightInfo::add_to_white_list()]659        pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{660661            let sender = ensure_signed(origin)?;662            Self::check_owner_or_admin_permissions(collection_id, sender)?;663664            <WhiteList<T>>::insert(collection_id, address, true);665            666            Ok(())667        }668669        /// Remove an address from white list.670        /// 671        /// # Permissions672        /// 673        /// * Collection Owner674        /// * Collection Admin675        /// 676        /// # Arguments677        /// 678        /// * collection_id.679        /// 680        /// * address.681        #[weight = T::WeightInfo::remove_from_white_list()]682        pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{683684            let sender = ensure_signed(origin)?;685            Self::check_owner_or_admin_permissions(collection_id, sender)?;686687            <WhiteList<T>>::remove(collection_id, address);688689            Ok(())690        }691692        /// Toggle between normal and white list access for the methods with access for `Anyone`.693        /// 694        /// # Permissions695        /// 696        /// * Collection Owner.697        /// 698        /// # Arguments699        /// 700        /// * collection_id.701        /// 702        /// * mode: [AccessMode]703        #[weight = T::WeightInfo::set_public_access_mode()]704        pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult705        {706            let sender = ensure_signed(origin)?;707708            Self::check_owner_permissions(collection_id, sender)?;709            let mut target_collection = <Collection<T>>::get(collection_id);710            target_collection.access = mode;711            <Collection<T>>::insert(collection_id, target_collection);712713            Ok(())714        }715716        /// Allows Anyone to create tokens if:717        /// * White List is enabled, and718        /// * Address is added to white list, and719        /// * This method was called with True parameter720        /// 721        /// # Permissions722        /// * Collection Owner723        ///724        /// # Arguments725        /// 726        /// * collection_id.727        /// 728        /// * mint_permission: Boolean parameter. If True, allows minting to Anyone with conditions above.729        #[weight = T::WeightInfo::set_mint_permission()]730        pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult731        {732            let sender = ensure_signed(origin)?;733734            Self::check_owner_permissions(collection_id, sender)?;735            let mut target_collection = <Collection<T>>::get(collection_id);736            target_collection.mint_mode = mint_permission;737            <Collection<T>>::insert(collection_id, target_collection);738739            Ok(())740        }741742        /// Change the owner of the collection.743        /// 744        /// # Permissions745        /// 746        /// * Collection Owner.747        /// 748        /// # Arguments749        /// 750        /// * collection_id.751        /// 752        /// * new_owner.753        #[weight = T::WeightInfo::change_collection_owner()]754        pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {755756            let sender = ensure_signed(origin)?;757            Self::check_owner_permissions(collection_id, sender)?;758            let mut target_collection = <Collection<T>>::get(collection_id);759            target_collection.owner = new_owner;760            <Collection<T>>::insert(collection_id, target_collection);761762            Ok(())763        }764765        /// Adds an admin of the Collection.766        /// 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. 767        /// 768        /// # Permissions769        /// 770        /// * Collection Owner.771        /// * Collection Admin.772        /// 773        /// # Arguments774        /// 775        /// * collection_id: ID of the Collection to add admin for.776        /// 777        /// * new_admin_id: Address of new admin to add.778        #[weight = T::WeightInfo::add_collection_admin()]779        pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::AccountId) -> DispatchResult {780781            let sender = ensure_signed(origin)?;782            Self::check_owner_or_admin_permissions(collection_id, sender)?;783            let mut admin_arr: Vec<T::AccountId> = Vec::new();784785            if <AdminList<T>>::contains_key(collection_id)786            {787                admin_arr = <AdminList<T>>::get(collection_id);788                ensure!(!admin_arr.contains(&new_admin_id), Error::<T>::AlreadyAdmin);789            }790791            // Number of collection admins792            ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, Error::<T>::CollectionAdminsLimitExceeded);793794            admin_arr.push(new_admin_id);795            <AdminList<T>>::insert(collection_id, admin_arr);796797            Ok(())798        }799800        /// 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.801        ///802        /// # Permissions803        /// 804        /// * Collection Owner.805        /// * Collection Admin.806        /// 807        /// # Arguments808        /// 809        /// * collection_id: ID of the Collection to remove admin for.810        /// 811        /// * account_id: Address of admin to remove.812        #[weight = T::WeightInfo::remove_collection_admin()]813        pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::AccountId) -> DispatchResult {814815            let sender = ensure_signed(origin)?;816            Self::check_owner_or_admin_permissions(collection_id, sender)?;817            ensure!(<AdminList<T>>::contains_key(collection_id), Error::<T>::AdminNotFound);818819            let mut admin_arr = <AdminList<T>>::get(collection_id);820            admin_arr.retain(|i| *i != account_id);821            <AdminList<T>>::insert(collection_id, admin_arr);822823            Ok(())824        }825826        /// # Permissions827        /// 828        /// * Collection Owner829        /// 830        /// # Arguments831        /// 832        /// * collection_id.833        /// 834        /// * new_sponsor.835        #[weight = T::WeightInfo::set_collection_sponsor()]836        pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {837838            let sender = ensure_signed(origin)?;839            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);840841            let mut target_collection = <Collection<T>>::get(collection_id);842            ensure!(sender == target_collection.owner, Error::<T>::NoPermission);843844            target_collection.sponsor = new_sponsor;845            target_collection.sponsor_confirmed = false;846            <Collection<T>>::insert(collection_id, target_collection);847848            Ok(())849        }850851        /// # Permissions852        /// 853        /// * Sponsor.854        /// 855        /// # Arguments856        /// 857        /// * collection_id.858        #[weight = T::WeightInfo::confirm_sponsorship()]859        pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {860861            let sender = ensure_signed(origin)?;862            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);863864            let mut target_collection = <Collection<T>>::get(collection_id);865            ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);866867            target_collection.sponsor_confirmed = true;868            <Collection<T>>::insert(collection_id, target_collection);869870            Ok(())871        }872873        /// Switch back to pay-per-own-transaction model.874        ///875        /// # Permissions876        ///877        /// * Collection owner.878        /// 879        /// # Arguments880        /// 881        /// * collection_id.882        #[weight = T::WeightInfo::remove_collection_sponsor()]883        pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {884885            let sender = ensure_signed(origin)?;886            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);887888            let mut target_collection = <Collection<T>>::get(collection_id);889            ensure!(sender == target_collection.owner, Error::<T>::NoPermission);890891            target_collection.sponsor = T::AccountId::default();892            target_collection.sponsor_confirmed = false;893            <Collection<T>>::insert(collection_id, target_collection);894895            Ok(())896        }897898        /// This method creates a concrete instance of NFT Collection created with CreateCollection method.899        /// 900        /// # Permissions901        /// 902        /// * Collection Owner.903        /// * Collection Admin.904        /// * Anyone if905        ///     * White List is enabled, and906        ///     * Address is added to white list, and907        ///     * MintPermission is enabled (see SetMintPermission method)908        /// 909        /// # Arguments910        /// 911        /// * collection_id: ID of the collection.912        /// 913        /// * owner: Address, initial owner of the NFT.914        ///915        /// * data: Token data to store on chain.916        // #[weight =917        // (130_000_000 as Weight)918        // .saturating_add((2135 as Weight).saturating_mul((properties.len() as u64) as Weight))919        // .saturating_add(RocksDbWeight::get().reads(10 as Weight))920        // .saturating_add(RocksDbWeight::get().writes(8 as Weight))]921922        #[weight = T::WeightInfo::create_item(data.len())]923        pub fn create_item(origin, collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {924925            let sender = ensure_signed(origin)?;926927            Self::collection_exists(collection_id)?;928929            let target_collection = <Collection<T>>::get(collection_id);930931            Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;932            Self::validate_create_item_args(&target_collection, &data)?;933            Self::create_item_no_validation(collection_id, &target_collection, owner, data)?;934935            Ok(())936        }937938        /// This method creates multiple instances of NFT Collection created with CreateCollection method.939        /// 940        /// # Permissions941        /// 942        /// * Collection Owner.943        /// * Collection Admin.944        /// * Anyone if945        ///     * White List is enabled, and946        ///     * Address is added to white list, and947        ///     * MintPermission is enabled (see SetMintPermission method)948        /// 949        /// # Arguments950        /// 951        /// * collection_id: ID of the collection.952        /// 953        /// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].954        /// 955        /// * owner: Address, initial owner of the NFT.956        #[weight = T::WeightInfo::create_item(items_data.into_iter()957                               .map(|data| { data.len() })958                               .sum())]959        pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::AccountId, items_data: Vec<CreateItemData>) -> DispatchResult {960961            ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);962            let sender = ensure_signed(origin)?;963964            Self::collection_exists(collection_id)?;965            let target_collection = <Collection<T>>::get(collection_id);966967            Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;968969            for data in &items_data {970                Self::validate_create_item_args(&target_collection, data)?;971            }972            for data in &items_data {973                Self::create_item_no_validation(collection_id, &target_collection, owner.clone(), data.clone())?;974            }975976            Ok(())977        }978979        /// Destroys a concrete instance of NFT.980        /// 981        /// # Permissions982        /// 983        /// * Collection Owner.984        /// * Collection Admin.985        /// * Current NFT Owner.986        /// 987        /// # Arguments988        /// 989        /// * collection_id: ID of the collection.990        /// 991        /// * item_id: ID of NFT to burn.992        #[weight = T::WeightInfo::burn_item()]993        pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {994995            let sender = ensure_signed(origin)?;996            Self::collection_exists(collection_id)?;997998            // Transfer permissions check999            let target_collection = <Collection<T>>::get(collection_id);1000            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1001                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1002                Error::<T>::NoPermission);10031004            if target_collection.access == AccessMode::WhiteList {1005                Self::check_white_list(collection_id, &sender)?;1006            }10071008            match target_collection.mode1009            {1010                CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,1011                CollectionMode::Fungible(_)  => Self::burn_fungible_item(&sender, collection_id, value)?,1012                CollectionMode::ReFungible(_)  => Self::burn_refungible_item(collection_id, item_id, &sender)?,1013                _ => ()1014            };10151016            // call event1017            Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));10181019            Ok(())1020        }10211022        /// Change ownership of the token.1023        /// 1024        /// # Permissions1025        /// 1026        /// * Collection Owner1027        /// * Collection Admin1028        /// * Current NFT owner1029        ///1030        /// # Arguments1031        /// 1032        /// * recipient: Address of token recipient.1033        /// 1034        /// * collection_id.1035        /// 1036        /// * item_id: ID of the item1037        ///     * Non-Fungible Mode: Required.1038        ///     * Fungible Mode: Ignored.1039        ///     * Re-Fungible Mode: Required.1040        /// 1041        /// * value: Amount to transfer.1042        ///     * Non-Fungible Mode: Ignored1043        ///     * Fungible Mode: Must specify transferred amount1044        ///     * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)1045        #[weight = T::WeightInfo::transfer()]1046        pub fn transfer(origin, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {10471048            let sender = ensure_signed(origin)?;1049            let target_collection = <Collection<T>>::get(collection_id);10501051            // Limits check1052            Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;10531054            // Transfer permissions check1055            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1056                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1057                Error::<T>::NoPermission);10581059            if target_collection.access == AccessMode::WhiteList {1060                Self::check_white_list(collection_id, &sender)?;1061                Self::check_white_list(collection_id, &recipient)?;1062            }10631064            match target_collection.mode1065            {1066                CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,1067                CollectionMode::Fungible(_)  => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,1068                CollectionMode::ReFungible(_)  => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient)?,1069                _ => ()1070            };10711072            Ok(())1073        }10741075        /// Set, change, or remove approved address to transfer the ownership of the NFT.1076        /// 1077        /// # Permissions1078        /// 1079        /// * Collection Owner1080        /// * Collection Admin1081        /// * Current NFT owner1082        /// 1083        /// # Arguments1084        /// 1085        /// * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).1086        /// 1087        /// * collection_id.1088        /// 1089        /// * item_id: ID of the item.1090        #[weight = T::WeightInfo::approve()]1091        pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {10921093            let sender = ensure_signed(origin)?;10941095            Self::collection_exists(collection_id)?;1096            Self::token_exists(collection_id, item_id, &sender)?;10971098            // Transfer permissions check1099            let target_collection = <Collection<T>>::get(collection_id);1100            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1101                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1102                Error::<T>::NoPermission);11031104            if target_collection.access == AccessMode::WhiteList {1105                Self::check_white_list(collection_id, &sender)?;1106                Self::check_white_list(collection_id, &spender)?;1107            }11081109            let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));1110            let mut allowance: u128 = amount;1111            if allowance_exists {1112                allowance += <Allowances<T>>::get(collection_id, (item_id, &sender, &spender));1113            }1114            <Allowances<T>>::insert(collection_id, (item_id, sender.clone(), spender.clone()), allowance);11151116            Ok(())1117        }1118        1119        /// 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.1120        /// 1121        /// # Permissions1122        /// * Collection Owner1123        /// * Collection Admin1124        /// * Current NFT owner1125        /// * Address approved by current NFT owner1126        /// 1127        /// # Arguments1128        /// 1129        /// * from: Address that owns token.1130        /// 1131        /// * recipient: Address of token recipient.1132        /// 1133        /// * collection_id.1134        /// 1135        /// * item_id: ID of the item.1136        /// 1137        /// * value: Amount to transfer.1138        #[weight = T::WeightInfo::transfer_from()]1139        pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {11401141            let sender = ensure_signed(origin)?;1142            let mut appoved_transfer = false;11431144            // Check approval1145            let mut approval: u128 = 0;1146            if <Allowances<T>>::contains_key(collection_id, (item_id, &from, &recipient)) {1147                approval = <Allowances<T>>::get(collection_id, (item_id, &from, &recipient));1148                ensure!(approval >= value, Error::<T>::TokenValueNotEnough);1149                appoved_transfer = true;1150            }11511152            let target_collection = <Collection<T>>::get(collection_id);11531154            // Limits check1155            Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;11561157            // Transfer permissions check         1158            ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1159                Error::<T>::NoPermission);11601161            if target_collection.access == AccessMode::WhiteList {1162                Self::check_white_list(collection_id, &sender)?;1163                Self::check_white_list(collection_id, &recipient)?;1164            }11651166            // Reduce approval by transferred amount or remove if remaining approval drops to 01167            if approval.checked_sub(value).unwrap_or(0) > 0 {1168                <Allowances<T>>::insert(collection_id, (item_id, &from, &recipient), approval - value);1169            }1170            else {1171                <Allowances<T>>::remove(collection_id, (item_id, &from, &recipient));1172            }11731174            match target_collection.mode1175            {1176                CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,1177                CollectionMode::Fungible(_)  => Self::transfer_fungible(collection_id, value, &from, &recipient)?,1178                CollectionMode::ReFungible(_)  => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,1179                _ => ()1180            };11811182            Ok(())1183        }11841185        #[weight = 0]1186        pub fn safe_transfer_from(origin, collection_id: CollectionId, item_id: TokenId, new_owner: T::AccountId) -> DispatchResult {11871188            // let no_perm_mes = "You do not have permissions to modify this collection";1189            // ensure!(<ApprovedList<T>>::contains_key((collection_id, item_id)), no_perm_mes);1190            // let list_itm = <ApprovedList<T>>::get((collection_id, item_id));1191            // ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes);11921193            // // on_nft_received  call11941195            // Self::transfer(origin, collection_id, item_id, new_owner)?;11961197            Ok(())1198        }11991200        /// Set off-chain data schema.1201        /// 1202        /// # Permissions1203        /// 1204        /// * Collection Owner1205        /// * Collection Admin1206        /// 1207        /// # Arguments1208        /// 1209        /// * collection_id.1210        /// 1211        /// * schema: String representing the offchain data schema.1212        #[weight = T::WeightInfo::set_variable_meta_data()]1213        pub fn set_variable_meta_data (1214            origin,1215            collection_id: CollectionId,1216            item_id: TokenId,1217            data: Vec<u8>1218        ) -> DispatchResult {1219            let sender = ensure_signed(origin)?;1220            1221            Self::collection_exists(collection_id)?;1222            Self::token_exists(collection_id, item_id, &sender)?;12231224            ensure!(ChainLimit::get().custom_data_limit >= data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);12251226            // Modify permissions check1227            let target_collection = <Collection<T>>::get(collection_id);1228            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1229                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1230                Error::<T>::NoPermission);12311232            match target_collection.mode1233            {1234                CollectionMode::NFT => Self::set_nft_variable_data(collection_id, item_id, data)?,1235                CollectionMode::ReFungible(_)  => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,1236                CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),1237                _ => fail!(Error::<T>::UnexpectedCollectionType)1238            };12391240            Ok(())1241        }1242 1243        /// Set schema standard1244        /// ImageURL1245        /// Unique1246        /// 1247        /// # Permissions1248        /// 1249        /// * Collection Owner1250        /// * Collection Admin1251        /// 1252        /// # Arguments1253        /// 1254        /// * collection_id.1255        /// 1256        /// * schema: SchemaVersion: enum1257        #[weight = T::WeightInfo::set_schema_version()]1258        pub fn set_schema_version(1259            origin,1260            collection_id: CollectionId,1261            version: SchemaVersion1262        ) -> DispatchResult {1263            let sender = ensure_signed(origin)?;1264            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1265            let mut target_collection = <Collection<T>>::get(collection_id);1266            target_collection.schema_version = version;1267            <Collection<T>>::insert(collection_id, target_collection);12681269            Ok(())1270        }12711272        /// Set off-chain data schema.1273        /// 1274        /// # Permissions1275        /// 1276        /// * Collection Owner1277        /// * Collection Admin1278        /// 1279        /// # Arguments1280        /// 1281        /// * collection_id.1282        /// 1283        /// * schema: String representing the offchain data schema.1284        #[weight = T::WeightInfo::set_offchain_schema()]1285        pub fn set_offchain_schema(1286            origin,1287            collection_id: CollectionId,1288            schema: Vec<u8>1289        ) -> DispatchResult {1290            let sender = ensure_signed(origin)?;1291            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;12921293            // check schema limit1294            ensure!(schema.len() as u32 > ChainLimit::get().offchain_schema_limit, "");12951296            let mut target_collection = <Collection<T>>::get(collection_id);1297            target_collection.offchain_schema = schema;1298            <Collection<T>>::insert(collection_id, target_collection);12991300            Ok(())1301        }13021303        /// Set const on-chain data schema.1304        /// 1305        /// # Permissions1306        /// 1307        /// * Collection Owner1308        /// * Collection Admin1309        /// 1310        /// # Arguments1311        /// 1312        /// * collection_id.1313        /// 1314        /// * schema: String representing the const on-chain data schema.1315        #[weight = T::WeightInfo::set_const_on_chain_schema()]1316        pub fn set_const_on_chain_schema (1317            origin,1318            collection_id: CollectionId,1319            schema: Vec<u8>1320        ) -> DispatchResult {1321            let sender = ensure_signed(origin)?;1322            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13231324            // check schema limit1325            ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");13261327            let mut target_collection = <Collection<T>>::get(collection_id);1328            target_collection.const_on_chain_schema = schema;1329            <Collection<T>>::insert(collection_id, target_collection);13301331            Ok(())1332        }13331334        /// Set variable on-chain data schema.1335        /// 1336        /// # Permissions1337        /// 1338        /// * Collection Owner1339        /// * Collection Admin1340        /// 1341        /// # Arguments1342        /// 1343        /// * collection_id.1344        /// 1345        /// * schema: String representing the variable on-chain data schema.1346        #[weight = T::WeightInfo::set_const_on_chain_schema()]1347        pub fn set_variable_on_chain_schema (1348            origin,1349            collection_id: CollectionId,1350            schema: Vec<u8>1351        ) -> DispatchResult {1352            let sender = ensure_signed(origin)?;1353            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13541355            // check schema limit1356            ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");13571358            let mut target_collection = <Collection<T>>::get(collection_id);1359            target_collection.variable_on_chain_schema = schema;1360            <Collection<T>>::insert(collection_id, target_collection);13611362            Ok(())1363        }13641365        // Sudo permissions function1366        #[weight = T::WeightInfo::set_chain_limits()]1367        pub fn set_chain_limits(1368            origin,1369            limits: ChainLimits1370        ) -> DispatchResult {13711372            #[cfg(not(feature = "runtime-benchmarks"))]1373            ensure_root(origin)?;13741375            <ChainLimit>::put(limits);1376            Ok(())1377        }13781379        /// Enable smart contract self-sponsoring.1380        /// 1381        /// # Permissions1382        /// 1383        /// * Contract Owner1384        /// 1385        /// # Arguments1386        /// 1387        /// * contract address1388        /// * enable flag1389        /// 1390        #[weight = T::WeightInfo::enable_contract_sponsoring()]1391        pub fn enable_contract_sponsoring(1392            origin,1393            contract_address: T::AccountId,1394            enable: bool1395        ) -> DispatchResult {13961397            let sender = ensure_signed(origin)?;13981399            #[cfg(feature = "runtime-benchmarks")]1400            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14011402            Self::ensure_contract_owned(sender, &contract_address)?;14031404            <ContractSelfSponsoring<T>>::insert(contract_address, enable);1405            Ok(())1406        }14071408        /// Set the rate limit for contract sponsoring to specified number of blocks.1409        /// 1410        /// If not set (has the default value of 0 blocks), the sponsoring will be disabled. 1411        /// If set to the number B (for blocks), the transactions will be sponsored with a rate 1412        /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid 1413        /// from contract endowment if there are at least B blocks between such transactions. 1414        /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.1415        /// 1416        /// # Permissions1417        /// 1418        /// * Contract Owner1419        /// 1420        /// # Arguments1421        /// 1422        /// -`contract_address`: Address of the contract to sponsor1423        /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed1424        /// 1425        #[weight = T::WeightInfo::set_contract_sponsoring_rate_limit()]1426        pub fn set_contract_sponsoring_rate_limit(1427            origin,1428            contract_address: T::AccountId,1429            rate_limit: T::BlockNumber1430        ) -> DispatchResult {1431            let sender = ensure_signed(origin)?;14321433            #[cfg(feature = "runtime-benchmarks")]1434            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14351436            Self::ensure_contract_owned(sender, &contract_address)?;1437            <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);1438            Ok(())1439        }14401441        /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.1442        /// 1443        /// # Permissions1444        /// 1445        /// * Address that deployed smart contract.1446        /// 1447        /// # Arguments1448        /// 1449        /// -`contract_address`: Address of the contract.1450        /// 1451        /// - `enable`: .  1452        #[weight = T::WeightInfo::toggle_contract_white_list()]1453        pub fn toggle_contract_white_list(1454            origin,1455            contract_address: T::AccountId,1456            enable: bool1457        ) -> DispatchResult {1458            let sender = ensure_signed(origin)?;14591460            #[cfg(feature = "runtime-benchmarks")]1461            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14621463            Self::ensure_contract_owned(sender, &contract_address)?;1464            <ContractWhiteListEnabled<T>>::insert(contract_address, enable);1465            Ok(())1466        }1467        1468        /// Add an address to smart contract white list.1469        /// 1470        /// # Permissions1471        /// 1472        /// * Address that deployed smart contract.1473        /// 1474        /// # Arguments1475        /// 1476        /// -`contract_address`: Address of the contract.1477        ///1478        /// -`account_address`: Address to add.1479        #[weight = T::WeightInfo::add_to_contract_white_list()]1480        pub fn add_to_contract_white_list(1481            origin,1482            contract_address: T::AccountId,1483            account_address: T::AccountId1484        ) -> DispatchResult {1485            let sender = ensure_signed(origin)?;14861487            #[cfg(feature = "runtime-benchmarks")]1488            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());1489            1490            Self::ensure_contract_owned(sender, &contract_address)?;      1491            <ContractWhiteList<T>>::insert(contract_address, account_address, true);1492            Ok(())1493        }14941495        /// Remove an address from smart contract white list.1496        /// 1497        /// # Permissions1498        /// 1499        /// * Address that deployed smart contract.1500        /// 1501        /// # Arguments1502        /// 1503        /// -`contract_address`: Address of the contract.1504        ///1505        /// -`account_address`: Address to remove.1506        #[weight = T::WeightInfo::remove_from_contract_white_list()]1507        pub fn remove_from_contract_white_list(1508            origin,1509            contract_address: T::AccountId,1510            account_address: T::AccountId1511        ) -> DispatchResult {1512            let sender = ensure_signed(origin)?;15131514            #[cfg(feature = "runtime-benchmarks")]1515            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());15161517            Self::ensure_contract_owned(sender, &contract_address)?;1518            <ContractWhiteList<T>>::remove(contract_address, account_address);1519            Ok(())1520        }15211522        #[weight = T::WeightInfo::set_collection_limits()]1523        pub fn set_collection_limits(1524            origin,1525            collection_id: u32,1526            limits: CollectionLimits,1527        ) -> DispatchResult {1528            let sender = ensure_signed(origin)?;1529            Self::check_owner_permissions(collection_id, sender.clone())?;1530            let mut target_collection = <Collection<T>>::get(collection_id);1531            let chain_limits = ChainLimit::get();1532            let climits = target_collection.limits;15331534            // collection bounds1535            ensure!(limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&1536                limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP,  1537                Error::<T>::CollectionLimitBoundsExceeded);15381539            // token_limit   check  prev1540            ensure!(climits.token_limit > limits.token_limit && 1541                limits.token_limit <= chain_limits.account_token_ownership_limit, 1542                Error::<T>::AccountTokenLimitExceeded);15431544            target_collection.limits = limits;1545            <Collection<T>>::insert(collection_id, target_collection);15461547            Ok(())1548        } 1549    }1550}15511552impl<T: Trait> Module<T> {15531554    fn is_correct_transfer(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, recipient: &T::AccountId) -> DispatchResult {15551556        // check token limit and account token limit1557        let account_items: u32 = <AddressTokens<T>>::get(collection_id, recipient).len() as u32;1558        ensure!(collection.limits.account_token_ownership_limit > account_items,  Error::<T>::AccountTokenLimitExceeded);1559        1560        Ok(())1561    }15621563    fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {15641565        // check token limit and account token limit1566        let total_items: u32 = ItemListIndex::get(collection_id);1567        let account_items: u32 = <AddressTokens<T>>::get(collection_id, owner).len() as u32;1568        ensure!(collection.limits.token_limit > total_items,  Error::<T>::CollectionTokenLimitExceeded);1569        ensure!(collection.limits.account_token_ownership_limit > account_items,  Error::<T>::AccountTokenLimitExceeded);15701571        if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {1572            ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);1573            Self::check_white_list(collection_id, owner)?;1574            Self::check_white_list(collection_id, sender)?;1575        }15761577        Ok(())1578    }15791580    fn validate_create_item_args(target_collection: &CollectionType<T::AccountId>, data: &CreateItemData) -> DispatchResult {1581        match target_collection.mode1582        {1583            CollectionMode::NFT => {1584                if let CreateItemData::NFT(data) = data {1585                    // check sizes1586                    ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);1587                    ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);1588                } else {1589                    fail!(Error::<T>::NotNftDataUsedToMintNftCollectionToken);1590                }1591            },1592            CollectionMode::Fungible(_) => {1593                if let CreateItemData::Fungible(_) = data {1594                } else {1595                    fail!(Error::<T>::NotFungibleDataUsedToMintFungibleCollectionToken);1596                }1597            },1598            CollectionMode::ReFungible(_) => {1599                if let CreateItemData::ReFungible(data) = data {16001601                    // check sizes1602                    ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);1603                    ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);1604                } else {1605                    fail!(Error::<T>::NotReFungibleDataUsedToMintReFungibleCollectionToken);1606                }1607            },1608            _ => { fail!(Error::<T>::UnexpectedCollectionType); }1609        };16101611        Ok(())1612    }16131614    fn create_item_no_validation(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1615        match data1616        {1617            CreateItemData::NFT(data) => {1618                let item = NftItemType {1619                    owner,1620                    const_data: data.const_data,1621                    variable_data: data.variable_data1622                };16231624                Self::add_nft_item(collection_id, item)?;1625            },1626            CreateItemData::Fungible(data) => {1627                Self::add_fungible_item(collection_id, &owner, data.value)?;1628            },1629            CreateItemData::ReFungible(data) => {1630                let mut owner_list = Vec::new();1631                let value = (10 as u128).pow(collection.decimal_points as u32);1632                owner_list.push(Ownership {owner: owner.clone(), fraction: value});16331634                let item = ReFungibleItemType {1635                    owner: owner_list,1636                    const_data: data.const_data,1637                    variable_data: data.variable_data1638                };16391640                Self::add_refungible_item(collection_id, item)?;1641            }1642        };16431644        // call event1645        Self::deposit_event(RawEvent::ItemCreated(collection_id, <ItemListIndex>::get(collection_id)));16461647        Ok(())1648    }16491650    fn add_fungible_item(collection_id: CollectionId, owner: &T::AccountId, value: u128) -> DispatchResult {16511652        // Does new owner already have an account?1653        let mut balance: u128 = 0;1654        if <FungibleItemList<T>>::contains_key(collection_id, owner) {1655            balance = <FungibleItemList<T>>::get(collection_id, owner).value;1656        } 16571658        // Mint 1659        let item = FungibleItemType {1660            value: balance + value1661        };1662        <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), item);16631664        // Update balance1665        let new_balance = <Balance<T>>::get(collection_id, owner)1666            .checked_add(value)1667            .ok_or(Error::<T>::NumOverflow)?;1668        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);16691670        Ok(())1671    }16721673    fn add_refungible_item(collection_id: CollectionId, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {1674        let current_index = <ItemListIndex>::get(collection_id)1675            .checked_add(1)1676            .ok_or(Error::<T>::NumOverflow)?;1677        let itemcopy = item.clone();16781679        let value = item.owner.first().unwrap().fraction;1680        let owner = item.owner.first().unwrap().owner.clone();16811682        Self::add_token_index(collection_id, current_index, &owner)?;16831684        <ItemListIndex>::insert(collection_id, current_index);1685        <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);16861687        // Update balance1688        let new_balance = <Balance<T>>::get(collection_id, &owner)1689            .checked_add(value)1690            .ok_or(Error::<T>::NumOverflow)?;1691        <Balance<T>>::insert(collection_id, owner.clone(), new_balance);16921693        Ok(())1694    }16951696    fn add_nft_item(collection_id: CollectionId, item: NftItemType<T::AccountId>) -> DispatchResult {1697        let current_index = <ItemListIndex>::get(collection_id)1698            .checked_add(1)1699            .ok_or(Error::<T>::NumOverflow)?;17001701        let item_owner = item.owner.clone();1702        Self::add_token_index(collection_id, current_index, &item.owner)?;17031704        <ItemListIndex>::insert(collection_id, current_index);1705        <NftItemList<T>>::insert(collection_id, current_index, item);17061707        // Update balance1708        let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())1709            .checked_add(1)1710            .ok_or(Error::<T>::NumOverflow)?;1711        <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);17121713        Ok(())1714    }17151716    fn burn_refungible_item(1717        collection_id: CollectionId,1718        item_id: TokenId,1719        owner: &T::AccountId,1720    ) -> DispatchResult {1721        ensure!(1722            <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1723            Error::<T>::TokenNotFound1724        );1725        let mut token = <ReFungibleItemList<T>>::get(collection_id, item_id);1726        let rft_balance = token1727            .owner1728            .iter()1729            .filter(|&i| i.owner == *owner)1730            .next()1731            .unwrap();1732        Self::remove_token_index(collection_id, item_id, owner)?;17331734        // update balance1735        let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.clone())1736            .checked_sub(rft_balance.fraction)1737            .ok_or(Error::<T>::NumOverflow)?;1738        <Balance<T>>::insert(collection_id, rft_balance.owner.clone(), new_balance);17391740        // Re-create owners list with sender removed1741        let index = token1742            .owner1743            .iter()1744            .position(|i| i.owner == *owner)1745            .unwrap();1746        token.owner.remove(index);1747        let owner_count = token.owner.len();17481749        // Burn the token completely if this was the last (only) owner1750        if owner_count == 0 {1751            <ReFungibleItemList<T>>::remove(collection_id, item_id);1752        }1753        else {1754            <ReFungibleItemList<T>>::insert(collection_id, item_id, token);1755        }17561757        Ok(())1758    }17591760    fn burn_nft_item(collection_id: CollectionId, item_id: TokenId) -> DispatchResult {1761        ensure!(1762            <NftItemList<T>>::contains_key(collection_id, item_id),1763            Error::<T>::TokenNotFound1764        );1765        let item = <NftItemList<T>>::get(collection_id, item_id);1766        Self::remove_token_index(collection_id, item_id, &item.owner)?;17671768        // update balance1769        let new_balance = <Balance<T>>::get(collection_id, &item.owner)1770            .checked_sub(1)1771            .ok_or(Error::<T>::NumOverflow)?;1772        <Balance<T>>::insert(collection_id, item.owner.clone(), new_balance);1773        <NftItemList<T>>::remove(collection_id, item_id);17741775        Ok(())1776    }17771778    fn burn_fungible_item(owner: &T::AccountId, collection_id: CollectionId, value: u128) -> DispatchResult {1779        ensure!(1780            <FungibleItemList<T>>::contains_key(collection_id, owner),1781            Error::<T>::TokenNotFound1782        );1783        let mut balance = <FungibleItemList<T>>::get(collection_id, owner);1784        ensure!(balance.value >= value, Error::<T>::TokenValueNotEnough);17851786        // update balance1787        let new_balance = <Balance<T>>::get(collection_id, owner)1788            .checked_sub(value)1789            .ok_or(Error::<T>::NumOverflow)?;1790        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);17911792        if balance.value - value > 0 {1793            balance.value -= value;1794            <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);1795        }1796        else {1797            <FungibleItemList<T>>::remove(collection_id, owner);1798        }17991800        Ok(())1801    }18021803    fn collection_exists(collection_id: CollectionId) -> DispatchResult {1804        ensure!(1805            <Collection<T>>::contains_key(collection_id),1806            Error::<T>::CollectionNotFound1807        );1808        Ok(())1809    }18101811    fn check_owner_permissions(collection_id: CollectionId, subject: T::AccountId) -> DispatchResult {1812        Self::collection_exists(collection_id)?;18131814        let target_collection = <Collection<T>>::get(collection_id);1815        ensure!(1816            subject == target_collection.owner,1817            Error::<T>::NoPermission1818        );18191820        Ok(())1821    }18221823    fn is_owner_or_admin_permissions(collection_id: CollectionId, subject: T::AccountId) -> bool {1824        let target_collection = <Collection<T>>::get(collection_id);1825        let mut result: bool = subject == target_collection.owner;1826        let exists = <AdminList<T>>::contains_key(collection_id);18271828        if !result & exists {1829            if <AdminList<T>>::get(collection_id).contains(&subject) {1830                result = true1831            }1832        }18331834        result1835    }18361837    fn check_owner_or_admin_permissions(1838        collection_id: CollectionId,1839        subject: T::AccountId,1840    ) -> DispatchResult {1841        Self::collection_exists(collection_id)?;1842        let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());18431844        ensure!(1845            result,1846            Error::<T>::NoPermission1847        );1848        Ok(())1849    }18501851    fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool {1852        let target_collection = <Collection<T>>::get(collection_id);18531854        match target_collection.mode {1855            CollectionMode::NFT => {1856                <NftItemList<T>>::get(collection_id, item_id).owner == subject1857            }1858            CollectionMode::Fungible(_) => {1859                <FungibleItemList<T>>::contains_key(collection_id, &subject)1860            }1861            CollectionMode::ReFungible(_) => {1862                <ReFungibleItemList<T>>::get(collection_id, item_id)1863                    .owner1864                    .iter()1865                    .any(|i| i.owner == subject)1866            }1867            CollectionMode::Invalid => false,1868        }1869    }18701871    fn check_white_list(collection_id: CollectionId, address: &T::AccountId) -> DispatchResult {1872        let mes = Error::<T>::AddresNotInWhiteList;1873        ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);18741875        Ok(())1876    }18771878    /// Check if token exists. In case of Fungible, check if there is an entry for 1879    /// the owner in fungible balances double map1880    fn token_exists(1881        collection_id: CollectionId,1882        item_id: TokenId,1883        owner: &T::AccountId1884    ) -> DispatchResult {1885        let target_collection = <Collection<T>>::get(collection_id);1886        let exists = match target_collection.mode1887        {1888            CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),1889            CollectionMode::Fungible(_)  => <FungibleItemList<T>>::contains_key(collection_id, owner),1890            CollectionMode::ReFungible(_)  => <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1891            _ => false1892        };18931894        ensure!(exists == true, Error::<T>::TokenNotFound);1895        Ok(())1896    }18971898    fn transfer_fungible(1899        collection_id: CollectionId,1900        value: u128,1901        owner: &T::AccountId,1902        recipient: &T::AccountId,1903    ) -> DispatchResult {1904        Self::token_exists(collection_id, 0, owner)?;19051906        let mut balance = <FungibleItemList<T>>::get(collection_id, owner);1907        ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);19081909        // Send balance to recipient (updates balanceOf of recipient)1910        Self::add_fungible_item(collection_id, recipient, value)?;19111912        // update balanceOf of sender1913        <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);19141915        // Reduce or remove sender1916        if balance.value == value {1917            <FungibleItemList<T>>::remove(collection_id, owner);1918        }1919        else {1920            balance.value -= value;1921            <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);1922        }19231924        Ok(())1925    }19261927    fn transfer_refungible(1928        collection_id: CollectionId,1929        item_id: TokenId,1930        value: u128,1931        owner: T::AccountId,1932        new_owner: T::AccountId,1933    ) -> DispatchResult {1934        Self::token_exists(collection_id, item_id, &owner)?;19351936        let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);1937        let item = full_item1938            .owner1939            .iter()1940            .filter(|i| i.owner == owner)1941            .next()1942            .ok_or(Error::<T>::NumOverflow)?;1943        let amount = item.fraction;19441945        ensure!(amount >= value, Error::<T>::TokenValueTooLow);19461947        // update balance1948        let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone())1949            .checked_sub(value)1950            .ok_or(Error::<T>::NumOverflow)?;1951        <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);19521953        let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())1954            .checked_add(value)1955            .ok_or(Error::<T>::NumOverflow)?;1956        <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);19571958        let old_owner = item.owner.clone();1959        let new_owner_has_account = full_item.owner.iter().any(|i| i.owner == new_owner);19601961        // transfer1962        if amount == value && !new_owner_has_account {1963            // change owner1964            // new owner do not have account1965            let mut new_full_item = full_item.clone();1966            new_full_item1967                .owner1968                .iter_mut()1969                .find(|i| i.owner == owner)1970                .unwrap()1971                .owner = new_owner.clone();1972            <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);19731974            // update index collection1975            Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;1976        } else {1977            let mut new_full_item = full_item.clone();1978            new_full_item1979                .owner1980                .iter_mut()1981                .find(|i| i.owner == owner)1982                .unwrap()1983                .fraction -= value;19841985            // separate amount1986            if new_owner_has_account {1987                // new owner has account1988                new_full_item1989                    .owner1990                    .iter_mut()1991                    .find(|i| i.owner == new_owner)1992                    .unwrap()1993                    .fraction += value;1994            } else {1995                // new owner do not have account1996                new_full_item.owner.push(Ownership {1997                    owner: new_owner.clone(),1998                    fraction: value,1999                });2000                Self::add_token_index(collection_id, item_id, &new_owner)?;2001            }20022003            <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2004        }20052006        Ok(())2007    }20082009    fn transfer_nft(2010        collection_id: CollectionId,2011        item_id: TokenId,2012        sender: T::AccountId,2013        new_owner: T::AccountId,2014    ) -> DispatchResult {2015        Self::token_exists(collection_id, item_id, &sender)?;20162017        let mut item = <NftItemList<T>>::get(collection_id, item_id);20182019        ensure!(2020            sender == item.owner,2021            Error::<T>::MustBeTokenOwner2022        );20232024        // update balance2025        let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone())2026            .checked_sub(1)2027            .ok_or(Error::<T>::NumOverflow)?;2028        <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);20292030        let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())2031            .checked_add(1)2032            .ok_or(Error::<T>::NumOverflow)?;2033        <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);20342035        // change owner2036        let old_owner = item.owner.clone();2037        item.owner = new_owner.clone();2038        <NftItemList<T>>::insert(collection_id, item_id, item);20392040        // update index collection2041        Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;20422043        Ok(())2044    }2045    2046    fn set_re_fungible_variable_data(2047        collection_id: CollectionId,2048        item_id: TokenId,2049        data: Vec<u8>2050    ) -> DispatchResult {2051        let mut item = <ReFungibleItemList<T>>::get(collection_id, item_id);20522053        item.variable_data = data;20542055        <ReFungibleItemList<T>>::insert(collection_id, item_id, item);20562057        Ok(())2058    }20592060    fn set_nft_variable_data(2061        collection_id: CollectionId,2062        item_id: TokenId,2063        data: Vec<u8>2064    ) -> DispatchResult {2065        let mut item = <NftItemList<T>>::get(collection_id, item_id);2066        2067        item.variable_data = data;20682069        <NftItemList<T>>::insert(collection_id, item_id, item);2070        2071        Ok(())2072    }20732074    fn init_collection(item: &CollectionType<T::AccountId>) {2075        // check params2076        assert!(2077            item.decimal_points <= MAX_DECIMAL_POINTS,2078            "decimal_points parameter must be lower than MAX_DECIMAL_POINTS"2079        );2080        assert!(2081            item.name.len() <= 64,2082            "Collection name can not be longer than 63 char"2083        );2084        assert!(2085            item.name.len() <= 256,2086            "Collection description can not be longer than 255 char"2087        );2088        assert!(2089            item.token_prefix.len() <= 16,2090            "Token prefix can not be longer than 15 char"2091        );20922093        // Generate next collection ID2094        let next_id = CreatedCollectionCount::get()2095            .checked_add(1)2096            .unwrap();20972098        CreatedCollectionCount::put(next_id);2099    }21002101    fn init_nft_token(collection_id: CollectionId, item: &NftItemType<T::AccountId>) {2102        let current_index = <ItemListIndex>::get(collection_id)2103            .checked_add(1)2104            .unwrap();21052106        let item_owner = item.owner.clone();2107        Self::add_token_index(collection_id, current_index, &item.owner).unwrap();21082109        <ItemListIndex>::insert(collection_id, current_index);21102111        // Update balance2112        let new_balance = <Balance<T>>::get(collection_id, &item_owner)2113            .checked_add(1)2114            .unwrap();2115        <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);2116    }21172118    fn init_fungible_token(collection_id: CollectionId, owner: &T::AccountId, item: &FungibleItemType) {2119        let current_index = <ItemListIndex>::get(collection_id)2120            .checked_add(1)2121            .unwrap();21222123        Self::add_token_index(collection_id, current_index, owner).unwrap();21242125        <ItemListIndex>::insert(collection_id, current_index);21262127        // Update balance2128        let new_balance = <Balance<T>>::get(collection_id, owner)2129            .checked_add(item.value)2130            .unwrap();2131        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);2132    }21332134    fn init_refungible_token(collection_id: CollectionId, item: &ReFungibleItemType<T::AccountId>) {2135        let current_index = <ItemListIndex>::get(collection_id)2136            .checked_add(1)2137            .unwrap();21382139        let value = item.owner.first().unwrap().fraction;2140        let owner = item.owner.first().unwrap().owner.clone();21412142        Self::add_token_index(collection_id, current_index, &owner).unwrap();21432144        <ItemListIndex>::insert(collection_id, current_index);21452146        // Update balance2147        let new_balance = <Balance<T>>::get(collection_id, &owner)2148            .checked_add(value)2149            .unwrap();2150        <Balance<T>>::insert(collection_id, owner.clone(), new_balance);2151    }21522153    fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: &T::AccountId) -> DispatchResult {21542155        // add to account limit2156        if <AccountItemCount<T>>::contains_key(owner) {21572158            // bound Owned tokens by a single address2159            let count = <AccountItemCount<T>>::get(owner);2160            ensure!(count < ChainLimit::get().account_token_ownership_limit, Error::<T>::AddressOwnershipLimitExceeded);21612162            <AccountItemCount<T>>::insert(owner.clone(), count2163                .checked_add(1)2164                .ok_or(Error::<T>::NumOverflow)?);2165        }2166        else {2167            <AccountItemCount<T>>::insert(owner.clone(), 1);2168        }21692170        let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner);2171        if list_exists {2172            let mut list = <AddressTokens<T>>::get(collection_id, owner);2173            let item_contains = list.contains(&item_index.clone());21742175            if !item_contains {2176                list.push(item_index.clone());2177            }21782179            <AddressTokens<T>>::insert(collection_id, owner.clone(), list);2180        } else {2181            let mut itm = Vec::new();2182            itm.push(item_index.clone());2183            <AddressTokens<T>>::insert(collection_id, owner.clone(), itm);2184        }21852186        Ok(())2187    }21882189    fn remove_token_index(2190        collection_id: CollectionId,2191        item_index: TokenId,2192        owner: &T::AccountId,2193    ) -> DispatchResult {21942195        // update counter2196        <AccountItemCount<T>>::insert(owner.clone(), 2197            <AccountItemCount<T>>::get(owner)2198            .checked_sub(1)2199            .ok_or(Error::<T>::NumOverflow)?);220022012202        let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner);2203        if list_exists {2204            let mut list = <AddressTokens<T>>::get(collection_id, owner);2205            let item_contains = list.contains(&item_index.clone());22062207            if item_contains {2208                list.retain(|&item| item != item_index);2209                <AddressTokens<T>>::insert(collection_id, owner.clone(), list);2210            }2211        }22122213        Ok(())2214    }22152216    fn move_token_index(2217        collection_id: CollectionId,2218        item_index: TokenId,2219        old_owner: &T::AccountId,2220        new_owner: &T::AccountId,2221    ) -> DispatchResult {2222        Self::remove_token_index(collection_id, item_index, old_owner)?;2223        Self::add_token_index(collection_id, item_index, new_owner)?;22242225        Ok(())2226    }2227    2228    fn ensure_contract_owned(account: T::AccountId, contract: &T::AccountId) -> DispatchResult {2229        if <ContractOwner<T>>::contains_key(contract.clone()) {2230            let owner = <ContractOwner<T>>::get(contract);2231            ensure!(account == owner, Error::<T>::NoPermission);2232        } else {2233            fail!(Error::<T>::NoPermission);2234        }22352236        Ok(())2237    }2238}22392240////////////////////////////////////////////////////////////////////////////////////////////////////2241// Economic models2242// #region22432244/// Fee multiplier.2245pub type Multiplier = FixedU128;22462247type BalanceOf<T> = <<T as transaction_payment::Trait>::Currency as Currency<2248    <T as system::Trait>::AccountId,2249>>::Balance;2250type NegativeImbalanceOf<T> = <<T as transaction_payment::Trait>::Currency as Currency<2251    <T as system::Trait>::AccountId,2252>>::NegativeImbalance;22532254/// Require the transactor pay for themselves and maybe include a tip to gain additional priority2255/// in the queue.2256#[derive(Encode, Decode, Clone, Eq, PartialEq)]2257pub struct ChargeTransactionPayment<T: Trait + Send + Sync>(2258    #[codec(compact)] BalanceOf<T>2259);22602261impl<T: Trait + Send + Sync> sp_std::fmt::Debug2262    for ChargeTransactionPayment<T>2263{2264    #[cfg(feature = "std")]2265    fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {2266        write!(f, "ChargeTransactionPayment<{:?}>", self.0)2267    }2268    #[cfg(not(feature = "std"))]2269    fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {2270        Ok(())2271    }2272}22732274impl<T: Trait + Send + Sync> ChargeTransactionPayment<T>2275where2276    T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,2277    BalanceOf<T>: Send + Sync + FixedPointOperand,2278{2279    /// utility constructor. Used only in client/factory code.2280    pub fn from(fee: BalanceOf<T>) -> Self {2281        Self(fee)2282    }22832284    pub fn traditional_fee(2285        len: usize,2286        info: &DispatchInfoOf<T::Call>,2287        tip: BalanceOf<T>,2288    ) -> BalanceOf<T>2289    where2290        T::Call: Dispatchable<Info = DispatchInfo>,2291    {2292        <transaction_payment::Module<T>>::compute_fee(len as u32, info, tip)2293    }22942295	fn get_priority(len: usize, info: &DispatchInfoOf<T::Call>, final_fee: BalanceOf<T>) -> TransactionPriority {2296		let weight_saturation = T::MaximumBlockWeight::get() / info.weight.max(1);2297		let len_saturation = T::MaximumBlockLength::get() as u64 / (len as u64).max(1);2298		let coefficient: BalanceOf<T> = weight_saturation.min(len_saturation).saturated_into::<BalanceOf<T>>();2299		final_fee.saturating_mul(coefficient).saturated_into::<TransactionPriority>()2300	}23012302    fn withdraw_fee(2303        &self,2304        who: &T::AccountId,2305        call: &T::Call,2306        info: &DispatchInfoOf<T::Call>,2307        len: usize,2308    ) -> Result<(BalanceOf<T>, Option<NegativeImbalanceOf<T>>), TransactionValidityError> {2309        let tip = self.0;23102311        // Set fee based on call type. Creating collection costs 1 Unique.2312        // All other transactions have traditional fees so far2313        // let fee = match call.is_sub_type() {2314        //     Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),2315        //     _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes2316        //                                                 // _ => <BalanceOf<T>>::from(100)2317        // };2318        let fee = Self::traditional_fee(len, info, tip);23192320        // Only mess with balances if fee is not zero.2321        if fee.is_zero() {2322            return Ok((fee, None));2323        }23242325        // Determine who is paying transaction fee based on ecnomic model2326        // Parse call to extract collection ID and access collection sponsor2327        let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {2328            Some(Call::create_item(collection_id, _owner, _properties)) => {23292330                // sponsor timeout2331                let block_number = <system::Module<T>>::block_number() as T::BlockNumber;23322333                let limit = <Collection<T>>::get(collection_id).limits.sponsor_transfer_timeout;2334                let mut sponsored = true;2335                if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {2336                    let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));2337                    let limit_time = last_tx_block + limit.into();2338                    if block_number <= limit_time {2339                        sponsored = false;2340                    }2341                }2342                if sponsored {2343                    <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);2344                }23452346                // check free create limit2347                if (<Collection<T>>::get(collection_id).limits.sponsored_data_size >= (_properties.len() as u32)) &&2348                   (<Collection<T>>::get(collection_id).sponsor_confirmed) &&2349                   (sponsored)2350                {2351                    <Collection<T>>::get(collection_id).sponsor2352                } else {2353                    T::AccountId::default()2354                }2355            }2356            Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {2357                2358                let mut sponsor_transfer = false;2359                if <Collection<T>>::get(collection_id).sponsor_confirmed {23602361                    let collection_limits = <Collection<T>>::get(collection_id).limits;2362                    let collection_mode = <Collection<T>>::get(collection_id).mode;2363    2364                    // sponsor timeout2365                    let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2366                    sponsor_transfer = match collection_mode {2367                        CollectionMode::NFT => {2368    2369                            // get correct limit2370                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2371                                collection_limits.sponsor_transfer_timeout2372                            } else {2373                                ChainLimit::get().nft_sponsor_transfer_timeout2374                            };2375    2376                            let mut sponsored = true;2377                            if <NftTransferBasket<T>>::contains_key(collection_id, item_id) {2378                                let last_tx_block = <NftTransferBasket<T>>::get(collection_id, item_id);2379                                let limit_time = last_tx_block + limit.into();2380                                if block_number <= limit_time {2381                                    sponsored = false;2382                                }2383                            }2384                            if sponsored {2385                                <NftTransferBasket<T>>::insert(collection_id, item_id, block_number);2386                            }23872388                            sponsored2389                        }2390                        CollectionMode::Fungible(_) => {2391    2392                            // get correct limit2393                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2394                                collection_limits.sponsor_transfer_timeout2395                            } else {2396                                ChainLimit::get().fungible_sponsor_transfer_timeout2397                            };2398    2399                            let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2400                            let mut sponsored = true;2401                            if <FungibleTransferBasket<T>>::contains_key(collection_id, who) {2402                                let last_tx_block = <FungibleTransferBasket<T>>::get(collection_id, who);2403                                let limit_time = last_tx_block + limit.into();2404                                if block_number <= limit_time {2405                                    sponsored = false;2406                                }2407                            }2408                            if sponsored {2409                                <FungibleTransferBasket<T>>::insert(collection_id, who, block_number);2410                            }24112412                            sponsored2413                        }2414                        CollectionMode::ReFungible(_) => {2415    2416                            // get correct limit2417                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2418                                collection_limits.sponsor_transfer_timeout2419                            } else {2420                                ChainLimit::get().refungible_sponsor_transfer_timeout2421                            };2422    2423                            let mut sponsored = true;2424                            if <ReFungibleTransferBasket<T>>::contains_key(collection_id, item_id) {2425                                let last_tx_block = <ReFungibleTransferBasket<T>>::get(collection_id, item_id);2426                                let limit_time = last_tx_block + limit.into();2427                                if block_number <= limit_time {2428                                    sponsored = false;2429                                }2430                            }2431                            if sponsored {2432                                <ReFungibleTransferBasket<T>>::insert(collection_id, item_id, block_number);2433                            }24342435                            sponsored2436                        }2437                        _ => {2438                            false2439                        },2440                    };2441                }24422443                if !sponsor_transfer {2444                    T::AccountId::default()2445                } else {2446                    <Collection<T>>::get(collection_id).sponsor2447                }2448            }24492450            _ => T::AccountId::default(),2451        };24522453        // Sponsor smart contracts2454        sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {24552456            // On instantiation: set the contract owner2457            Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, data)) => {24582459                let new_contract_address = <T as pallet_contracts::Trait>::DetermineContractAddress::contract_address_for(2460                    code_hash,2461                    &data,2462                    &who,2463                );2464                <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());24652466                T::AccountId::default()2467            },24682469            // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2470            Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {24712472                let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());24732474                let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())2475                  && <ContractOwner<T>>::get(called_contract.clone()) == *who;2476                let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());2477                  2478                if !owned_contract && white_list_enabled {2479                    if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {2480                        return Err(InvalidTransaction::Call.into());2481                    }2482                }24832484                let mut sponsor_transfer = false;2485                if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {2486                    let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));2487                    let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2488                    let rate_limit = <ContractSponsoringRateLimit<T>>::get(&called_contract);2489                    let limit_time = last_tx_block + rate_limit;24902491                    if block_number >= limit_time {2492                        <ContractSponsorBasket<T>>::insert((called_contract.clone(), who.clone()), block_number);2493                        sponsor_transfer = true;2494                    }2495                } else {2496                    sponsor_transfer = false;2497                }2498               2499                2500                let mut sp = T::AccountId::default();2501                if sponsor_transfer {2502                    if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2503                        if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2504                            sp = called_contract;2505                        }2506                    }2507                }25082509                sp2510            },25112512            _ => sponsor,2513        };25142515        let mut who_pays_fee: T::AccountId = sponsor.clone();2516        if sponsor == T::AccountId::default() {2517            who_pays_fee = who.clone();2518        }25192520        match <T as transaction_payment::Trait>::Currency::withdraw(2521            &who_pays_fee,2522            fee,2523            if tip.is_zero() {2524                WithdrawReason::TransactionPayment.into()2525            } else {2526                WithdrawReason::TransactionPayment | WithdrawReason::Tip2527            },2528            ExistenceRequirement::KeepAlive,2529        ) {2530            Ok(imbalance) => Ok((fee, Some(imbalance))),2531            Err(_) => Err(InvalidTransaction::Payment.into()),2532        }2533    }2534}253525362537impl<T: Trait + Send + Sync> SignedExtension2538    for ChargeTransactionPayment<T>2539where2540    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,2541    T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,2542{2543    const IDENTIFIER: &'static str = "ChargeTransactionPayment";2544    type AccountId = T::AccountId;2545    type Call = T::Call;2546    type AdditionalSigned = ();2547    type Pre = (2548        BalanceOf<T>,2549        Self::AccountId,2550        Option<NegativeImbalanceOf<T>>,2551        BalanceOf<T>,2552    );2553    fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {2554        Ok(())2555    }25562557    fn validate(2558        &self,2559        who: &Self::AccountId,2560        call: &Self::Call,2561        info: &DispatchInfoOf<Self::Call>,2562        len: usize,2563    ) -> TransactionValidity {2564		let (fee, _) = self.withdraw_fee(who, call, info, len)?;2565		Ok(ValidTransaction {2566			priority: Self::get_priority(len, info, fee),2567			..Default::default()2568		})2569    }25702571    fn pre_dispatch(2572        self,2573        who: &Self::AccountId,2574        call: &Self::Call,2575        info: &DispatchInfoOf<Self::Call>,2576        len: usize,2577    ) -> Result<Self::Pre, TransactionValidityError> {2578        let (fee, imbalance) = self.withdraw_fee(who, call, info, len)?;2579        Ok((self.0, who.clone(), imbalance, fee))2580    }25812582    fn post_dispatch(2583        pre: Self::Pre,2584        info: &DispatchInfoOf<Self::Call>,2585        post_info: &PostDispatchInfoOf<Self::Call>,2586        len: usize,2587        _result: &DispatchResult,2588    ) -> Result<(), TransactionValidityError> {2589        let (tip, who, imbalance, fee) = pre;2590        if let Some(payed) = imbalance {2591            let actual_fee = <transaction_payment::Module<T>>::compute_actual_fee(2592                len as u32, info, post_info, tip,2593            );2594            let refund = fee.saturating_sub(actual_fee);2595            let actual_payment =2596                match <T as transaction_payment::Trait>::Currency::deposit_into_existing(2597                    &who, refund,2598                ) {2599                    Ok(refund_imbalance) => {2600                        // The refund cannot be larger than the up front payed max weight.2601                        // `PostDispatchInfo::calc_unspent` guards against such a case.2602                        match payed.offset(refund_imbalance) {2603                            Ok(actual_payment) => actual_payment,2604                            Err(_) => return Err(InvalidTransaction::Payment.into()),2605                        }2606                    }2607                    // We do not recreate the account using the refund. The up front payment2608                    // is gone in that case.2609                    Err(_) => payed,2610                };2611            let imbalances = actual_payment.split(tip);2612            <T as transaction_payment::Trait>::OnTransactionPayment::on_unbalanceds(2613                Some(imbalances.0).into_iter().chain(Some(imbalances.1)),2614            );2615        }2616        Ok(())2617    }2618}26192620// #endregion
after · 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_SPONSOR_TIMEOUT: u32 = 10_368_000;58pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;5960// Structs61// #region6263pub type CollectionId = u32;64pub type TokenId = u32;65pub type DecimalPoints = u8;6667#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]68#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]69pub enum CollectionMode {70    Invalid,71    NFT,72    // decimal points73    Fungible(DecimalPoints),74    // decimal points75    ReFungible(DecimalPoints),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}189190impl Default for CollectionLimits {191    fn default() -> CollectionLimits {192        CollectionLimits { 193            account_token_ownership_limit: 10_000_000, 194            token_limit: u32::max_value(),195            sponsored_data_size: u32::max_value(), 196            sponsor_transfer_timeout: 14400 }197    }198}199200#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]201#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]202pub struct ChainLimits {203    pub collection_numbers_limit: u32,204    pub account_token_ownership_limit: u32,205    pub collections_admins_limit: u64,206    pub custom_data_limit: u32,207208    // Timeouts for item types in passed blocks209    pub nft_sponsor_transfer_timeout: u32,210    pub fungible_sponsor_transfer_timeout: u32,211    pub refungible_sponsor_transfer_timeout: u32,212213    // Schema limits214    pub offchain_schema_limit: u32,215    pub variable_on_chain_schema_limit: u32,216    pub const_on_chain_schema_limit: u32,217}218219pub trait WeightInfo {220	fn create_collection() -> Weight;221	fn destroy_collection() -> Weight;222	fn add_to_white_list() -> Weight;223	fn remove_from_white_list() -> Weight;224    fn set_public_access_mode() -> Weight;225    fn set_mint_permission() -> Weight;226    fn change_collection_owner() -> Weight;227    fn add_collection_admin() -> Weight;228    fn remove_collection_admin() -> Weight;229    fn set_collection_sponsor() -> Weight;230    fn confirm_sponsorship() -> Weight;231    fn remove_collection_sponsor() -> Weight;232    fn create_item(s: usize) -> Weight;233    fn burn_item() -> Weight;234    fn transfer() -> Weight;235    fn approve() -> Weight;236    fn transfer_from() -> Weight;237    fn set_offchain_schema() -> Weight;238    fn set_const_on_chain_schema() -> Weight;239    fn set_variable_on_chain_schema() -> Weight;240    fn set_variable_meta_data() -> Weight;241    fn enable_contract_sponsoring() -> Weight;242    fn set_schema_version() -> Weight;243    fn set_chain_limits() -> Weight;244    fn set_contract_sponsoring_rate_limit() -> Weight;245    fn toggle_contract_white_list() -> Weight;246    fn add_to_contract_white_list() -> Weight;247    fn remove_from_contract_white_list() -> Weight;248    fn set_collection_limits() -> Weight;249}250251#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]252#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]253pub struct CreateNftData {254    pub const_data: Vec<u8>,255    pub variable_data: Vec<u8>,256}257258#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]259#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]260pub struct CreateFungibleData {261    pub value: u128,262}263264#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]265#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]266pub struct CreateReFungibleData {267    pub const_data: Vec<u8>,268    pub variable_data: Vec<u8>,269}270271#[derive(Encode, Decode, Debug, Clone, PartialEq)]272#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]273pub enum CreateItemData {274    NFT(CreateNftData),275    Fungible(CreateFungibleData),276    ReFungible(CreateReFungibleData),277}278279impl CreateItemData {280    pub fn len(&self) -> usize {281        let len = match self {282            CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),283            CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),284            _ => 0285        };286        287        return len;288    }289}290291impl From<CreateNftData> for CreateItemData {292    fn from(item: CreateNftData) -> Self {293        CreateItemData::NFT(item)294    }295}296297impl From<CreateReFungibleData> for CreateItemData {298    fn from(item: CreateReFungibleData) -> Self {299        CreateItemData::ReFungible(item)300    }301}302303impl From<CreateFungibleData> for CreateItemData {304    fn from(item: CreateFungibleData) -> Self {305        CreateItemData::Fungible(item)306    }307}308309310decl_error! {311	/// Error for non-fungible-token module.312	pub enum Error for Module<T: Config> {313        /// Total collections bound exceeded.314        TotalCollectionsLimitExceeded,315		/// Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.316        CollectionDecimalPointLimitExceeded, 317        /// Collection name can not be longer than 63 char.318        CollectionNameLimitExceeded, 319        /// Collection description can not be longer than 255 char.320        CollectionDescriptionLimitExceeded, 321        /// Token prefix can not be longer than 15 char.322        CollectionTokenPrefixLimitExceeded,323        /// This collection does not exist.324        CollectionNotFound,325        /// Item not exists.326        TokenNotFound,327        /// Admin not found328        AdminNotFound,329        /// Arithmetic calculation overflow.330        NumOverflow,       331        /// Account already has admin role.332        AlreadyAdmin,  333        /// You do not own this collection.334        NoPermission,335        /// This address is not set as sponsor, use setCollectionSponsor first.336        ConfirmUnsetSponsorFail,337        /// Collection is not in mint mode.338        PublicMintingNotAllowed,339        /// Sender parameter and item owner must be equal.340        MustBeTokenOwner,341        /// Item balance not enough.342        TokenValueTooLow,343        /// Size of item is too large.344        NftSizeLimitExceeded,345        /// No approve found346        ApproveNotFound,347        /// Requested value more than approved.348        TokenValueNotEnough,349        /// Only approved addresses can call this method.350        ApproveRequired,351        /// Address is not in white list.352        AddresNotInWhiteList,353        /// Number of collection admins bound exceeded.354        CollectionAdminsLimitExceeded,355        /// Owned tokens by a single address bound exceeded.356        AddressOwnershipLimitExceeded,357        /// Length of items properties must be greater than 0.358        EmptyArgument,359        /// const_data exceeded data limit.360        TokenConstDataLimitExceeded,361        /// variable_data exceeded data limit.362        TokenVariableDataLimitExceeded,363        /// Not NFT item data used to mint in NFT collection.364        NotNftDataUsedToMintNftCollectionToken,365        /// Not Fungible item data used to mint in Fungible collection.366        NotFungibleDataUsedToMintFungibleCollectionToken,367        /// Not Re Fungible item data used to mint in Re Fungible collection.368        NotReFungibleDataUsedToMintReFungibleCollectionToken,369        /// Unexpected collection type.370        UnexpectedCollectionType,371        /// Can't store metadata in fungible tokens.372        CantStoreMetadataInFungibleTokens,373        /// Collection token limit exceeded374        CollectionTokenLimitExceeded,375        /// Account token limit exceeded per collection376        AccountTokenLimitExceeded,377        /// Collection limit bounds per collection exceeded378        CollectionLimitBoundsExceeded,379        /// Schema data size limit bound exceeded380        SchemaDataLimitExceeded381	}382}383384pub trait Config: system::Config + Sized + transaction_payment::Config + pallet_contracts::Config {385    type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;386387    /// Weight information for extrinsics in this pallet.388	type WeightInfo: WeightInfo;389}390391#[cfg(feature = "runtime-benchmarks")]392mod benchmarking;393394// #endregion395396decl_storage! {397    trait Store for Module<T: Config> as Nft {398399        // Private members400        NextCollectionID: CollectionId;401        CreatedCollectionCount: u32;402        ChainVersion: u64;403        ItemListIndex: map hasher(identity) CollectionId => TokenId;404405        // Chain limits struct406        pub ChainLimit get(fn chain_limit) config(): ChainLimits;407408        // Bound counters409        CollectionCount: u32;410        pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;411412        // Basic collections413        pub Collection get(fn collection) config(): map hasher(identity) CollectionId => CollectionType<T::AccountId>;414        pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;415        pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;416417        /// Balance owner per collection map418        pub Balance get(fn balance_count): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => u128;419420        /// second parameter: item id + owner account id + spender account id421        pub Allowances get(fn approved): double_map hasher(identity) CollectionId, hasher(twox_64_concat) (TokenId, T::AccountId, T::AccountId) => u128;422423        /// Item collections424        pub NftItemList get(fn nft_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => NftItemType<T::AccountId>;425        pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => FungibleItemType;426        pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => ReFungibleItemType<T::AccountId>;427428        /// Index list429        pub AddressTokens get(fn address_tokens): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => Vec<TokenId>;430431        /// Tokens transfer baskets432        pub CreateItemBasket get(fn create_item_basket): map hasher(twox_64_concat) (CollectionId, T::AccountId) => T::BlockNumber;433        pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;434        pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;435        pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;436437        // Contract Sponsorship and Ownership438        pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;439        pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;440        pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;441        pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;442        pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 443        pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId => bool; 444    }445    add_extra_genesis {446        build(|config: &GenesisConfig<T>| {447            // Modification of storage448            for (_num, _c) in &config.collection {449                <Module<T>>::init_collection(_c);450            }451452            for (_num, _c, _i) in &config.nft_item_id {453                <Module<T>>::init_nft_token(*_c, _i);454            }455456            for (collection_id, account_id, fungible_item) in &config.fungible_item_id {457                <Module<T>>::init_fungible_token(*collection_id, account_id, fungible_item);458            }459460            for (_num, _c, _i) in &config.refungible_item_id {461                <Module<T>>::init_refungible_token(*_c, _i);462            }463        })464    }465}466467decl_event!(468    pub enum Event<T>469    where470        AccountId = <T as system::Config>::AccountId,471    {472        /// New collection was created473        /// 474        /// # Arguments475        /// 476        /// * collection_id: Globally unique identifier of newly created collection.477        /// 478        /// * mode: [CollectionMode] converted into u8.479        /// 480        /// * account_id: Collection owner.481        Created(CollectionId, u8, AccountId),482483        /// New item was created.484        /// 485        /// # Arguments486        /// 487        /// * collection_id: Id of the collection where item was created.488        /// 489        /// * item_id: Id of an item. Unique within the collection.490        ItemCreated(CollectionId, TokenId),491492        /// Collection item was burned.493        /// 494        /// # Arguments495        /// 496        /// collection_id.497        /// 498        /// item_id: Identifier of burned NFT.499        ItemDestroyed(CollectionId, TokenId),500    }501);502503decl_module! {504    pub struct Module<T: Config> for enum Call 505    where 506        origin: T::Origin507    {508        fn deposit_event() = default;509        type Error = Error<T>;510511        fn on_initialize(now: T::BlockNumber) -> Weight {512513            if ChainVersion::get() < 2514            {515                let value = NextCollectionID::get();516                CreatedCollectionCount::put(value);517                ChainVersion::put(2);518            }519520            0521        }522523        /// 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.524        /// 525        /// # Permissions526        /// 527        /// * Anyone.528        /// 529        /// # Arguments530        /// 531        /// * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.532        /// 533        /// * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.534        /// 535        /// * token_prefix: UTF-8 string with token prefix.536        /// 537        /// * mode: [CollectionMode] collection type and type dependent data.538        // returns collection ID539        #[weight = <T as Config>::WeightInfo::create_collection()]540        pub fn create_collection(origin,541                                 collection_name: Vec<u16>,542                                 collection_description: Vec<u16>,543                                 token_prefix: Vec<u8>,544                                 mode: CollectionMode) -> DispatchResult {545546            // Anyone can create a collection547            let who = ensure_signed(origin)?;548549            let decimal_points = match mode {550                CollectionMode::Fungible(points) => points,551                CollectionMode::ReFungible(points) => points,552                _ => 0553            };554555            // bound Total number of collections556            ensure!(CollectionCount::get() < ChainLimit::get().collection_numbers_limit, Error::<T>::TotalCollectionsLimitExceeded);557558            // check params559            ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);560            ensure!(collection_name.len() <= 64, Error::<T>::CollectionNameLimitExceeded);561            ensure!(collection_description.len() <= 256, Error::<T>::CollectionDescriptionLimitExceeded);562            ensure!(token_prefix.len() <= 16, Error::<T>::CollectionTokenPrefixLimitExceeded);563564            // Generate next collection ID565            let next_id = CreatedCollectionCount::get()566                .checked_add(1)567                .ok_or(Error::<T>::NumOverflow)?;568569            // bound counter570            let total = CollectionCount::get()571                .checked_add(1)572                .ok_or(Error::<T>::NumOverflow)?;573574            CreatedCollectionCount::put(next_id);575            CollectionCount::put(total);576577            // Create new collection578            let new_collection = CollectionType {579                owner: who.clone(),580                name: collection_name,581                mode: mode.clone(),582                mint_mode: false,583                access: AccessMode::Normal,584                description: collection_description,585                decimal_points: decimal_points,586                token_prefix: token_prefix,587                offchain_schema: Vec::new(),588                schema_version: SchemaVersion::ImageURL,589                sponsor: T::AccountId::default(),590                sponsor_confirmed: false,591                variable_on_chain_schema: Vec::new(),592                const_on_chain_schema: Vec::new(),593                limits: CollectionLimits::default(),594            };595596            // Add new collection to map597            <Collection<T>>::insert(next_id, new_collection);598599            // call event600            Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));601602            Ok(())603        }604605        /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.606        /// 607        /// # Permissions608        /// 609        /// * Collection Owner.610        /// 611        /// # Arguments612        /// 613        /// * collection_id: collection to destroy.614        #[weight = <T as Config>::WeightInfo::destroy_collection()]615        pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {616617            let sender = ensure_signed(origin)?;618            Self::check_owner_permissions(collection_id, sender)?;619620            <AddressTokens<T>>::remove_prefix(collection_id);621            <Allowances<T>>::remove_prefix(collection_id);622            <Balance<T>>::remove_prefix(collection_id);623            <ItemListIndex>::remove(collection_id);624            <AdminList<T>>::remove(collection_id);625            <Collection<T>>::remove(collection_id);626            <WhiteList<T>>::remove_prefix(collection_id);627628            <NftItemList<T>>::remove_prefix(collection_id);629            <FungibleItemList<T>>::remove_prefix(collection_id);630            <ReFungibleItemList<T>>::remove_prefix(collection_id);631632            <NftTransferBasket<T>>::remove_prefix(collection_id);633            <FungibleTransferBasket<T>>::remove_prefix(collection_id);634            <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);635636            if CollectionCount::get() > 0637            {638                // bound couter639                let total = CollectionCount::get()640                    .checked_sub(1)641                    .ok_or(Error::<T>::NumOverflow)?;642643                CollectionCount::put(total);644            }645646            Ok(())647        }648649        /// Add an address to white list.650        /// 651        /// # Permissions652        /// 653        /// * Collection Owner654        /// * Collection Admin655        /// 656        /// # Arguments657        /// 658        /// * collection_id.659        /// 660        /// * address.661        #[weight = <T as Config>::WeightInfo::add_to_white_list()]662        pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{663664            let sender = ensure_signed(origin)?;665            Self::check_owner_or_admin_permissions(collection_id, sender)?;666667            <WhiteList<T>>::insert(collection_id, address, true);668            669            Ok(())670        }671672        /// Remove an address from white list.673        /// 674        /// # Permissions675        /// 676        /// * Collection Owner677        /// * Collection Admin678        /// 679        /// # Arguments680        /// 681        /// * collection_id.682        /// 683        /// * address.684        #[weight = <T as Config>::WeightInfo::remove_from_white_list()]685        pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{686687            let sender = ensure_signed(origin)?;688            Self::check_owner_or_admin_permissions(collection_id, sender)?;689690            <WhiteList<T>>::remove(collection_id, address);691692            Ok(())693        }694695        /// Toggle between normal and white list access for the methods with access for `Anyone`.696        /// 697        /// # Permissions698        /// 699        /// * Collection Owner.700        /// 701        /// # Arguments702        /// 703        /// * collection_id.704        /// 705        /// * mode: [AccessMode]706        #[weight = <T as Config>::WeightInfo::set_public_access_mode()]707        pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult708        {709            let sender = ensure_signed(origin)?;710711            Self::check_owner_permissions(collection_id, sender)?;712            let mut target_collection = <Collection<T>>::get(collection_id);713            target_collection.access = mode;714            <Collection<T>>::insert(collection_id, target_collection);715716            Ok(())717        }718719        /// Allows Anyone to create tokens if:720        /// * White List is enabled, and721        /// * Address is added to white list, and722        /// * This method was called with True parameter723        /// 724        /// # Permissions725        /// * Collection Owner726        ///727        /// # Arguments728        /// 729        /// * collection_id.730        /// 731        /// * mint_permission: Boolean parameter. If True, allows minting to Anyone with conditions above.732        #[weight = <T as Config>::WeightInfo::set_mint_permission()]733        pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult734        {735            let sender = ensure_signed(origin)?;736737            Self::check_owner_permissions(collection_id, sender)?;738            let mut target_collection = <Collection<T>>::get(collection_id);739            target_collection.mint_mode = mint_permission;740            <Collection<T>>::insert(collection_id, target_collection);741742            Ok(())743        }744745        /// Change the owner of the collection.746        /// 747        /// # Permissions748        /// 749        /// * Collection Owner.750        /// 751        /// # Arguments752        /// 753        /// * collection_id.754        /// 755        /// * new_owner.756        #[weight = <T as Config>::WeightInfo::change_collection_owner()]757        pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {758759            let sender = ensure_signed(origin)?;760            Self::check_owner_permissions(collection_id, sender)?;761            let mut target_collection = <Collection<T>>::get(collection_id);762            target_collection.owner = new_owner;763            <Collection<T>>::insert(collection_id, target_collection);764765            Ok(())766        }767768        /// Adds an admin of the Collection.769        /// 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. 770        /// 771        /// # Permissions772        /// 773        /// * Collection Owner.774        /// * Collection Admin.775        /// 776        /// # Arguments777        /// 778        /// * collection_id: ID of the Collection to add admin for.779        /// 780        /// * new_admin_id: Address of new admin to add.781        #[weight = <T as Config>::WeightInfo::add_collection_admin()]782        pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::AccountId) -> DispatchResult {783784            let sender = ensure_signed(origin)?;785            Self::check_owner_or_admin_permissions(collection_id, sender)?;786            let mut admin_arr: Vec<T::AccountId> = Vec::new();787788            if <AdminList<T>>::contains_key(collection_id)789            {790                admin_arr = <AdminList<T>>::get(collection_id);791                ensure!(!admin_arr.contains(&new_admin_id), Error::<T>::AlreadyAdmin);792            }793794            // Number of collection admins795            ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, Error::<T>::CollectionAdminsLimitExceeded);796797            admin_arr.push(new_admin_id);798            <AdminList<T>>::insert(collection_id, admin_arr);799800            Ok(())801        }802803        /// 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.804        ///805        /// # Permissions806        /// 807        /// * Collection Owner.808        /// * Collection Admin.809        /// 810        /// # Arguments811        /// 812        /// * collection_id: ID of the Collection to remove admin for.813        /// 814        /// * account_id: Address of admin to remove.815        #[weight = <T as Config>::WeightInfo::remove_collection_admin()]816        pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::AccountId) -> DispatchResult {817818            let sender = ensure_signed(origin)?;819            Self::check_owner_or_admin_permissions(collection_id, sender)?;820            ensure!(<AdminList<T>>::contains_key(collection_id), Error::<T>::AdminNotFound);821822            let mut admin_arr = <AdminList<T>>::get(collection_id);823            admin_arr.retain(|i| *i != account_id);824            <AdminList<T>>::insert(collection_id, admin_arr);825826            Ok(())827        }828829        /// # Permissions830        /// 831        /// * Collection Owner832        /// 833        /// # Arguments834        /// 835        /// * collection_id.836        /// 837        /// * new_sponsor.838        #[weight = <T as Config>::WeightInfo::set_collection_sponsor()]839        pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {840841            let sender = ensure_signed(origin)?;842            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);843844            let mut target_collection = <Collection<T>>::get(collection_id);845            ensure!(sender == target_collection.owner, Error::<T>::NoPermission);846847            target_collection.sponsor = new_sponsor;848            target_collection.sponsor_confirmed = false;849            <Collection<T>>::insert(collection_id, target_collection);850851            Ok(())852        }853854        /// # Permissions855        /// 856        /// * Sponsor.857        /// 858        /// # Arguments859        /// 860        /// * collection_id.861        #[weight = <T as Config>::WeightInfo::confirm_sponsorship()]862        pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {863864            let sender = ensure_signed(origin)?;865            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);866867            let mut target_collection = <Collection<T>>::get(collection_id);868            ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);869870            target_collection.sponsor_confirmed = true;871            <Collection<T>>::insert(collection_id, target_collection);872873            Ok(())874        }875876        /// Switch back to pay-per-own-transaction model.877        ///878        /// # Permissions879        ///880        /// * Collection owner.881        /// 882        /// # Arguments883        /// 884        /// * collection_id.885        #[weight = <T as Config>::WeightInfo::remove_collection_sponsor()]886        pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {887888            let sender = ensure_signed(origin)?;889            ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);890891            let mut target_collection = <Collection<T>>::get(collection_id);892            ensure!(sender == target_collection.owner, Error::<T>::NoPermission);893894            target_collection.sponsor = T::AccountId::default();895            target_collection.sponsor_confirmed = false;896            <Collection<T>>::insert(collection_id, target_collection);897898            Ok(())899        }900901        /// This method creates a concrete instance of NFT Collection created with CreateCollection method.902        /// 903        /// # Permissions904        /// 905        /// * Collection Owner.906        /// * Collection Admin.907        /// * Anyone if908        ///     * White List is enabled, and909        ///     * Address is added to white list, and910        ///     * MintPermission is enabled (see SetMintPermission method)911        /// 912        /// # Arguments913        /// 914        /// * collection_id: ID of the collection.915        /// 916        /// * owner: Address, initial owner of the NFT.917        ///918        /// * data: Token data to store on chain.919        // #[weight =920        // (130_000_000 as Weight)921        // .saturating_add((2135 as Weight).saturating_mul((properties.len() as u64) as Weight))922        // .saturating_add(RocksDbWeight::get().reads(10 as Weight))923        // .saturating_add(RocksDbWeight::get().writes(8 as Weight))]924925        #[weight = <T as Config>::WeightInfo::create_item(data.len())]926        pub fn create_item(origin, collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {927928            let sender = ensure_signed(origin)?;929930            Self::collection_exists(collection_id)?;931932            let target_collection = <Collection<T>>::get(collection_id);933934            Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;935            Self::validate_create_item_args(&target_collection, &data)?;936            Self::create_item_no_validation(collection_id, &target_collection, owner, data)?;937938            Ok(())939        }940941        /// This method creates multiple instances of NFT Collection created with CreateCollection method.942        /// 943        /// # Permissions944        /// 945        /// * Collection Owner.946        /// * Collection Admin.947        /// * Anyone if948        ///     * White List is enabled, and949        ///     * Address is added to white list, and950        ///     * MintPermission is enabled (see SetMintPermission method)951        /// 952        /// # Arguments953        /// 954        /// * collection_id: ID of the collection.955        /// 956        /// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].957        /// 958        /// * owner: Address, initial owner of the NFT.959        #[weight = <T as Config>::WeightInfo::create_item(items_data.into_iter()960                               .map(|data| { data.len() })961                               .sum())]962        pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::AccountId, items_data: Vec<CreateItemData>) -> DispatchResult {963964            ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);965            let sender = ensure_signed(origin)?;966967            Self::collection_exists(collection_id)?;968            let target_collection = <Collection<T>>::get(collection_id);969970            Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;971972            for data in &items_data {973                Self::validate_create_item_args(&target_collection, data)?;974            }975            for data in &items_data {976                Self::create_item_no_validation(collection_id, &target_collection, owner.clone(), data.clone())?;977            }978979            Ok(())980        }981982        /// Destroys a concrete instance of NFT.983        /// 984        /// # Permissions985        /// 986        /// * Collection Owner.987        /// * Collection Admin.988        /// * Current NFT Owner.989        /// 990        /// # Arguments991        /// 992        /// * collection_id: ID of the collection.993        /// 994        /// * item_id: ID of NFT to burn.995        #[weight = <T as Config>::WeightInfo::burn_item()]996        pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {997998            let sender = ensure_signed(origin)?;999            Self::collection_exists(collection_id)?;10001001            // Transfer permissions check1002            let target_collection = <Collection<T>>::get(collection_id);1003            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1004                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1005                Error::<T>::NoPermission);10061007            if target_collection.access == AccessMode::WhiteList {1008                Self::check_white_list(collection_id, &sender)?;1009            }10101011            match target_collection.mode1012            {1013                CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,1014                CollectionMode::Fungible(_)  => Self::burn_fungible_item(&sender, collection_id, value)?,1015                CollectionMode::ReFungible(_)  => Self::burn_refungible_item(collection_id, item_id, &sender)?,1016                _ => ()1017            };10181019            // call event1020            Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));10211022            Ok(())1023        }10241025        /// Change ownership of the token.1026        /// 1027        /// # Permissions1028        /// 1029        /// * Collection Owner1030        /// * Collection Admin1031        /// * Current NFT owner1032        ///1033        /// # Arguments1034        /// 1035        /// * recipient: Address of token recipient.1036        /// 1037        /// * collection_id.1038        /// 1039        /// * item_id: ID of the item1040        ///     * Non-Fungible Mode: Required.1041        ///     * Fungible Mode: Ignored.1042        ///     * Re-Fungible Mode: Required.1043        /// 1044        /// * value: Amount to transfer.1045        ///     * Non-Fungible Mode: Ignored1046        ///     * Fungible Mode: Must specify transferred amount1047        ///     * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)1048        #[weight = <T as Config>::WeightInfo::transfer()]1049        pub fn transfer(origin, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {10501051            let sender = ensure_signed(origin)?;1052            let target_collection = <Collection<T>>::get(collection_id);10531054            // Limits check1055            Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;10561057            // Transfer permissions check1058            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1059                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1060                Error::<T>::NoPermission);10611062            if target_collection.access == AccessMode::WhiteList {1063                Self::check_white_list(collection_id, &sender)?;1064                Self::check_white_list(collection_id, &recipient)?;1065            }10661067            match target_collection.mode1068            {1069                CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,1070                CollectionMode::Fungible(_)  => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,1071                CollectionMode::ReFungible(_)  => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient)?,1072                _ => ()1073            };10741075            Ok(())1076        }10771078        /// Set, change, or remove approved address to transfer the ownership of the NFT.1079        /// 1080        /// # Permissions1081        /// 1082        /// * Collection Owner1083        /// * Collection Admin1084        /// * Current NFT owner1085        /// 1086        /// # Arguments1087        /// 1088        /// * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).1089        /// 1090        /// * collection_id.1091        /// 1092        /// * item_id: ID of the item.1093        #[weight = <T as Config>::WeightInfo::approve()]1094        pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {10951096            let sender = ensure_signed(origin)?;10971098            Self::collection_exists(collection_id)?;1099            Self::token_exists(collection_id, item_id, &sender)?;11001101            // Transfer permissions check1102            let target_collection = <Collection<T>>::get(collection_id);1103            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1104                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1105                Error::<T>::NoPermission);11061107            if target_collection.access == AccessMode::WhiteList {1108                Self::check_white_list(collection_id, &sender)?;1109                Self::check_white_list(collection_id, &spender)?;1110            }11111112            let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));1113            let mut allowance: u128 = amount;1114            if allowance_exists {1115                allowance += <Allowances<T>>::get(collection_id, (item_id, &sender, &spender));1116            }1117            <Allowances<T>>::insert(collection_id, (item_id, sender.clone(), spender.clone()), allowance);11181119            Ok(())1120        }1121        1122        /// 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.1123        /// 1124        /// # Permissions1125        /// * Collection Owner1126        /// * Collection Admin1127        /// * Current NFT owner1128        /// * Address approved by current NFT owner1129        /// 1130        /// # Arguments1131        /// 1132        /// * from: Address that owns token.1133        /// 1134        /// * recipient: Address of token recipient.1135        /// 1136        /// * collection_id.1137        /// 1138        /// * item_id: ID of the item.1139        /// 1140        /// * value: Amount to transfer.1141        #[weight = <T as Config>::WeightInfo::transfer_from()]1142        pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {11431144            let sender = ensure_signed(origin)?;1145            let mut appoved_transfer = false;11461147            // Check approval1148            let mut approval: u128 = 0;1149            if <Allowances<T>>::contains_key(collection_id, (item_id, &from, &recipient)) {1150                approval = <Allowances<T>>::get(collection_id, (item_id, &from, &recipient));1151                ensure!(approval >= value, Error::<T>::TokenValueNotEnough);1152                appoved_transfer = true;1153            }11541155            let target_collection = <Collection<T>>::get(collection_id);11561157            // Limits check1158            Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;11591160            // Transfer permissions check         1161            ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1162                Error::<T>::NoPermission);11631164            if target_collection.access == AccessMode::WhiteList {1165                Self::check_white_list(collection_id, &sender)?;1166                Self::check_white_list(collection_id, &recipient)?;1167            }11681169            // Reduce approval by transferred amount or remove if remaining approval drops to 01170            if approval.checked_sub(value).unwrap_or(0) > 0 {1171                <Allowances<T>>::insert(collection_id, (item_id, &from, &recipient), approval - value);1172            }1173            else {1174                <Allowances<T>>::remove(collection_id, (item_id, &from, &recipient));1175            }11761177            match target_collection.mode1178            {1179                CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,1180                CollectionMode::Fungible(_)  => Self::transfer_fungible(collection_id, value, &from, &recipient)?,1181                CollectionMode::ReFungible(_)  => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,1182                _ => ()1183            };11841185            Ok(())1186        }11871188        // #[weight = 0]1189        // pub fn safe_transfer_from(origin, collection_id: CollectionId, item_id: TokenId, new_owner: T::AccountId) -> DispatchResult {11901191        //     // let no_perm_mes = "You do not have permissions to modify this collection";1192        //     // ensure!(<ApprovedList<T>>::contains_key((collection_id, item_id)), no_perm_mes);1193        //     // let list_itm = <ApprovedList<T>>::get((collection_id, item_id));1194        //     // ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes);11951196        //     // // on_nft_received  call11971198        //     // Self::transfer(origin, collection_id, item_id, new_owner)?;11991200        //     Ok(())1201        // }12021203        /// Set off-chain data schema.1204        /// 1205        /// # Permissions1206        /// 1207        /// * Collection Owner1208        /// * Collection Admin1209        /// 1210        /// # Arguments1211        /// 1212        /// * collection_id.1213        /// 1214        /// * schema: String representing the offchain data schema.1215        #[weight = <T as Config>::WeightInfo::set_variable_meta_data()]1216        pub fn set_variable_meta_data (1217            origin,1218            collection_id: CollectionId,1219            item_id: TokenId,1220            data: Vec<u8>1221        ) -> DispatchResult {1222            let sender = ensure_signed(origin)?;1223            1224            Self::collection_exists(collection_id)?;1225            Self::token_exists(collection_id, item_id, &sender)?;12261227            ensure!(ChainLimit::get().custom_data_limit >= data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);12281229            // Modify permissions check1230            let target_collection = <Collection<T>>::get(collection_id);1231            ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1232                Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1233                Error::<T>::NoPermission);12341235            match target_collection.mode1236            {1237                CollectionMode::NFT => Self::set_nft_variable_data(collection_id, item_id, data)?,1238                CollectionMode::ReFungible(_)  => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,1239                CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),1240                _ => fail!(Error::<T>::UnexpectedCollectionType)1241            };12421243            Ok(())1244        }1245 1246        /// Set schema standard1247        /// ImageURL1248        /// Unique1249        /// 1250        /// # Permissions1251        /// 1252        /// * Collection Owner1253        /// * Collection Admin1254        /// 1255        /// # Arguments1256        /// 1257        /// * collection_id.1258        /// 1259        /// * schema: SchemaVersion: enum1260        #[weight = <T as Config>::WeightInfo::set_schema_version()]1261        pub fn set_schema_version(1262            origin,1263            collection_id: CollectionId,1264            version: SchemaVersion1265        ) -> DispatchResult {1266            let sender = ensure_signed(origin)?;1267            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1268            let mut target_collection = <Collection<T>>::get(collection_id);1269            target_collection.schema_version = version;1270            <Collection<T>>::insert(collection_id, target_collection);12711272            Ok(())1273        }12741275        /// Set off-chain data schema.1276        /// 1277        /// # Permissions1278        /// 1279        /// * Collection Owner1280        /// * Collection Admin1281        /// 1282        /// # Arguments1283        /// 1284        /// * collection_id.1285        /// 1286        /// * schema: String representing the offchain data schema.1287        #[weight = <T as Config>::WeightInfo::set_offchain_schema()]1288        pub fn set_offchain_schema(1289            origin,1290            collection_id: CollectionId,1291            schema: Vec<u8>1292        ) -> DispatchResult {1293            let sender = ensure_signed(origin)?;1294            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;12951296            // check schema limit1297            ensure!(schema.len() as u32 > ChainLimit::get().offchain_schema_limit, "");12981299            let mut target_collection = <Collection<T>>::get(collection_id);1300            target_collection.offchain_schema = schema;1301            <Collection<T>>::insert(collection_id, target_collection);13021303            Ok(())1304        }13051306        /// Set const on-chain data schema.1307        /// 1308        /// # Permissions1309        /// 1310        /// * Collection Owner1311        /// * Collection Admin1312        /// 1313        /// # Arguments1314        /// 1315        /// * collection_id.1316        /// 1317        /// * schema: String representing the const on-chain data schema.1318        #[weight = <T as Config>::WeightInfo::set_const_on_chain_schema()]1319        pub fn set_const_on_chain_schema (1320            origin,1321            collection_id: CollectionId,1322            schema: Vec<u8>1323        ) -> DispatchResult {1324            let sender = ensure_signed(origin)?;1325            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13261327            // check schema limit1328            ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");13291330            let mut target_collection = <Collection<T>>::get(collection_id);1331            target_collection.const_on_chain_schema = schema;1332            <Collection<T>>::insert(collection_id, target_collection);13331334            Ok(())1335        }13361337        /// Set variable on-chain data schema.1338        /// 1339        /// # Permissions1340        /// 1341        /// * Collection Owner1342        /// * Collection Admin1343        /// 1344        /// # Arguments1345        /// 1346        /// * collection_id.1347        /// 1348        /// * schema: String representing the variable on-chain data schema.1349        #[weight = <T as Config>::WeightInfo::set_const_on_chain_schema()]1350        pub fn set_variable_on_chain_schema (1351            origin,1352            collection_id: CollectionId,1353            schema: Vec<u8>1354        ) -> DispatchResult {1355            let sender = ensure_signed(origin)?;1356            Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;13571358            // check schema limit1359            ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");13601361            let mut target_collection = <Collection<T>>::get(collection_id);1362            target_collection.variable_on_chain_schema = schema;1363            <Collection<T>>::insert(collection_id, target_collection);13641365            Ok(())1366        }13671368        // Sudo permissions function1369        #[weight = <T as Config>::WeightInfo::set_chain_limits()]1370        pub fn set_chain_limits(1371            origin,1372            limits: ChainLimits1373        ) -> DispatchResult {13741375            #[cfg(not(feature = "runtime-benchmarks"))]1376            ensure_root(origin)?;13771378            <ChainLimit>::put(limits);1379            Ok(())1380        }13811382        /// Enable smart contract self-sponsoring.1383        /// 1384        /// # Permissions1385        /// 1386        /// * Contract Owner1387        /// 1388        /// # Arguments1389        /// 1390        /// * contract address1391        /// * enable flag1392        /// 1393        #[weight = <T as Config>::WeightInfo::enable_contract_sponsoring()]1394        pub fn enable_contract_sponsoring(1395            origin,1396            contract_address: T::AccountId,1397            enable: bool1398        ) -> DispatchResult {13991400            let sender = ensure_signed(origin)?;14011402            #[cfg(feature = "runtime-benchmarks")]1403            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14041405            Self::ensure_contract_owned(sender, &contract_address)?;14061407            <ContractSelfSponsoring<T>>::insert(contract_address, enable);1408            Ok(())1409        }14101411        /// Set the rate limit for contract sponsoring to specified number of blocks.1412        /// 1413        /// If not set (has the default value of 0 blocks), the sponsoring will be disabled. 1414        /// If set to the number B (for blocks), the transactions will be sponsored with a rate 1415        /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid 1416        /// from contract endowment if there are at least B blocks between such transactions. 1417        /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.1418        /// 1419        /// # Permissions1420        /// 1421        /// * Contract Owner1422        /// 1423        /// # Arguments1424        /// 1425        /// -`contract_address`: Address of the contract to sponsor1426        /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed1427        /// 1428        #[weight = <T as Config>::WeightInfo::set_contract_sponsoring_rate_limit()]1429        pub fn set_contract_sponsoring_rate_limit(1430            origin,1431            contract_address: T::AccountId,1432            rate_limit: T::BlockNumber1433        ) -> DispatchResult {1434            let sender = ensure_signed(origin)?;14351436            #[cfg(feature = "runtime-benchmarks")]1437            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14381439            Self::ensure_contract_owned(sender, &contract_address)?;1440            <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);1441            Ok(())1442        }14431444        /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.1445        /// 1446        /// # Permissions1447        /// 1448        /// * Address that deployed smart contract.1449        /// 1450        /// # Arguments1451        /// 1452        /// -`contract_address`: Address of the contract.1453        /// 1454        /// - `enable`: .  1455        #[weight = <T as Config>::WeightInfo::toggle_contract_white_list()]1456        pub fn toggle_contract_white_list(1457            origin,1458            contract_address: T::AccountId,1459            enable: bool1460        ) -> DispatchResult {1461            let sender = ensure_signed(origin)?;14621463            #[cfg(feature = "runtime-benchmarks")]1464            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());14651466            Self::ensure_contract_owned(sender, &contract_address)?;1467            <ContractWhiteListEnabled<T>>::insert(contract_address, enable);1468            Ok(())1469        }1470        1471        /// Add an address to smart contract white list.1472        /// 1473        /// # Permissions1474        /// 1475        /// * Address that deployed smart contract.1476        /// 1477        /// # Arguments1478        /// 1479        /// -`contract_address`: Address of the contract.1480        ///1481        /// -`account_address`: Address to add.1482        #[weight = <T as Config>::WeightInfo::add_to_contract_white_list()]1483        pub fn add_to_contract_white_list(1484            origin,1485            contract_address: T::AccountId,1486            account_address: T::AccountId1487        ) -> DispatchResult {1488            let sender = ensure_signed(origin)?;14891490            #[cfg(feature = "runtime-benchmarks")]1491            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());1492            1493            Self::ensure_contract_owned(sender, &contract_address)?;      1494            <ContractWhiteList<T>>::insert(contract_address, account_address, true);1495            Ok(())1496        }14971498        /// Remove an address from smart contract white list.1499        /// 1500        /// # Permissions1501        /// 1502        /// * Address that deployed smart contract.1503        /// 1504        /// # Arguments1505        /// 1506        /// -`contract_address`: Address of the contract.1507        ///1508        /// -`account_address`: Address to remove.1509        #[weight = <T as Config>::WeightInfo::remove_from_contract_white_list()]1510        pub fn remove_from_contract_white_list(1511            origin,1512            contract_address: T::AccountId,1513            account_address: T::AccountId1514        ) -> DispatchResult {1515            let sender = ensure_signed(origin)?;15161517            #[cfg(feature = "runtime-benchmarks")]1518            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());15191520            Self::ensure_contract_owned(sender, &contract_address)?;1521            <ContractWhiteList<T>>::remove(contract_address, account_address);1522            Ok(())1523        }15241525        #[weight = <T as Config>::WeightInfo::set_collection_limits()]1526        pub fn set_collection_limits(1527            origin,1528            collection_id: u32,1529            limits: CollectionLimits,1530        ) -> DispatchResult {1531            let sender = ensure_signed(origin)?;1532            Self::check_owner_permissions(collection_id, sender.clone())?;1533            let mut target_collection = <Collection<T>>::get(collection_id);1534            let chain_limits = ChainLimit::get();1535            let climits = target_collection.limits;15361537            // collection bounds1538            ensure!(limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&1539                limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP,  1540                Error::<T>::CollectionLimitBoundsExceeded);15411542            // token_limit   check  prev1543            ensure!(climits.token_limit > limits.token_limit && 1544                limits.token_limit <= chain_limits.account_token_ownership_limit, 1545                Error::<T>::AccountTokenLimitExceeded);15461547            target_collection.limits = limits;1548            <Collection<T>>::insert(collection_id, target_collection);15491550            Ok(())1551        } 1552    }1553}15541555impl<T: Config> Module<T> {15561557    fn is_correct_transfer(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, recipient: &T::AccountId) -> DispatchResult {15581559        // check token limit and account token limit1560        let account_items: u32 = <AddressTokens<T>>::get(collection_id, recipient).len() as u32;1561        ensure!(collection.limits.account_token_ownership_limit > account_items,  Error::<T>::AccountTokenLimitExceeded);1562        1563        Ok(())1564    }15651566    fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {15671568        // check token limit and account token limit1569        let total_items: u32 = ItemListIndex::get(collection_id);1570        let account_items: u32 = <AddressTokens<T>>::get(collection_id, owner).len() as u32;1571        ensure!(collection.limits.token_limit > total_items,  Error::<T>::CollectionTokenLimitExceeded);1572        ensure!(collection.limits.account_token_ownership_limit > account_items,  Error::<T>::AccountTokenLimitExceeded);15731574        if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {1575            ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);1576            Self::check_white_list(collection_id, owner)?;1577            Self::check_white_list(collection_id, sender)?;1578        }15791580        Ok(())1581    }15821583    fn validate_create_item_args(target_collection: &CollectionType<T::AccountId>, data: &CreateItemData) -> DispatchResult {1584        match target_collection.mode1585        {1586            CollectionMode::NFT => {1587                if let CreateItemData::NFT(data) = data {1588                    // check sizes1589                    ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);1590                    ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);1591                } else {1592                    fail!(Error::<T>::NotNftDataUsedToMintNftCollectionToken);1593                }1594            },1595            CollectionMode::Fungible(_) => {1596                if let CreateItemData::Fungible(_) = data {1597                } else {1598                    fail!(Error::<T>::NotFungibleDataUsedToMintFungibleCollectionToken);1599                }1600            },1601            CollectionMode::ReFungible(_) => {1602                if let CreateItemData::ReFungible(data) = data {16031604                    // check sizes1605                    ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);1606                    ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);1607                } else {1608                    fail!(Error::<T>::NotReFungibleDataUsedToMintReFungibleCollectionToken);1609                }1610            },1611            _ => { fail!(Error::<T>::UnexpectedCollectionType); }1612        };16131614        Ok(())1615    }16161617    fn create_item_no_validation(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1618        match data1619        {1620            CreateItemData::NFT(data) => {1621                let item = NftItemType {1622                    owner,1623                    const_data: data.const_data,1624                    variable_data: data.variable_data1625                };16261627                Self::add_nft_item(collection_id, item)?;1628            },1629            CreateItemData::Fungible(data) => {1630                Self::add_fungible_item(collection_id, &owner, data.value)?;1631            },1632            CreateItemData::ReFungible(data) => {1633                let mut owner_list = Vec::new();1634                let value = (10 as u128).pow(collection.decimal_points as u32);1635                owner_list.push(Ownership {owner: owner.clone(), fraction: value});16361637                let item = ReFungibleItemType {1638                    owner: owner_list,1639                    const_data: data.const_data,1640                    variable_data: data.variable_data1641                };16421643                Self::add_refungible_item(collection_id, item)?;1644            }1645        };16461647        // call event1648        Self::deposit_event(RawEvent::ItemCreated(collection_id, <ItemListIndex>::get(collection_id)));16491650        Ok(())1651    }16521653    fn add_fungible_item(collection_id: CollectionId, owner: &T::AccountId, value: u128) -> DispatchResult {16541655        // Does new owner already have an account?1656        let mut balance: u128 = 0;1657        if <FungibleItemList<T>>::contains_key(collection_id, owner) {1658            balance = <FungibleItemList<T>>::get(collection_id, owner).value;1659        } 16601661        // Mint 1662        let item = FungibleItemType {1663            value: balance + value1664        };1665        <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), item);16661667        // Update balance1668        let new_balance = <Balance<T>>::get(collection_id, owner)1669            .checked_add(value)1670            .ok_or(Error::<T>::NumOverflow)?;1671        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);16721673        Ok(())1674    }16751676    fn add_refungible_item(collection_id: CollectionId, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {1677        let current_index = <ItemListIndex>::get(collection_id)1678            .checked_add(1)1679            .ok_or(Error::<T>::NumOverflow)?;1680        let itemcopy = item.clone();16811682        let value = item.owner.first().unwrap().fraction;1683        let owner = item.owner.first().unwrap().owner.clone();16841685        Self::add_token_index(collection_id, current_index, &owner)?;16861687        <ItemListIndex>::insert(collection_id, current_index);1688        <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);16891690        // Update balance1691        let new_balance = <Balance<T>>::get(collection_id, &owner)1692            .checked_add(value)1693            .ok_or(Error::<T>::NumOverflow)?;1694        <Balance<T>>::insert(collection_id, owner.clone(), new_balance);16951696        Ok(())1697    }16981699    fn add_nft_item(collection_id: CollectionId, item: NftItemType<T::AccountId>) -> DispatchResult {1700        let current_index = <ItemListIndex>::get(collection_id)1701            .checked_add(1)1702            .ok_or(Error::<T>::NumOverflow)?;17031704        let item_owner = item.owner.clone();1705        Self::add_token_index(collection_id, current_index, &item.owner)?;17061707        <ItemListIndex>::insert(collection_id, current_index);1708        <NftItemList<T>>::insert(collection_id, current_index, item);17091710        // Update balance1711        let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())1712            .checked_add(1)1713            .ok_or(Error::<T>::NumOverflow)?;1714        <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);17151716        Ok(())1717    }17181719    fn burn_refungible_item(1720        collection_id: CollectionId,1721        item_id: TokenId,1722        owner: &T::AccountId,1723    ) -> DispatchResult {1724        ensure!(1725            <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1726            Error::<T>::TokenNotFound1727        );1728        let mut token = <ReFungibleItemList<T>>::get(collection_id, item_id);1729        let rft_balance = token1730            .owner1731            .iter()1732            .filter(|&i| i.owner == *owner)1733            .next()1734            .unwrap();1735        Self::remove_token_index(collection_id, item_id, owner)?;17361737        // update balance1738        let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.clone())1739            .checked_sub(rft_balance.fraction)1740            .ok_or(Error::<T>::NumOverflow)?;1741        <Balance<T>>::insert(collection_id, rft_balance.owner.clone(), new_balance);17421743        // Re-create owners list with sender removed1744        let index = token1745            .owner1746            .iter()1747            .position(|i| i.owner == *owner)1748            .unwrap();1749        token.owner.remove(index);1750        let owner_count = token.owner.len();17511752        // Burn the token completely if this was the last (only) owner1753        if owner_count == 0 {1754            <ReFungibleItemList<T>>::remove(collection_id, item_id);1755        }1756        else {1757            <ReFungibleItemList<T>>::insert(collection_id, item_id, token);1758        }17591760        Ok(())1761    }17621763    fn burn_nft_item(collection_id: CollectionId, item_id: TokenId) -> DispatchResult {1764        ensure!(1765            <NftItemList<T>>::contains_key(collection_id, item_id),1766            Error::<T>::TokenNotFound1767        );1768        let item = <NftItemList<T>>::get(collection_id, item_id);1769        Self::remove_token_index(collection_id, item_id, &item.owner)?;17701771        // update balance1772        let new_balance = <Balance<T>>::get(collection_id, &item.owner)1773            .checked_sub(1)1774            .ok_or(Error::<T>::NumOverflow)?;1775        <Balance<T>>::insert(collection_id, item.owner.clone(), new_balance);1776        <NftItemList<T>>::remove(collection_id, item_id);17771778        Ok(())1779    }17801781    fn burn_fungible_item(owner: &T::AccountId, collection_id: CollectionId, value: u128) -> DispatchResult {1782        ensure!(1783            <FungibleItemList<T>>::contains_key(collection_id, owner),1784            Error::<T>::TokenNotFound1785        );1786        let mut balance = <FungibleItemList<T>>::get(collection_id, owner);1787        ensure!(balance.value >= value, Error::<T>::TokenValueNotEnough);17881789        // update balance1790        let new_balance = <Balance<T>>::get(collection_id, owner)1791            .checked_sub(value)1792            .ok_or(Error::<T>::NumOverflow)?;1793        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);17941795        if balance.value - value > 0 {1796            balance.value -= value;1797            <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);1798        }1799        else {1800            <FungibleItemList<T>>::remove(collection_id, owner);1801        }18021803        Ok(())1804    }18051806    fn collection_exists(collection_id: CollectionId) -> DispatchResult {1807        ensure!(1808            <Collection<T>>::contains_key(collection_id),1809            Error::<T>::CollectionNotFound1810        );1811        Ok(())1812    }18131814    fn check_owner_permissions(collection_id: CollectionId, subject: T::AccountId) -> DispatchResult {1815        Self::collection_exists(collection_id)?;18161817        let target_collection = <Collection<T>>::get(collection_id);1818        ensure!(1819            subject == target_collection.owner,1820            Error::<T>::NoPermission1821        );18221823        Ok(())1824    }18251826    fn is_owner_or_admin_permissions(collection_id: CollectionId, subject: T::AccountId) -> bool {1827        let target_collection = <Collection<T>>::get(collection_id);1828        let mut result: bool = subject == target_collection.owner;1829        let exists = <AdminList<T>>::contains_key(collection_id);18301831        if !result & exists {1832            if <AdminList<T>>::get(collection_id).contains(&subject) {1833                result = true1834            }1835        }18361837        result1838    }18391840    fn check_owner_or_admin_permissions(1841        collection_id: CollectionId,1842        subject: T::AccountId,1843    ) -> DispatchResult {1844        Self::collection_exists(collection_id)?;1845        let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());18461847        ensure!(1848            result,1849            Error::<T>::NoPermission1850        );1851        Ok(())1852    }18531854    fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool {1855        let target_collection = <Collection<T>>::get(collection_id);18561857        match target_collection.mode {1858            CollectionMode::NFT => {1859                <NftItemList<T>>::get(collection_id, item_id).owner == subject1860            }1861            CollectionMode::Fungible(_) => {1862                <FungibleItemList<T>>::contains_key(collection_id, &subject)1863            }1864            CollectionMode::ReFungible(_) => {1865                <ReFungibleItemList<T>>::get(collection_id, item_id)1866                    .owner1867                    .iter()1868                    .any(|i| i.owner == subject)1869            }1870            CollectionMode::Invalid => false,1871        }1872    }18731874    fn check_white_list(collection_id: CollectionId, address: &T::AccountId) -> DispatchResult {1875        let mes = Error::<T>::AddresNotInWhiteList;1876        ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);18771878        Ok(())1879    }18801881    /// Check if token exists. In case of Fungible, check if there is an entry for 1882    /// the owner in fungible balances double map1883    fn token_exists(1884        collection_id: CollectionId,1885        item_id: TokenId,1886        owner: &T::AccountId1887    ) -> DispatchResult {1888        let target_collection = <Collection<T>>::get(collection_id);1889        let exists = match target_collection.mode1890        {1891            CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),1892            CollectionMode::Fungible(_)  => <FungibleItemList<T>>::contains_key(collection_id, owner),1893            CollectionMode::ReFungible(_)  => <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1894            _ => false1895        };18961897        ensure!(exists == true, Error::<T>::TokenNotFound);1898        Ok(())1899    }19001901    fn transfer_fungible(1902        collection_id: CollectionId,1903        value: u128,1904        owner: &T::AccountId,1905        recipient: &T::AccountId,1906    ) -> DispatchResult {1907        Self::token_exists(collection_id, 0, owner)?;19081909        let mut balance = <FungibleItemList<T>>::get(collection_id, owner);1910        ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);19111912        // Send balance to recipient (updates balanceOf of recipient)1913        Self::add_fungible_item(collection_id, recipient, value)?;19141915        // update balanceOf of sender1916        <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);19171918        // Reduce or remove sender1919        if balance.value == value {1920            <FungibleItemList<T>>::remove(collection_id, owner);1921        }1922        else {1923            balance.value -= value;1924            <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);1925        }19261927        Ok(())1928    }19291930    fn transfer_refungible(1931        collection_id: CollectionId,1932        item_id: TokenId,1933        value: u128,1934        owner: T::AccountId,1935        new_owner: T::AccountId,1936    ) -> DispatchResult {1937        Self::token_exists(collection_id, item_id, &owner)?;19381939        let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);1940        let item = full_item1941            .owner1942            .iter()1943            .filter(|i| i.owner == owner)1944            .next()1945            .ok_or(Error::<T>::NumOverflow)?;1946        let amount = item.fraction;19471948        ensure!(amount >= value, Error::<T>::TokenValueTooLow);19491950        // update balance1951        let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone())1952            .checked_sub(value)1953            .ok_or(Error::<T>::NumOverflow)?;1954        <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);19551956        let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())1957            .checked_add(value)1958            .ok_or(Error::<T>::NumOverflow)?;1959        <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);19601961        let old_owner = item.owner.clone();1962        let new_owner_has_account = full_item.owner.iter().any(|i| i.owner == new_owner);19631964        // transfer1965        if amount == value && !new_owner_has_account {1966            // change owner1967            // new owner do not have account1968            let mut new_full_item = full_item.clone();1969            new_full_item1970                .owner1971                .iter_mut()1972                .find(|i| i.owner == owner)1973                .unwrap()1974                .owner = new_owner.clone();1975            <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);19761977            // update index collection1978            Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;1979        } else {1980            let mut new_full_item = full_item.clone();1981            new_full_item1982                .owner1983                .iter_mut()1984                .find(|i| i.owner == owner)1985                .unwrap()1986                .fraction -= value;19871988            // separate amount1989            if new_owner_has_account {1990                // new owner has account1991                new_full_item1992                    .owner1993                    .iter_mut()1994                    .find(|i| i.owner == new_owner)1995                    .unwrap()1996                    .fraction += value;1997            } else {1998                // new owner do not have account1999                new_full_item.owner.push(Ownership {2000                    owner: new_owner.clone(),2001                    fraction: value,2002                });2003                Self::add_token_index(collection_id, item_id, &new_owner)?;2004            }20052006            <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2007        }20082009        Ok(())2010    }20112012    fn transfer_nft(2013        collection_id: CollectionId,2014        item_id: TokenId,2015        sender: T::AccountId,2016        new_owner: T::AccountId,2017    ) -> DispatchResult {2018        Self::token_exists(collection_id, item_id, &sender)?;20192020        let mut item = <NftItemList<T>>::get(collection_id, item_id);20212022        ensure!(2023            sender == item.owner,2024            Error::<T>::MustBeTokenOwner2025        );20262027        // update balance2028        let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone())2029            .checked_sub(1)2030            .ok_or(Error::<T>::NumOverflow)?;2031        <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);20322033        let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())2034            .checked_add(1)2035            .ok_or(Error::<T>::NumOverflow)?;2036        <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);20372038        // change owner2039        let old_owner = item.owner.clone();2040        item.owner = new_owner.clone();2041        <NftItemList<T>>::insert(collection_id, item_id, item);20422043        // update index collection2044        Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;20452046        Ok(())2047    }2048    2049    fn set_re_fungible_variable_data(2050        collection_id: CollectionId,2051        item_id: TokenId,2052        data: Vec<u8>2053    ) -> DispatchResult {2054        let mut item = <ReFungibleItemList<T>>::get(collection_id, item_id);20552056        item.variable_data = data;20572058        <ReFungibleItemList<T>>::insert(collection_id, item_id, item);20592060        Ok(())2061    }20622063    fn set_nft_variable_data(2064        collection_id: CollectionId,2065        item_id: TokenId,2066        data: Vec<u8>2067    ) -> DispatchResult {2068        let mut item = <NftItemList<T>>::get(collection_id, item_id);2069        2070        item.variable_data = data;20712072        <NftItemList<T>>::insert(collection_id, item_id, item);2073        2074        Ok(())2075    }20762077    fn init_collection(item: &CollectionType<T::AccountId>) {2078        // check params2079        assert!(2080            item.decimal_points <= MAX_DECIMAL_POINTS,2081            "decimal_points parameter must be lower than MAX_DECIMAL_POINTS"2082        );2083        assert!(2084            item.name.len() <= 64,2085            "Collection name can not be longer than 63 char"2086        );2087        assert!(2088            item.name.len() <= 256,2089            "Collection description can not be longer than 255 char"2090        );2091        assert!(2092            item.token_prefix.len() <= 16,2093            "Token prefix can not be longer than 15 char"2094        );20952096        // Generate next collection ID2097        let next_id = CreatedCollectionCount::get()2098            .checked_add(1)2099            .unwrap();21002101        CreatedCollectionCount::put(next_id);2102    }21032104    fn init_nft_token(collection_id: CollectionId, item: &NftItemType<T::AccountId>) {2105        let current_index = <ItemListIndex>::get(collection_id)2106            .checked_add(1)2107            .unwrap();21082109        let item_owner = item.owner.clone();2110        Self::add_token_index(collection_id, current_index, &item.owner).unwrap();21112112        <ItemListIndex>::insert(collection_id, current_index);21132114        // Update balance2115        let new_balance = <Balance<T>>::get(collection_id, &item_owner)2116            .checked_add(1)2117            .unwrap();2118        <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);2119    }21202121    fn init_fungible_token(collection_id: CollectionId, owner: &T::AccountId, item: &FungibleItemType) {2122        let current_index = <ItemListIndex>::get(collection_id)2123            .checked_add(1)2124            .unwrap();21252126        Self::add_token_index(collection_id, current_index, owner).unwrap();21272128        <ItemListIndex>::insert(collection_id, current_index);21292130        // Update balance2131        let new_balance = <Balance<T>>::get(collection_id, owner)2132            .checked_add(item.value)2133            .unwrap();2134        <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);2135    }21362137    fn init_refungible_token(collection_id: CollectionId, item: &ReFungibleItemType<T::AccountId>) {2138        let current_index = <ItemListIndex>::get(collection_id)2139            .checked_add(1)2140            .unwrap();21412142        let value = item.owner.first().unwrap().fraction;2143        let owner = item.owner.first().unwrap().owner.clone();21442145        Self::add_token_index(collection_id, current_index, &owner).unwrap();21462147        <ItemListIndex>::insert(collection_id, current_index);21482149        // Update balance2150        let new_balance = <Balance<T>>::get(collection_id, &owner)2151            .checked_add(value)2152            .unwrap();2153        <Balance<T>>::insert(collection_id, owner.clone(), new_balance);2154    }21552156    fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: &T::AccountId) -> DispatchResult {21572158        // add to account limit2159        if <AccountItemCount<T>>::contains_key(owner) {21602161            // bound Owned tokens by a single address2162            let count = <AccountItemCount<T>>::get(owner);2163            ensure!(count < ChainLimit::get().account_token_ownership_limit, Error::<T>::AddressOwnershipLimitExceeded);21642165            <AccountItemCount<T>>::insert(owner.clone(), count2166                .checked_add(1)2167                .ok_or(Error::<T>::NumOverflow)?);2168        }2169        else {2170            <AccountItemCount<T>>::insert(owner.clone(), 1);2171        }21722173        let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner);2174        if list_exists {2175            let mut list = <AddressTokens<T>>::get(collection_id, owner);2176            let item_contains = list.contains(&item_index.clone());21772178            if !item_contains {2179                list.push(item_index.clone());2180            }21812182            <AddressTokens<T>>::insert(collection_id, owner.clone(), list);2183        } else {2184            let mut itm = Vec::new();2185            itm.push(item_index.clone());2186            <AddressTokens<T>>::insert(collection_id, owner.clone(), itm);2187        }21882189        Ok(())2190    }21912192    fn remove_token_index(2193        collection_id: CollectionId,2194        item_index: TokenId,2195        owner: &T::AccountId,2196    ) -> DispatchResult {21972198        // update counter2199        <AccountItemCount<T>>::insert(owner.clone(), 2200            <AccountItemCount<T>>::get(owner)2201            .checked_sub(1)2202            .ok_or(Error::<T>::NumOverflow)?);220322042205        let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner);2206        if list_exists {2207            let mut list = <AddressTokens<T>>::get(collection_id, owner);2208            let item_contains = list.contains(&item_index.clone());22092210            if item_contains {2211                list.retain(|&item| item != item_index);2212                <AddressTokens<T>>::insert(collection_id, owner.clone(), list);2213            }2214        }22152216        Ok(())2217    }22182219    fn move_token_index(2220        collection_id: CollectionId,2221        item_index: TokenId,2222        old_owner: &T::AccountId,2223        new_owner: &T::AccountId,2224    ) -> DispatchResult {2225        Self::remove_token_index(collection_id, item_index, old_owner)?;2226        Self::add_token_index(collection_id, item_index, new_owner)?;22272228        Ok(())2229    }2230    2231    fn ensure_contract_owned(account: T::AccountId, contract: &T::AccountId) -> DispatchResult {2232        if <ContractOwner<T>>::contains_key(contract.clone()) {2233            let owner = <ContractOwner<T>>::get(contract);2234            ensure!(account == owner, Error::<T>::NoPermission);2235        } else {2236            fail!(Error::<T>::NoPermission);2237        }22382239        Ok(())2240    }2241}22422243////////////////////////////////////////////////////////////////////////////////////////////////////2244// Economic models2245// #region22462247/// Fee multiplier.2248pub type Multiplier = FixedU128;22492250type BalanceOf<T> = <<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::Balance;22512252/// Require the transactor pay for themselves and maybe include a tip to gain additional priority2253/// in the queue.2254#[derive(Encode, Decode, Clone, Eq, PartialEq)]2255pub struct ChargeTransactionPayment<T: Config>(#[codec(compact)] BalanceOf<T>);22562257impl<T: Config + Send + Sync> sp_std::fmt::Debug 2258    for ChargeTransactionPayment<T>2259{2260	#[cfg(feature = "std")]2261	fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {2262		write!(f, "ChargeTransactionPayment<{:?}>", self.0)2263	}2264	#[cfg(not(feature = "std"))]2265	fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {2266		Ok(())2267	}2268}22692270impl<T: Config> ChargeTransactionPayment<T>2271where2272    T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,2273    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,2274    T::AccountId: AsRef<[u8]>,2275    T::AccountId: UncheckedFrom<T::Hash>,2276{2277    fn traditional_fee(2278        len: usize,2279        info: &DispatchInfoOf<T::Call>,2280        tip: BalanceOf<T>,2281    ) -> BalanceOf<T>2282    where2283        T::Call: Dispatchable<Info = DispatchInfo>,2284    {2285        <transaction_payment::Module<T>>::compute_fee(len as u32, info, tip)2286    }22872288	fn get_priority(len: usize, info: &DispatchInfoOf<T::Call>, final_fee: BalanceOf<T>) -> TransactionPriority {2289        let weight_saturation = T::BlockWeights::get().max_block / info.weight.max(1);2290        let max_block_length = *T::BlockLength::get().max.get(DispatchClass::Normal);2291        let len_saturation = max_block_length as u64 / (len as u64).max(1);2292        let coefficient: BalanceOf<T> = weight_saturation2293            .min(len_saturation)2294            .saturated_into::<BalanceOf<T>>();2295        final_fee2296            .saturating_mul(coefficient)2297            .saturated_into::<TransactionPriority>()2298    }22992300    fn withdraw_fee(2301        &self,2302        who: &T::AccountId,2303        call: &T::Call,2304        info: &DispatchInfoOf<T::Call>,2305        len: usize,2306	) -> Result<2307		(2308			BalanceOf<T>,2309			<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::LiquidityInfo,2310		),2311		TransactionValidityError,2312	> {2313        let tip = self.0;23142315        // Set fee based on call type. Creating collection costs 1 Unique.2316        // All other transactions have traditional fees so far2317        // let fee = match call.is_sub_type() {2318        //     Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),2319        //     _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes2320        //                                                 // _ => <BalanceOf<T>>::from(100)2321        // };2322        let fee = Self::traditional_fee(len, info, tip);23232324        // Only mess with balances if fee is not zero.2325        if fee.is_zero() {2326            return <<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(who, call, info, fee, tip)2327			.map(|i| (fee, i));2328        }23292330        // Determine who is paying transaction fee based on ecnomic model2331        // Parse call to extract collection ID and access collection sponsor2332        let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {2333            Some(Call::create_item(collection_id, _owner, _properties)) => {23342335                // sponsor timeout2336                let block_number = <system::Module<T>>::block_number() as T::BlockNumber;23372338                let limit = <Collection<T>>::get(collection_id).limits.sponsor_transfer_timeout;2339                let mut sponsored = true;2340                if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {2341                    let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));2342                    let limit_time = last_tx_block + limit.into();2343                    if block_number <= limit_time {2344                        sponsored = false;2345                    }2346                }2347                if sponsored {2348                    <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);2349                }23502351                // check free create limit2352                if (<Collection<T>>::get(collection_id).limits.sponsored_data_size >= (_properties.len() as u32)) &&2353                   (<Collection<T>>::get(collection_id).sponsor_confirmed) &&2354                   (sponsored)2355                {2356                    <Collection<T>>::get(collection_id).sponsor2357                } else {2358                    T::AccountId::default()2359                }2360            }2361            Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {2362                2363                let mut sponsor_transfer = false;2364                if <Collection<T>>::get(collection_id).sponsor_confirmed {23652366                    let collection_limits = <Collection<T>>::get(collection_id).limits;2367                    let collection_mode = <Collection<T>>::get(collection_id).mode;2368    2369                    // sponsor timeout2370                    let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2371                    sponsor_transfer = match collection_mode {2372                        CollectionMode::NFT => {2373    2374                            // get correct limit2375                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2376                                collection_limits.sponsor_transfer_timeout2377                            } else {2378                                ChainLimit::get().nft_sponsor_transfer_timeout2379                            };2380    2381                            let mut sponsored = true;2382                            if <NftTransferBasket<T>>::contains_key(collection_id, item_id) {2383                                let last_tx_block = <NftTransferBasket<T>>::get(collection_id, item_id);2384                                let limit_time = last_tx_block + limit.into();2385                                if block_number <= limit_time {2386                                    sponsored = false;2387                                }2388                            }2389                            if sponsored {2390                                <NftTransferBasket<T>>::insert(collection_id, item_id, block_number);2391                            }23922393                            sponsored2394                        }2395                        CollectionMode::Fungible(_) => {2396    2397                            // get correct limit2398                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2399                                collection_limits.sponsor_transfer_timeout2400                            } else {2401                                ChainLimit::get().fungible_sponsor_transfer_timeout2402                            };2403    2404                            let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2405                            let mut sponsored = true;2406                            if <FungibleTransferBasket<T>>::contains_key(collection_id, who) {2407                                let last_tx_block = <FungibleTransferBasket<T>>::get(collection_id, who);2408                                let limit_time = last_tx_block + limit.into();2409                                if block_number <= limit_time {2410                                    sponsored = false;2411                                }2412                            }2413                            if sponsored {2414                                <FungibleTransferBasket<T>>::insert(collection_id, who, block_number);2415                            }24162417                            sponsored2418                        }2419                        CollectionMode::ReFungible(_) => {2420    2421                            // get correct limit2422                            let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {2423                                collection_limits.sponsor_transfer_timeout2424                            } else {2425                                ChainLimit::get().refungible_sponsor_transfer_timeout2426                            };2427    2428                            let mut sponsored = true;2429                            if <ReFungibleTransferBasket<T>>::contains_key(collection_id, item_id) {2430                                let last_tx_block = <ReFungibleTransferBasket<T>>::get(collection_id, item_id);2431                                let limit_time = last_tx_block + limit.into();2432                                if block_number <= limit_time {2433                                    sponsored = false;2434                                }2435                            }2436                            if sponsored {2437                                <ReFungibleTransferBasket<T>>::insert(collection_id, item_id, block_number);2438                            }24392440                            sponsored2441                        }2442                        _ => {2443                            false2444                        },2445                    };2446                }24472448                if !sponsor_transfer {2449                    T::AccountId::default()2450                } else {2451                    <Collection<T>>::get(collection_id).sponsor2452                }2453            }24542455            _ => T::AccountId::default(),2456        };24572458        // Sponsor smart contracts2459        sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {24602461            // On instantiation: set the contract owner2462            Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, _data, salt)) => {24632464                let new_contract_address = <pallet_contracts::Module<T>>::contract_address(2465                    &who,2466                    code_hash,2467                    salt,2468                );2469                <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());24702471                T::AccountId::default()2472            },24732474            // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2475            Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {24762477                let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());24782479                let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())2480                  && <ContractOwner<T>>::get(called_contract.clone()) == *who;2481                let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());2482                  2483                if !owned_contract && white_list_enabled {2484                    if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {2485                        return Err(InvalidTransaction::Call.into());2486                    }2487                }24882489                let mut sponsor_transfer = false;2490                if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {2491                    let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));2492                    let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2493                    let rate_limit = <ContractSponsoringRateLimit<T>>::get(&called_contract);2494                    let limit_time = last_tx_block + rate_limit;24952496                    if block_number >= limit_time {2497                        <ContractSponsorBasket<T>>::insert((called_contract.clone(), who.clone()), block_number);2498                        sponsor_transfer = true;2499                    }2500                } else {2501                    sponsor_transfer = false;2502                }2503               2504                2505                let mut sp = T::AccountId::default();2506                if sponsor_transfer {2507                    if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2508                        if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2509                            sp = called_contract;2510                        }2511                    }2512                }25132514                sp2515            },25162517            _ => sponsor,2518        };25192520        let mut who_pays_fee: T::AccountId = sponsor.clone();2521        if sponsor == T::AccountId::default() {2522            who_pays_fee = who.clone();2523        }25242525		<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(&who_pays_fee, call, info, fee, tip)2526			.map(|i| (fee, i))2527    }2528}252925302531impl<T: Config + Send + Sync> SignedExtension2532    for ChargeTransactionPayment<T>2533where2534    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,2535    T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,2536    T::AccountId: AsRef<[u8]>,2537    T::AccountId: UncheckedFrom<T::Hash>,2538{2539    const IDENTIFIER: &'static str = "ChargeTransactionPayment";2540    type AccountId = T::AccountId;2541    type Call = T::Call;2542    type AdditionalSigned = ();2543    type Pre = (2544        // tip2545        BalanceOf<T>,2546        // who pays fee2547        Self::AccountId,2548		// imbalance resulting from withdrawing the fee2549		<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::LiquidityInfo,2550    );2551    fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {2552        Ok(())2553    }25542555    fn validate(2556        &self,2557        who: &Self::AccountId,2558        call: &Self::Call,2559        info: &DispatchInfoOf<Self::Call>,2560        len: usize,2561    ) -> TransactionValidity {2562		let (fee, _) = self.withdraw_fee(who, call, info, len)?;2563		Ok(ValidTransaction {2564			priority: Self::get_priority(len, info, fee),2565			..Default::default()2566		})2567    }25682569    fn pre_dispatch(2570        self,2571        who: &Self::AccountId,2572        call: &Self::Call,2573        info: &DispatchInfoOf<Self::Call>,2574        len: usize,2575    ) -> Result<Self::Pre, TransactionValidityError> {2576        let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;2577        Ok((self.0, who.clone(), imbalance))2578    }25792580    fn post_dispatch(2581        pre: Self::Pre,2582        info: &DispatchInfoOf<Self::Call>,2583        post_info: &PostDispatchInfoOf<Self::Call>,2584        len: usize,2585        _result: &DispatchResult,2586    ) -> Result<(), TransactionValidityError> {2587		let (tip, who, imbalance) = pre;2588		let actual_fee = transaction_payment::Module::<T>::compute_actual_fee(2589			len as u32,2590			info,2591			post_info,2592			tip,2593		);2594		<T as transaction_payment::Config>::OnChargeTransaction::correct_and_deposit_fee(&who, info, post_info, actual_fee, tip, imbalance)?;2595		Ok(())2596    }2597}25982599// #endregion
modifiedruntime/Cargo.tomldiffbeforeafterboth
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -5,7 +5,7 @@
 license = 'Unlicense'
 name = 'nft-runtime'
 repository = 'https://github.com/usetech-llc/nft_parachain/'
-version = '2.0.0'
+version = '2.0.1'
 
 [package.metadata.docs.rs]
 targets = ['x86_64-unknown-linux-gnu']
@@ -25,39 +25,39 @@
 serde = { features = ['derive'], optional = true, version = '1.0.101' }
 
 # local dependencies
-pallet-nft = { path = '../pallets/nft', default-features = false, version = '2.0.0' }
+pallet-nft = { path = '../pallets/nft', default-features = false, version = '2.0.1' }
 
 # Substrate dependencies
-frame-benchmarking = { default-features = false, optional = true, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-frame-executive = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-frame-support = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-frame-system = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-frame-system-benchmarking = { default-features = false, optional = true, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-frame-system-rpc-runtime-api = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-aura = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-balances = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-contracts = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-contracts-primitives = { default-features = false, version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-contracts-rpc-runtime-api = { default-features = false, version = '0.8.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-grandpa = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-randomness-collective-flip = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-sudo = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-timestamp = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-transaction-payment = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-transaction-payment-rpc-runtime-api = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-treasury = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-pallet-vesting = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-api = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-block-builder = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-consensus-aura = { default-features = false, version = '0.8.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-core = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-inherents = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-offchain = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-runtime = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-session = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-std = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-transaction-pool = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-sp-version = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
+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-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' }
 
 [features]
 default = ['std']
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -13,17 +13,19 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
-use pallet_contracts_rpc_runtime_api::ContractExecResult;
 use pallet_grandpa::fg_primitives;
 use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
 use sp_api::impl_runtime_apis;
 use sp_consensus_aura::sr25519::AuthorityId as AuraId;
 use sp_core::{ crypto::KeyTypeId, crypto::Public, OpaqueMetadata };
 use sp_runtime::{
+    Permill, Perbill, Perquintill, Percent,
+    // BuildStorage, 
+    ModuleId, FixedPointNumber,
     create_runtime_str, generic, impl_opaque_keys,
     traits::{
         Convert, ConvertInto, BlakeTwo256, Block as BlockT, IdentifyAccount, 
-        IdentityLookup, NumberFor, Saturating, Verify,
+        IdentityLookup, NumberFor, Verify,
     },
     transaction_validity::{TransactionSource, TransactionValidity},
     ApplyExtrinsicResult, MultiSignature,
@@ -32,17 +34,18 @@
 #[cfg(feature = "std")]
 use sp_version::NativeVersion;
 use sp_version::RuntimeVersion;
-
+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;
+use pallet_contracts::WeightInfo;
 pub use frame_support::{
     construct_runtime,
     dispatch::DispatchResult,
     parameter_types,
     traits::{
         Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness,
-        WithdrawReason, LockIdentifier,
+        LockIdentifier,
     },
     weights::{
         constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
@@ -51,10 +54,11 @@
     },
     StorageValue,
 };
-#[cfg(any(feature = "std", test))]
-pub use sp_runtime::BuildStorage;
-use sp_runtime:: { Perbill, Permill, Percent, ModuleId };
-use frame_system::{self as system, EnsureRoot };
+// #[cfg(any(feature = "std", test))]
+use frame_system::{
+    self as system,
+    EnsureRoot, 
+    limits::{BlockWeights, BlockLength}};
 use sp_std::{marker::PhantomData};
 
 pub use pallet_timestamp::Call as TimestampCall;
@@ -168,7 +172,7 @@
 }
 
 /// Provides a membership set with only the configured aura users
-pub struct ValiudatorsOnly<Runtime: pallet_aura::Trait>(PhantomData<Runtime>);
+pub struct ValiudatorsOnly<Runtime: pallet_aura::Config>(PhantomData<Runtime>);
 impl frame_support::traits::Contains<AccountId> for ValiudatorsOnly<Runtime> {
 	fn contains(t: &AccountId) -> bool {
         let arr: [u8; 32] = *t.as_ref();
@@ -204,19 +208,62 @@
 	}
 }
 
+type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
+
+pub struct DealWithFees;
+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, 80% to treasury, 20% to author
+			let mut split = fees.ration(80, 20);
+			if let Some(tips) = fees_then_tips.next() {
+				// for tips, if any, 80% to treasury, 20% to author (though this can be anything)
+				tips.ration_merge_into(80, 20, &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);
+/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
+/// by  Operational  extrinsics.
+const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
+/// We allow for 2 seconds of compute with a 6 second average block time.
+const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND;
+
 parameter_types! {
     pub const BlockHashCount: BlockNumber = 2400;
-    /// We allow for 2 seconds of compute with a 6 second average block time.
-    pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND;
+	pub RuntimeBlockLength: BlockLength =
+		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
     pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
-    /// Assume 10% of weight for average on_initialize calls.
-    pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get()
-        .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get();
     pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
+	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
+		.base_block(BlockExecutionWeight::get())
+		.for_class(DispatchClass::all(), |weights| {
+			weights.base_extrinsic = ExtrinsicBaseWeight::get();
+		})
+		.for_class(DispatchClass::Normal, |weights| {
+			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
+		})
+		.for_class(DispatchClass::Operational, |weights| {
+			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
+			// Operational transactions have some extra reserved space, so that they
+			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
+			weights.reserved = Some(
+				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
+			);
+		})
+		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
+		.build_or_panic();
     pub const Version: RuntimeVersion = VERSION;
+    pub const SS58Prefix: u8 = 42;
 }
 
-impl system::Trait for Runtime {
+impl system::Config for Runtime {
     /// The basic call filter to use in dispatchable.
     type BaseCallFilter = ();
     /// The identifier used to distinguish between accounts.
@@ -241,24 +288,11 @@
     type Origin = Origin;
     /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
     type BlockHashCount = BlockHashCount;
-    /// Maximum weight of each block.
-    type MaximumBlockWeight = MaximumBlockWeight;
     /// The weight of database operations that the runtime can invoke.
     type DbWeight = RocksDbWeight;
     /// The weight of the overhead invoked on the block import process, independent of the
     /// extrinsics included in that block.
-    type BlockExecutionWeight = BlockExecutionWeight;
-    /// The base weight of any extrinsic processed by the runtime, independent of the
-    /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...)
-    type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
-    /// The maximum weight that a single extrinsic of `Normal` dispatch class can have,
-    /// idependent of the logic of that extrinsics. (Roughly max block weight - average on
-    /// initialize cost).
-    type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
-    /// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
-    type MaximumBlockLength = MaximumBlockLength;
-    /// Portion of the block weight that is available to all normal transactions.
-    type AvailableBlockRatio = AvailableBlockRatio;
+	type BlockWeights = RuntimeBlockWeights;
     /// Version of the runtime.
     type Version = Version;
  	/// This type is being generated by `construct_runtime!`.
@@ -270,14 +304,17 @@
     /// The data to be stored in an account.
     type AccountData = pallet_balances::AccountData<Balance>;
 	/// Weight information for the extrinsics of this pallet.
-	type SystemWeightInfo = ();
+    type SystemWeightInfo = system::weights::SubstrateWeight<Runtime>;
+    
+	type BlockLength = RuntimeBlockLength;
+	type SS58Prefix = SS58Prefix;
 }
 
-impl pallet_aura::Trait for Runtime {
+impl pallet_aura::Config for Runtime {
     type AuthorityId = AuraId;
 }
 
-impl pallet_grandpa::Trait for Runtime {
+impl pallet_grandpa::Config for Runtime {
 	type Event = Event;
 	type Call = Call;
 
@@ -300,7 +337,7 @@
     pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
 }
 
-impl pallet_timestamp::Trait for Runtime {
+impl pallet_timestamp::Config for Runtime {
 	/// A timestamp: milliseconds since the unix epoch.
 	type Moment = u64;
 	type OnTimestampSet = Aura;
@@ -314,7 +351,7 @@
 	pub const MaxLocks: u32 = 50;
 }
 
-impl pallet_balances::Trait for Runtime {
+impl pallet_balances::Config for Runtime {
 	type MaxLocks = MaxLocks;
 	/// The type for recording an account's balance.
 	type Balance = Balance;
@@ -330,42 +367,70 @@
 pub const CENTS: Balance = 1_000 * MILLICENTS;
 pub const DOLLARS: Balance = 100 * CENTS;
 
+pub const fn deposit(items: u32, bytes: u32) -> Balance {
+    items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS
+}
+
 parameter_types! {
-    pub const TombstoneDeposit: Balance = 0;
-    pub const RentByteFee: Balance = 4 * MILLICENTS;
-    pub const RentDepositOffset: Balance = 1000 * MILLICENTS;
-    pub const SurchargeReward: Balance = 150 * MILLICENTS;
+	pub const TombstoneDeposit: Balance = deposit(
+		0,
+		sp_std::mem::size_of::<pallet_contracts::ContractInfo<Runtime>>() as u32
+	);
+	pub const DepositPerContract: Balance = TombstoneDeposit::get();
+	pub const DepositPerStorageByte: Balance = deposit(0, 1);
+	pub const DepositPerStorageItem: Balance = deposit(1, 0);
+	pub RentFraction: Perbill = Perbill::from_rational_approximation(1u32, 30 * DAYS);
+	pub const SurchargeReward: Balance = 150 * MILLICENTS;
+	pub const SignedClaimHandicap: u32 = 2;
+	pub const MaxDepth: u32 = 32;
+	pub const MaxValueSize: u32 = 16 * 1024;
+	// The lazy deletion runs inside on_initialize.
+	pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
+		RuntimeBlockWeights::get().max_block;
+	// The weight needed for decoding the queue should be less or equal than a fifth
+	// of the overall weight dedicated to the lazy deletion.
+	pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
+			<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
+			<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
+		)) / 5) as u32;
 }
 
-impl pallet_contracts::Trait for Runtime {
+
+impl pallet_contracts::Config for Runtime {
 	type Time = Timestamp;
 	type Randomness = RandomnessCollectiveFlip;
 	type Currency = Balances;
 	type Event = Event;
-	type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer<Runtime>;
-	type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter<Runtime>;
 	type RentPayment = ();
-	type SignedClaimHandicap = pallet_contracts::DefaultSignedClaimHandicap;
+	type SignedClaimHandicap = SignedClaimHandicap;
 	type TombstoneDeposit = TombstoneDeposit;
-	type StorageSizeOffset = pallet_contracts::DefaultStorageSizeOffset;
-	type RentByteFee = RentByteFee;
-	type RentDepositOffset = RentDepositOffset;
+	type DepositPerContract = DepositPerContract;
+	type DepositPerStorageByte = DepositPerStorageByte;
+	type DepositPerStorageItem = DepositPerStorageItem;
+	type RentFraction = RentFraction;
 	type SurchargeReward = SurchargeReward;
-	type MaxDepth = pallet_contracts::DefaultMaxDepth;
-	type MaxValueSize = pallet_contracts::DefaultMaxValueSize;
+	type MaxDepth = MaxDepth;
+	type MaxValueSize = MaxValueSize;
 	type WeightPrice = pallet_transaction_payment::Module<Self>;
+	type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
+	type ChainExtension = ();
+	type DeletionQueueDepth = DeletionQueueDepth;
+	type DeletionWeightLimit = DeletionWeightLimit;
 }
 
 parameter_types! {
 	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
+	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
+	pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000);
+	pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128);
 }
 
-impl pallet_transaction_payment::Trait for Runtime {
-    type Currency = pallet_balances::Module<Runtime>;
-    type OnTransactionPayment = Treasury;
-    type TransactionByteFee = TransactionByteFee;
-    type WeightToFee = IdentityFee<Balance>;
-    type FeeMultiplierUpdate =  ();
+impl pallet_transaction_payment::Config for Runtime {
+	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
+	type TransactionByteFee = TransactionByteFee;
+	type WeightToFee = IdentityFee<Balance>;
+	type FeeMultiplierUpdate =
+		TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
 }
 
 parameter_types! {
@@ -386,33 +451,23 @@
 	pub const BountyValueMinimum: Balance = 5 * DOLLARS;
 }
 
-impl pallet_treasury::Trait for Runtime {
+impl pallet_treasury::Config for Runtime {
 	type ModuleId = TreasuryModuleId;
 	type Currency = Balances;
-    type ApproveOrigin = EnsureRoot<AccountId>;
+	type ApproveOrigin = EnsureRoot<AccountId>;
 	type RejectOrigin = EnsureRoot<AccountId>;
-	type Tippers = ValiudatorsOnly<Self>;
-	type TipCountdown = TipCountdown;
-	type TipFindersFee = TipFindersFee;
-	type TipReportDepositBase = TipReportDepositBase;
-	type DataDepositPerByte = DataDepositPerByte;
 	type Event = Event;
 	type OnSlash = ();
 	type ProposalBond = ProposalBond;
 	type ProposalBondMinimum = ProposalBondMinimum;
 	type SpendPeriod = SpendPeriod;
 	type Burn = Burn;
-	type BountyDepositBase = BountyDepositBase;
-	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
-	type BountyUpdatePeriod = BountyUpdatePeriod;
-	type BountyCuratorDeposit = BountyCuratorDeposit;
-	type BountyValueMinimum = BountyValueMinimum;
-	type MaximumReasonLength = MaximumReasonLength;
 	type BurnDestination = ();
-	type WeightInfo = ();
+	type SpendFunds = ();
+	type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
 }
 
-impl pallet_sudo::Trait for Runtime {
+impl pallet_sudo::Config for Runtime {
     type Event = Event;
     type Call = Call;
 }
@@ -421,7 +476,7 @@
 	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
 }
 
-impl pallet_vesting::Trait for Runtime {
+impl pallet_vesting::Config for Runtime {
 	type Event = Event;
 	type Currency = Balances;
 	type BlockNumberToBalance = ConvertInto;
@@ -430,7 +485,7 @@
 }
 
 /// Used for the module nft in `./nft.rs`
-impl pallet_nft::Trait for Runtime {
+impl pallet_nft::Config for Runtime {
     type Event = Event;
     type WeightInfo = nft_weights::WeightInfo;
 }
@@ -443,7 +498,7 @@
     {
         System: system::{Module, Call, Config, Storage, Event<T>},
         RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
-        Contracts: pallet_contracts::{Module, Call, Config, Storage, Event<T>},
+        Contracts: pallet_contracts::{Module, Call, Config<T>, Storage, Event<T>},
         Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
         Aura: pallet_aura::{Module, Config<T>, Inherent},
         Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
@@ -486,41 +541,32 @@
 
 impl_runtime_apis! {
 
-    impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber>
-    for Runtime
-    {
-        fn call(
-            origin: AccountId,
-            dest: AccountId,
-            value: Balance,
-            gas_limit: u64,
-            input_data: Vec<u8>,
-        ) -> ContractExecResult {
-			let (exec_result, gas_consumed) =
-				Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data);
-			match exec_result {
-				Ok(v) => ContractExecResult::Success {
-					flags: v.flags.bits(),
-					data: v.data,
-					gas_consumed: gas_consumed,
-				},
-				Err(_) => ContractExecResult::Error,
-			}
-        }
+	impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber>
+		for Runtime
+	{
+		fn call(
+			origin: AccountId,
+			dest: AccountId,
+			value: Balance,
+			gas_limit: u64,
+			input_data: Vec<u8>,
+		) -> pallet_contracts_primitives::ContractExecResult {
+			Contracts::bare_call(origin, dest, value, gas_limit, input_data)
+		}
 
-        fn get_storage(
-            address: AccountId,
-            key: [u8; 32],
-        ) -> pallet_contracts_primitives::GetStorageResult {
-            Contracts::get_storage(address, key)
-        }
+		fn get_storage(
+			address: AccountId,
+			key: [u8; 32],
+		) -> pallet_contracts_primitives::GetStorageResult {
+			Contracts::get_storage(address, key)
+		}
 
-        fn rent_projection(
-            address: AccountId,
-        ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
-            Contracts::rent_projection(address)
-        }
-    }
+		fn rent_projection(
+			address: AccountId,
+		) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
+			Contracts::rent_projection(address)
+		}
+	}
 
     impl sp_api::Core<Block> for Runtime {
         fn version() -> RuntimeVersion {
@@ -637,12 +683,12 @@
 	}
 
 	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
-		fn query_info(
-			uxt: <Block as BlockT>::Extrinsic,
-			len: u32,
-		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
+		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
 			TransactionPayment::query_info(uxt, len)
 		}
+		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
+			TransactionPayment::query_fee_details(uxt, len)
+		}
 	}
 
     #[cfg(feature = "runtime-benchmarks")]
modifiedruntime_types.jsondiffbeforeafterboth
--- a/runtime_types.json
+++ b/runtime_types.json
@@ -115,6 +115,14 @@
       "SponsoredMintSize": "u32",
       "TokenLimit": "u32",
       "SponsorTimeout": "u32"
+    },
+    "AccountInfo": "AccountInfoWithProviders",
+    "AccountInfoWithProviders": {
+      "nonce": "Index",
+      "consumers": "RefCount",
+      "providers": "RefCount",
+      "data": "AccountData"
     }
+
   }
   
\ No newline at end of file