--- a/smart_contracs/transfer/Cargo.toml +++ b/smart_contracs/transfer/Cargo.toml @@ -4,15 +4,17 @@ authors = ["[Greg Zaitsev] <[your_email]>"] edition = "2018" +[workspace] + [dependencies] -ink_primitives = { git = "https://github.com/usetech-llc/ink", branch = "unique", default-features = false } -ink_metadata = { git = "https://github.com/usetech-llc/ink", branch = "unique", default-features = false, features = ["derive"], optional = true } -ink_env = { git = "https://github.com/usetech-llc/ink", branch = "unique", default-features = false } -ink_storage = { git = "https://github.com/usetech-llc/ink", branch = "unique", default-features = false } -ink_lang = { git = "https://github.com/usetech-llc/ink", branch = "unique", default-features = false } +ink_primitives = { default-features = false } +ink_metadata = { default-features = false, features = ["derive"], optional = true } +ink_env = { default-features = false } +ink_storage = { default-features = false } +ink_lang = { default-features = false } -scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.4.1", default-features = false, features = ["derive"], optional = true } +scale = { package = "parity-scale-codec", version = "2.1.1", default-features = false, features = ["derive"] } +scale-info = { version = "0.6.0", default-features = false, features = ["derive"] } [lib] name = "nft_transfer" @@ -28,6 +30,7 @@ "ink_metadata/std", "ink_env/std", "ink_storage/std", + "ink_lang/std", "ink_primitives/std", "scale/std", "scale-info/std", --- a/smart_contracs/transfer/lib.rs +++ b/smart_contracs/transfer/lib.rs @@ -1,4 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; +use alloc::vec::Vec; use ink_lang as ink; use ink_env::{Environment, DefaultEnvironment}; @@ -36,6 +38,24 @@ } } +#[derive(scale::Encode, scale::Decode, scale_info::TypeInfo)] +pub enum CreateItemData { + Nft { + const_data: Vec, + variable_data: Vec, + }, + Fungible { + value: u128, + }, + ReFungible { + const_data: Vec, + variable_data: Vec, + pieces: u128, + }, +} + +type DefaultAccountId = ::AccountId; + #[ink::chain_extension] pub trait NftChainExtension { type ErrorCode = NftErrorCode; @@ -43,11 +63,26 @@ /// Transfer one NFT token from sender /// #[ink(extension = 0, returns_result = false)] - fn transfer(recipient: ::AccountId, collection_id: u32, token_id: u32, amount: u128); + fn transfer(recipient: DefaultAccountId, collection_id: u32, token_id: u32, amount: u128); + #[ink(extension = 1, returns_result = false)] + fn create_item(owner: DefaultAccountId, collection_id: u32, data: CreateItemData); + #[ink(extension = 2, returns_result = false)] + fn create_multiple_items(owner: DefaultAccountId, collection_id: u32, data: Vec); + #[ink(extension = 3, returns_result = false)] + fn approve(spender: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128); + #[ink(extension = 4, returns_result = false)] + fn transfer_from(owner: DefaultAccountId, recipient: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128); + #[ink(extension = 5, returns_result = false)] + fn set_variable_meta_data(collection_id: u32, item_id: u32, data: Vec); + #[ink(extension = 6, returns_result = false)] + fn toggle_white_list(collection_id: u32, address: DefaultAccountId, whitelisted: bool); } -#[ink::contract(env = crate::NftEnvironment)] +#[ink::contract(env = crate::NftEnvironment, dynamic_storage_allocator = true)] mod nft_transfer { + use alloc::vec::Vec; + // use ink_storage::Vec; + use crate::CreateItemData; #[ink(storage)] pub struct NftTransfer { @@ -69,6 +104,42 @@ .extension() .transfer(recipient, collection_id, token_id, amount); } + #[ink(message)] + pub fn create_item(&mut self, recipient: AccountId, collection_id: u32, data: CreateItemData) { + let _ = self.env() + .extension() + .create_item(recipient, collection_id, data); + } + #[ink(message)] + pub fn create_multiple_items(&mut self, owner: AccountId, collection_id: u32, data: Vec) { + let _ = self.env() + .extension() + .create_multiple_items(owner, collection_id, data); + } + #[ink(message)] + pub fn approve(&mut self, spender: AccountId, collection_id: u32, item_id: u32, amount: u128) { + let _ = self.env() + .extension() + .approve(spender, collection_id, item_id, amount); + } + #[ink(message)] + pub fn transfer_from(&mut self, owner: AccountId, recipient: AccountId, collection_id: u32, item_id: u32, amount: u128) { + let _ = self.env() + .extension() + .transfer_from(owner, recipient, collection_id, item_id, amount); + } + #[ink(message)] + pub fn set_variable_meta_data(&mut self, collection_id: u32, item_id: u32, data: Vec) { + let _ = self.env() + .extension() + .set_variable_meta_data(collection_id, item_id, data); + } + #[ink(message)] + pub fn toggle_white_list(&mut self, collection_id: u32, address: AccountId, whitelisted: bool) { + let _ = self.env() + .extension() + .toggle_white_list(collection_id, address, whitelisted); + } } --- a/tests/src/transfer_contract/metadata.json +++ b/tests/src/transfer_contract/metadata.json @@ -1,9 +1,9 @@ { "metadataVersion": "0.1.0", "source": { - "hash": "0xfbbc0729acefed9d99f93f6cbb751d12e317958fd0fe183f5781329b37f1bf6e", - "language": "ink! 3.0.0-rc2", - "compiler": "rustc 1.51.0-nightly" + "hash": "0xc6c3f47adeafe86d1674ed72c7179605787842f2f05a2d7da0dbabf3c4fa1aa8", + "language": "ink! 3.0.0-rc3", + "compiler": "rustc 1.52.0-nightly" }, "contract": { "name": "nft_transfer", @@ -24,7 +24,7 @@ "name": [ "default" ], - "selector": "0x6a3712e2" + "selector": "0xed4b9d1b" } ], "docs": [], @@ -78,7 +78,268 @@ ], "payable": false, "returnType": null, - "selector": "0xfae3a09d" + "selector": "0x84a15da1" + }, + { + "args": [ + { + "name": "recipient", + "type": { + "displayName": [ + "AccountId" + ], + "type": 1 + } + }, + { + "name": "collection_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "data", + "type": { + "displayName": [ + "CreateItemData" + ], + "type": 6 + } + } + ], + "docs": [], + "mutates": true, + "name": [ + "create_item" + ], + "payable": false, + "returnType": null, + "selector": "0xd7c3f083" + }, + { + "args": [ + { + "name": "owner", + "type": { + "displayName": [ + "AccountId" + ], + "type": 1 + } + }, + { + "name": "collection_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "data", + "type": { + "displayName": [ + "Vec" + ], + "type": 8 + } + } + ], + "docs": [], + "mutates": true, + "name": [ + "create_multiple_items" + ], + "payable": false, + "returnType": null, + "selector": "0x15f9a1eb" + }, + { + "args": [ + { + "name": "spender", + "type": { + "displayName": [ + "AccountId" + ], + "type": 1 + } + }, + { + "name": "collection_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "item_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "amount", + "type": { + "displayName": [ + "u128" + ], + "type": 5 + } + } + ], + "docs": [], + "mutates": true, + "name": [ + "approve" + ], + "payable": false, + "returnType": null, + "selector": "0x681266a0" + }, + { + "args": [ + { + "name": "owner", + "type": { + "displayName": [ + "AccountId" + ], + "type": 1 + } + }, + { + "name": "recipient", + "type": { + "displayName": [ + "AccountId" + ], + "type": 1 + } + }, + { + "name": "collection_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "item_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "amount", + "type": { + "displayName": [ + "u128" + ], + "type": 5 + } + } + ], + "docs": [], + "mutates": true, + "name": [ + "transfer_from" + ], + "payable": false, + "returnType": null, + "selector": "0x0b396f18" + }, + { + "args": [ + { + "name": "collection_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "item_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "data", + "type": { + "displayName": [ + "Vec" + ], + "type": 7 + } + } + ], + "docs": [], + "mutates": true, + "name": [ + "set_variable_meta_data" + ], + "payable": false, + "returnType": null, + "selector": "0xb0b26da2" + }, + { + "args": [ + { + "name": "collection_id", + "type": { + "displayName": [ + "u32" + ], + "type": 4 + } + }, + { + "name": "address", + "type": { + "displayName": [ + "AccountId" + ], + "type": 1 + } + }, + { + "name": "whitelisted", + "type": { + "displayName": [ + "bool" + ], + "type": 9 + } + } + ], + "docs": [], + "mutates": true, + "name": [ + "toggle_white_list" + ], + "payable": false, + "returnType": null, + "selector": "0x98574dac" } ] }, @@ -93,7 +354,8 @@ "composite": { "fields": [ { - "type": 2 + "type": 2, + "typeName": "[u8; 32]" } ] } @@ -126,6 +388,82 @@ "def": { "primitive": "u128" } + }, + { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "name": "const_data", + "type": 7, + "typeName": "Vec" + }, + { + "name": "variable_data", + "type": 7, + "typeName": "Vec" + } + ], + "name": "Nft" + }, + { + "fields": [ + { + "name": "value", + "type": 5, + "typeName": "u128" + } + ], + "name": "Fungible" + }, + { + "fields": [ + { + "name": "const_data", + "type": 7, + "typeName": "Vec" + }, + { + "name": "variable_data", + "type": 7, + "typeName": "Vec" + }, + { + "name": "pieces", + "type": 5, + "typeName": "u128" + } + ], + "name": "ReFungible" + } + ] + } + }, + "path": [ + "nft_transfer", + "CreateItemData" + ] + }, + { + "def": { + "sequence": { + "type": 3 + } + } + }, + { + "def": { + "sequence": { + "type": 6 + } + } + }, + { + "def": { + "primitive": "bool" + } } ] } \ No newline at end of file