difftreelog
panic marcos removed
in: master
2 files changed
README.mddiffbeforeafterboth123# NFT Parachain45## Application Development67If you are building an application that operates NFT tokens, use [this document](doc/application_development.md).89## Building1011Building NFT chain requires special versions of Rust and toolchain. We don't use the most recent versions of everything so that we can keep the builds stable.12131. Install Rust:1415```bash16curl https://sh.rustup.rs -sSf | sh17sudo apt-get install libssl-dev pkg-config libclang-dev clang18```19202. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall <toolchain>`.21223. Install Rust Toolchain 1.44.0:2324```bash25rustup install 1.44.026```27284. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)29```bash30rustup toolchain list31rustup default 1.44.0-x86_64-unknown-linux-gnu32```33345. Install nightly toolchain and add wasm target for it:3536```bash37rustup toolchain install nightly-2020-05-0138rustup target add wasm32-unknown-unknown --toolchain nightly-2020-05-01-x86_64-unknown-linux-gnu39```40416. Build:42```bash43cargo build44```4546## Run4748You can start a development chain with:4950```bash51cargo run -- --dev52```5354Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.5556If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. Give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.5758We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN`, which is generated from the `--node-key` value that we specify below:5960```bash61cargo run -- \62 --base-path /tmp/alice \63 --chain=local \64 --alice \65 --node-key 0000000000000000000000000000000000000000000000000000000000000001 \66 --telemetry-url ws://telemetry.polkadot.io:1024 \67 --validator68```6970In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's bootnode ID on TCP port 30333:7172```bash73cargo run -- \74 --base-path /tmp/bob \75 --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \76 --chain=local \77 --bob \78 --port 30334 \79 --telemetry-url ws://telemetry.polkadot.io:1024 \80 --validator81```8283Additional CLI usage options are available and may be shown by running `cargo run -- --help`.848586## UI custom types87```88{89 "Schedule": {90 "version": "u32",91 "put_code_per_byte_cost": "Gas",92 "grow_mem_cost": "Gas",93 "regular_op_cost": "Gas",94 "return_data_per_byte_cost": "Gas",95 "event_data_per_byte_cost": "Gas",96 "event_per_topic_cost": "Gas",97 "event_base_cost": "Gas",98 "call_base_cost": "Gas",99 "instantiate_base_cost": "Gas",100 "dispatch_base_cost": "Gas",101 "sandbox_data_read_cost": "Gas",102 "sandbox_data_write_cost": "Gas",103 "transfer_cost": "Gas",104 "instantiate_cost": "Gas",105 "max_event_topics": "u32",106 "max_stack_height": "u32",107 "max_memory_pages": "u32",108 "max_table_size": "u32",109 "enable_println": "bool",110 "max_subject_len": "u32"111 },112 "CollectionMode": {113 "_enum": {114 "Invalid": null,115 "NFT": "u32",116 "Fungible": "u32",117 "ReFungible": "(u32, u32)"118 }119 },120 "Ownership": {121 "Owner": "AccountId",122 "Fraction": "u128"123 },124 "FungibleItemType": {125 "Collection": "u64",126 "Owner": "AccountId",127 "Value": "u128"128 },129 "ReFungibleItemType": {130 "Collection": "u64",131 "Owner": "Vec<Ownership>",132 "Data": "Vec<u8>"133 },134 "NftItemType": {135 "Collection": "u64",136 "Owner": "AccountId",137 "Data": "Vec<u8>"138 },139 "CollectionType": {140 "Owner": "AccountId",141 "Mode": "CollectionMode",142 "Access": "u8",143 "DecimalPoints": "u32",144 "Name": "Vec<u16>",145 "Description": "Vec<u16>",146 "TokenPrefix": "Vec<u8>",147 "CustomDataSize": "u32",148 "MintMode": "bool",149 "OffchainSchema": "Vec<u8>",150 "Sponsor": "AccountId",151 "UnconfirmedSponsor": "AccountId"152 },153 "RawData": "Vec<u8>",154 "Address": "AccountId",155 "LookupSource": "AccountId",156 "Weight": "u64"157}158```123# NFT Parachain45## Application Development67If you are building an application that operates NFT tokens, use [this document](doc/application_development.md).89## Building1011Building NFT chain requires special versions of Rust and toolchain. We don't use the most recent versions of everything so that we can keep the builds stable.12131. Install Rust:1415```bash16curl https://sh.rustup.rs -sSf | sh17sudo apt-get install libssl-dev pkg-config libclang-dev clang18```19202. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall <toolchain>`.21223. Install Rust Toolchain 1.44.0:2324```bash25rustup install 1.44.026```27284. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)29```bash30rustup toolchain list31rustup default 1.44.0-x86_64-unknown-linux-gnu32```33345. Install nightly toolchain and add wasm target for it:3536```bash37rustup toolchain install nightly-2020-05-0138rustup target add wasm32-unknown-unknown --toolchain nightly-2020-05-01-x86_64-unknown-linux-gnu39```40416. Build:42```bash43cargo build44```4546## Run4748You can start a development chain with:4950```bash51cargo run -- --dev52```5354Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.5556If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. Give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.5758We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN`, which is generated from the `--node-key` value that we specify below:5960```bash61cargo run -- \62 --base-path /tmp/alice \63 --chain=local \64 --alice \65 --node-key 0000000000000000000000000000000000000000000000000000000000000001 \66 --telemetry-url ws://telemetry.polkadot.io:1024 \67 --validator68```6970In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's bootnode ID on TCP port 30333:7172```bash73cargo run -- \74 --base-path /tmp/bob \75 --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \76 --chain=local \77 --bob \78 --port 30334 \79 --telemetry-url ws://telemetry.polkadot.io:1024 \80 --validator81```8283Additional CLI usage options are available and may be shown by running `cargo run -- --help`.848586## UI custom types87```88{89 "Schedule": {90 "version": "u32",91 "put_code_per_byte_cost": "Gas",92 "grow_mem_cost": "Gas",93 "regular_op_cost": "Gas",94 "return_data_per_byte_cost": "Gas",95 "event_data_per_byte_cost": "Gas",96 "event_per_topic_cost": "Gas",97 "event_base_cost": "Gas",98 "call_base_cost": "Gas",99 "instantiate_base_cost": "Gas",100 "dispatch_base_cost": "Gas",101 "sandbox_data_read_cost": "Gas",102 "sandbox_data_write_cost": "Gas",103 "transfer_cost": "Gas",104 "instantiate_cost": "Gas",105 "max_event_topics": "u32",106 "max_stack_height": "u32",107 "max_memory_pages": "u32",108 "max_table_size": "u32",109 "enable_println": "bool",110 "max_subject_len": "u32"111 },112 "AccessMode": {113 "_enum": [114 "Normal",115 "WhiteList"116 ]117 },118 "CollectionMode": {119 "_enum": {120 "Invalid": null,121 "NFT": "u32",122 "Fungible": "u32",123 "ReFungible": "(u32, u32)"124 }125 },126 "Ownership": {127 "Owner": "AccountId",128 "Fraction": "u128"129 },130 "FungibleItemType": {131 "Collection": "u64",132 "Owner": "AccountId",133 "Value": "u128"134 },135 "ReFungibleItemType": {136 "Collection": "u64",137 "Owner": "Vec<Ownership>",138 "Data": "Vec<u8>"139 },140 "NftItemType": {141 "Collection": "u64",142 "Owner": "AccountId",143 "Data": "Vec<u8>"144 },145 "CollectionType": {146 "Owner": "AccountId",147 "Mode": "CollectionMode",148 "Access": "AccessMode",149 "DecimalPoints": "u32",150 "Name": "Vec<u16>",151 "Description": "Vec<u16>",152 "TokenPrefix": "Vec<u8>",153 "CustomDataSize": "u32",154 "MintMode": "bool",155 "OffchainSchema": "Vec<u8>",156 "Sponsor": "AccountId",157 "UnconfirmedSponsor": "AccountId"158 },159 "RawData": "Vec<u8>",160 "Address": "AccountId",161 "LookupSource": "AccountId",162 "Weight": "u64"163}164165```pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -475,10 +475,7 @@
let target_collection = <Collection<T>>::get(collection_id);
if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {
- if target_collection.mint_mode == false {
- panic!("Collection is not in mint mode");
- }
-
+ ensure!(target_collection.mint_mode == true, "Collection is not in mint mode");
Self::check_white_list(collection_id, owner.clone())?;
}
@@ -628,26 +625,22 @@
let sender = ensure_signed(origin)?;
let approved_list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone()));
- if approved_list_exists
- {
- Self::check_white_list(collection_id, from.clone())?;
- Self::check_white_list(collection_id, recipient.clone())?;
- let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));
- let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());
- ensure!(opt_item.is_some(), "No approve found");
- ensure!(opt_item.unwrap().amount >= value, "Requested value more than approved");
+ ensure!(approved_list_exists, "Only approved addresses can call this method");
- // remove approve
- let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))
- .into_iter().filter(|i| i.approved != sender.clone()).collect();
- <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);
- }
- else
- {
- panic!("Only approved addresses can call this method");
- }
+ Self::check_white_list(collection_id, from.clone())?;
+ Self::check_white_list(collection_id, recipient.clone())?;
+ let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));
+ let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());
+ ensure!(opt_item.is_some(), "No approve found");
+ ensure!(opt_item.unwrap().amount >= value, "Requested value more than approved");
+
+ // remove approve
+ let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))
+ .into_iter().filter(|i| i.approved != sender.clone()).collect();
+ <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);
+
let target_collection = <Collection<T>>::get(collection_id);
match target_collection.mode
@@ -872,11 +865,8 @@
Self::collection_exists(collection_id)?;
let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());
- if result == true {
- Ok(())
- } else {
- panic!("You do not have permissions to modify this collection")
- }
+ ensure!(result, "You do not have permissions to modify this collection");
+ Ok(())
}
fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool {
@@ -902,15 +892,10 @@
fn check_white_list(collection_id: u64, address: T::AccountId) -> DispatchResult {
let mes = "Address is not in white list";
- if <WhiteList<T>>::contains_key(collection_id){
- let wl = <WhiteList<T>>::get(collection_id);
- if !wl.contains(&address.clone()) {
- panic!(mes);
- }
- }
- else {
- panic!(mes);
- }
+ ensure!(<WhiteList<T>>::contains_key(collection_id), mes);
+ let wl = <WhiteList<T>>::get(collection_id);
+ ensure!(wl.contains(&address.clone()), mes);
+
Ok(())
}