difftreelog
Offchain schema added
in: master
6 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3086,6 +3086,7 @@
"frame-support",
"frame-system",
"parity-scale-codec",
+ "serde",
"sp-core",
"sp-io",
"sp-runtime",
pallets/nft/Cargo.tomldiffbeforeafterboth--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -32,6 +32,10 @@
git = 'https://github.com/usetech-llc/substrate.git'
branch = 'rc4_ext_dispatch_reenabled'
version = '2.0.0-rc4'
+
+[dependencies]
+# third-party dependencies
+serde = { version = "1.0.102", features = ["derive"] }
[package]
authors = ['Substrate DevHub <https://github.com/substrate-developer-hub>']
@@ -49,6 +53,7 @@
default = ['std']
std = [
'codec/std',
+ "serde/std",
'frame-support/std',
'frame-system/std',
'sp-runtime/std',
pallets/nft/src/lib.rsdiffbeforeafterboth14#[cfg(test)]14#[cfg(test)]15mod tests;15mod tests;1617#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)]18pub enum CollectionMode {19 Invalid,20 // custom data size21 NFT(u32),22 // amount23 Fungible(u32),24 ReFungible,25}2627impl Into<u8> for CollectionMode {28 fn into(self) -> u8{29 match self {30 CollectionMode::Invalid => 0,31 CollectionMode::NFT(_) => 1,32 CollectionMode::Fungible(_) => 2,33 CollectionMode::ReFungible => 3,34 }35 }36}163717#[derive(Encode, Decode, Debug, Clone, PartialEq)]38#[derive(Encode, Decode, Debug, Clone, PartialEq)]18pub enum AccessMode {39pub enum AccessMode {21}42}22impl Default for AccessMode { fn default() -> Self { Self::Normal } }43impl Default for AccessMode { fn default() -> Self { Self::Normal } }234424#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)]25pub enum CollectionMode {26 Invalid,27 NFT,28 Fungible,29 ReFungible,30}31impl Default for CollectionMode { fn default() -> Self { Self::Invalid } }45impl Default for CollectionMode { fn default() -> Self { Self::Invalid } }324633#[derive(Encode, Decode, Default, Clone, PartialEq)]47#[derive(Encode, Decode, Default, Clone, PartialEq)]49 pub description: Vec<u16>, // 256 include null escape char63 pub description: Vec<u16>, // 256 include null escape char50 pub token_prefix: Vec<u8>, // 16 include null escape char64 pub token_prefix: Vec<u8>, // 16 include null escape char51 pub custom_data_size: u32,65 pub custom_data_size: u32,66 pub offchain_schema: Vec<u8>,67 pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender68 pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship52}69}537054#[derive(Encode, Decode, Default, Clone, PartialEq)]71#[derive(Encode, Decode, Default, Clone, PartialEq)]88decl_storage! {105decl_storage! {89 trait Store for Module<T: Trait> as Nft {106 trait Store for Module<T: Trait> as Nft {9010791 // Next available collection ID108 // Private members92 NextCollectionID get(fn next_collection_id): u64;109 NextCollectionID: u64;110 ItemListIndex: map hasher(blake2_128_concat) u64 => u64;11193 pub Collection get(fn collection): map hasher(identity) u64 => CollectionType<T::AccountId>;112 pub Collection get(fn collection): map hasher(identity) u64 => CollectionType<T::AccountId>;94 pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;113 pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;101 pub NftItemList get(fn nft_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;120 pub NftItemList get(fn nft_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;102 pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;121 pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;103 pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;122 pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;104 ItemListIndex get(fn item_index): map hasher(blake2_128_concat) u64 => u64;105123106 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;124 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;107 }125 }132 collection_name: Vec<u16>,150 collection_name: Vec<u16>,133 collection_description: Vec<u16>,151 collection_description: Vec<u16>,134 token_prefix: Vec<u8>,152 token_prefix: Vec<u8>,135 mode: u8,153 mode: CollectionMode) -> DispatchResult {136 decimal_points: u32,137 custom_data_size: u32) -> DispatchResult {138154139 // Anyone can create a collection155 // Anyone can create a collection140 let who = ensure_signed(origin)?;156 let who = ensure_signed(origin)?;141 let collection_mode: CollectionMode;157 let custom_data_size = match mode {142 match mode {143 1 => collection_mode = CollectionMode::NFT,158 CollectionMode::NFT(size) => size,144 2 => collection_mode = CollectionMode::Fungible,145 3 => collection_mode = CollectionMode::ReFungible,146 _ => collection_mode = CollectionMode::Invalid159 _ => 0147 }160 };148161149 // check type150 ensure!((collection_mode == CollectionMode::Fungible || collection_mode == CollectionMode::NFT || collection_mode == CollectionMode::ReFungible), 151 "Collection mode must be Fungible, NFT or ReFungible"); 152153 // NFT checks154 if collection_mode == CollectionMode::NFT155 {156 ensure!(decimal_points == 0, "Collection in NFT mode must have zero in decimal_points parameter"); 162 let decimal_points = match mode {157 }158159 // Fungible checks160 if collection_mode == CollectionMode::Fungible163 CollectionMode::Fungible(points) => points,161 {162 ensure!(custom_data_size == 0, "Collection in Fungible mode must have zero in custom_data_size parameter"); 163 ensure!(decimal_points != 0, "Collection in Fungible mode must have not zero in decimal_points parameter"); 164 _ => 0164 }165 };165166166 // check params167 // check params167 ensure!(decimal_points < 100, "decimal_points parameter must be lower than 100"); 168 ensure!(decimal_points < 100, "decimal_points parameter must be lower than 100"); 189 let new_collection = CollectionType {190 let new_collection = CollectionType {190 owner: who.clone(),191 owner: who.clone(),191 name: name,192 name: name,192 mode: collection_mode.clone(),193 mode: mode.clone(),193 access: AccessMode::Normal,194 access: AccessMode::Normal,194 description: description,195 description: description,195 decimal_points: decimal_points,196 decimal_points: decimal_points,196 token_prefix: prefix,197 token_prefix: prefix,197 next_item_id: next_id,198 next_item_id: next_id,199 offchain_schema: Vec::new(),198 custom_data_size: custom_data_size,200 custom_data_size: custom_data_size,201 sponsor: T::AccountId::default(),202 unconfirmed_sponsor: T::AccountId::default(),199 };203 };200204201 // Add new collection to map205 // Add new collection to map202 <Collection<T>>::insert(next_id, new_collection);206 <Collection<T>>::insert(next_id, new_collection);203207204 // call event208 // call event205 Self::deposit_event(RawEvent::Created(next_id, mode, who.clone()));209 Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));206210207 Ok(())211 Ok(())208 }212 }285 <Balance<T>>::insert(collection_id, owner.clone(), new_balance);289 <Balance<T>>::insert(collection_id, owner.clone(), new_balance);286290287 // TODO: implement other modes291 // TODO: implement other modes288 ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented");292 match target_collection.mode 289293 {290 if target_collection.mode == CollectionMode::NFT291 {294 CollectionMode::NFT(_) => {292 // Create nft item295 // Create nft item293 let item = NftItemType {296 let item = NftItemType {294 collection: collection_id,297 collection: collection_id,298301 299 Self::add_nft_item(item)?;302 Self::add_nft_item(item)?;303 300 }304 },305 _ => ()306 };301307302 // call event308 // call event303 Self::deposit_event(RawEvent::ItemCreated(collection_id, <ItemListIndex>::get(collection_id)));309 Self::deposit_event(RawEvent::ItemCreated(collection_id, <ItemListIndex>::get(collection_id)));336 let target_collection = <Collection<T>>::get(collection_id);342 let target_collection = <Collection<T>>::get(collection_id);337343338 // TODO: implement other modes344 // TODO: implement other modes339 ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented");345 match target_collection.mode 340346 {341 if target_collection.mode == CollectionMode::NFT342 {343 Self::transfer_nft(collection_id, item_id, recipient)?;347 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, recipient)?,344 }348 _ => ()349 };345350346 Ok(())351 Ok(())347 }352 }395 400 396 let target_collection = <Collection<T>>::get(collection_id);401 let target_collection = <Collection<T>>::get(collection_id);397402398 // TODO: implement other modes399 ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented");403 match target_collection.mode400404 {401 if target_collection.mode == CollectionMode::NFT402 {403 Self::transfer_nft(collection_id, item_id, recipient)?;405 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, recipient)?,404 }406 // TODO: implement other modes407 _ => ()408 };405409406 Ok(())410 Ok(())407 }411 }421 Ok(())425 Ok(())422 }426 }427428 #[weight = 0]429 pub fn set_offchain_schema(430 origin,431 collection_id: u64,432 schema: Vec<u8>433 ) -> DispatchResult {434 let sender = ensure_signed(origin)?;435 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;436 437 let mut target_collection = <Collection<T>>::get(collection_id);438 target_collection.offchain_schema = schema;439 <Collection<T>>::insert(collection_id, target_collection);440441 Ok(()) 442 }423 }443 }424}444}425445460480461 fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool{481 fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool{462482463 let mut result = false;464 let target_collection = <Collection<T>>::get(collection_id);483 let target_collection = <Collection<T>>::get(collection_id);465484466 if target_collection.mode == CollectionMode::NFT485 match target_collection.mode {467 {486 CollectionMode::NFT(_) => <NftItemList<T>>::get(collection_id, item_id).owner == subject,468 let item = <NftItemList<T>>::get(collection_id, item_id);469 result = item.owner == subject;470 }471472 if target_collection.mode == CollectionMode::Fungible487 CollectionMode::Fungible(_) => <FungibleItemList<T>>::get(collection_id, item_id).owner.contains(&subject),473 {474 let item = <FungibleItemList<T>>::get(collection_id, item_id);475 result = item.owner.contains(&subject);476 }477478 if target_collection.mode == CollectionMode::ReFungible488 CollectionMode::ReFungible => <ReFungibleItemList<T>>::get(collection_id, item_id).owner.iter().any(|i| i.owner == subject),479 {489 CollectionMode::Invalid => false480 let item = <ReFungibleItemList<T>>::get(collection_id, item_id);490 }481 result = item.owner.iter().any(|i| i.owner == subject);482 }483484 result485 }491 }486492487 fn add_nft_item(item: NftItemType<T::AccountId>) -> DispatchResult {493 fn add_nft_item(item: NftItemType<T::AccountId>) -> DispatchResult {smart_contract/ink-types-node-runtime/README.mddiffbeforeafterboth--- a/smart_contract/ink-types-node-runtime/README.md
+++ b/smart_contract/ink-types-node-runtime/README.md
@@ -30,4 +30,67 @@
## Test
```
cargo +nightly test
+```
+
+## UI custom types
+```
+{
+ "Schedule": {
+ "version": "u32",
+ "put_code_per_byte_cost": "Gas",
+ "grow_mem_cost": "Gas",
+ "regular_op_cost": "Gas",
+ "return_data_per_byte_cost": "Gas",
+ "event_data_per_byte_cost": "Gas",
+ "event_per_topic_cost": "Gas",
+ "event_base_cost": "Gas",
+ "call_base_cost": "Gas",
+ "instantiate_base_cost": "Gas",
+ "dispatch_base_cost": "Gas",
+ "sandbox_data_read_cost": "Gas",
+ "sandbox_data_write_cost": "Gas",
+ "transfer_cost": "Gas",
+ "instantiate_cost": "Gas",
+ "max_event_topics": "u32",
+ "max_stack_height": "u32",
+ "max_memory_pages": "u32",
+ "max_table_size": "u32",
+ "enable_println": "bool",
+ "max_subject_len": "u32"
+ },
+ "CollectionMode": {
+ "_enum": {
+ "Invalid": null,
+ "NFT": "u32",
+ "Fungible": "u32",
+ "ReFungible": null
+ }
+ },
+ "NftItemType": {
+ "Collection": "u64",
+ "Owner": "AccountId",
+ "Data": "Vec<u8>"
+ },
+
+
+"CollectionType": {
+ "Owner": "AccountId",
+ "Mode": "u8",
+ "ModeParam": "u32",
+ "Access": "u8",
+ "NextItemId": "u64",
+ "DecimalPoints": "u32",
+ "Name": "Vec<u16>",
+ "Description": "Vec<u16>",
+ "TokenPrefix": "Vec<u8>",
+ "CustomDataSize": "u32",
+ "OffchainSchema": "Vec<u8>",
+ "Sponsor": "AccountId",
+ "UnconfirmedSponsor": "AccountId"
+ },
+ "RawData": "Vec<u8>",
+ "Address": "AccountId",
+ "LookupSource": "AccountId",
+ "Weight": "u64"
+}
```
\ No newline at end of file
smart_contract/ink-types-node-runtime/calls/lib.rsdiffbeforeafterboth--- a/smart_contract/ink-types-node-runtime/calls/lib.rs
+++ b/smart_contract/ink-types-node-runtime/calls/lib.rs
@@ -123,15 +123,14 @@
}
// SafeTransferFrom
-
#[ink(message)]
- fn create_item(&self, collection_id: u64, properties: Vec<u8>) {
+ fn create_item(&self, collection_id: u64, properties: Vec<u8>, owner: AccountId) {
env::println(&format!(
"create_item invoke_runtime params {:?}, {:?} ",
collection_id, properties
));
- let create_item_call = runtime_calls::create_item(collection_id, properties);
+ let create_item_call = runtime_calls::create_item(collection_id, properties, owner);
// dispatch the call to the runtime
let result = self.env().invoke_runtime(&create_item_call);
smart_contract/ink-types-node-runtime/src/calls.rsdiffbeforeafterboth--- a/smart_contract/ink-types-node-runtime/src/calls.rs
+++ b/smart_contract/ink-types-node-runtime/src/calls.rs
@@ -25,7 +25,7 @@
T::AccountId: Member + Codec,
{
#[allow(non_camel_case_types)]
- create_collection(Vec<u16>, Vec<u16>, Vec<u8>, u32),
+ create_collection(Vec<u16>, Vec<u16>, Vec<u8>, u8, u32, u32),
#[allow(non_camel_case_types)]
destroy_collection(u64),
@@ -40,19 +40,19 @@
remove_collection_admin(u64, T::AccountId),
#[allow(non_camel_case_types)]
- create_item(u64, Vec<u8>),
+ create_item(u64, Vec<u8>, T::AccountId),
#[allow(non_camel_case_types)]
burn_item(u64, u64),
#[allow(non_camel_case_types)]
- transfer(u64, u64, T::AccountId),
+ transfer(T::AccountId, u64, u64),
#[allow(non_camel_case_types)]
nft_approve(T::AccountId, u64, u64),
#[allow(non_camel_case_types)]
- nft_transfer_from(u64, u64, T::AccountId),
+ nft_transfer_from(T::AccountId, u64, u64),
#[allow(non_camel_case_types)]
nft_safe_transfer(u64, u64, T::AccountId),
@@ -66,13 +66,17 @@
collection_name: Vec<u16>,
collection_description: Vec<u16>,
token_prefix: Vec<u8>,
- custom_data_sz: u32,
+ mode: u8,
+ decimal_points: u32,
+ custom_data_size: u32,
) -> Call {
Nft::<NodeRuntimeTypes>::create_collection(
collection_name,
collection_description,
token_prefix,
- custom_data_sz,
+ mode,
+ decimal_points,
+ custom_data_size,
)
.into()
}
@@ -89,8 +93,8 @@
Nft::<NodeRuntimeTypes>::nft_transfer_from(collection_id, item_id, new_owner.into()).into()
}
-pub fn create_item(collection_id: u64, properties: Vec<u8>) -> Call {
- Nft::<NodeRuntimeTypes>::create_item(collection_id, properties).into()
+pub fn create_item(collection_id: u64, properties: Vec<u8>, owner: AccountId) -> Call {
+ Nft::<NodeRuntimeTypes>::create_item(collection_id, properties, owner).into()
}
pub fn burn_item(collection_id: u64, item_id: u64) -> Call {