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.tomldiffbeforeafterboth33branch = 'rc4_ext_dispatch_reenabled'33branch = 'rc4_ext_dispatch_reenabled'34version = '2.0.0-rc4'34version = '2.0.0-rc4'35 36[dependencies]37# third-party dependencies38serde = { version = "1.0.102", features = ["derive"] }353936[package]40[package]37authors = ['Substrate DevHub <https://github.com/substrate-developer-hub>']41authors = ['Substrate DevHub <https://github.com/substrate-developer-hub>']49default = ['std']53default = ['std']50std = [54std = [51 'codec/std',55 'codec/std',56 "serde/std",52 'frame-support/std',57 'frame-support/std',53 'frame-system/std',58 'frame-system/std',54 'sp-runtime/std',59 'sp-runtime/std',pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -14,6 +14,27 @@
#[cfg(test)]
mod tests;
+#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)]
+pub enum CollectionMode {
+ Invalid,
+ // custom data size
+ NFT(u32),
+ // amount
+ Fungible(u32),
+ ReFungible,
+}
+
+impl Into<u8> for CollectionMode {
+ fn into(self) -> u8{
+ match self {
+ CollectionMode::Invalid => 0,
+ CollectionMode::NFT(_) => 1,
+ CollectionMode::Fungible(_) => 2,
+ CollectionMode::ReFungible => 3,
+ }
+ }
+}
+
#[derive(Encode, Decode, Debug, Clone, PartialEq)]
pub enum AccessMode {
Normal,
@@ -21,13 +42,6 @@
}
impl Default for AccessMode { fn default() -> Self { Self::Normal } }
-#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)]
-pub enum CollectionMode {
- Invalid,
- NFT,
- Fungible,
- ReFungible,
-}
impl Default for CollectionMode { fn default() -> Self { Self::Invalid } }
#[derive(Encode, Decode, Default, Clone, PartialEq)]
@@ -49,6 +63,9 @@
pub description: Vec<u16>, // 256 include null escape char
pub token_prefix: Vec<u8>, // 16 include null escape char
pub custom_data_size: u32,
+ pub offchain_schema: Vec<u8>,
+ pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender
+ pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship
}
#[derive(Encode, Decode, Default, Clone, PartialEq)]
@@ -88,8 +105,10 @@
decl_storage! {
trait Store for Module<T: Trait> as Nft {
- // Next available collection ID
- NextCollectionID get(fn next_collection_id): u64;
+ // Private members
+ NextCollectionID: u64;
+ ItemListIndex: map hasher(blake2_128_concat) u64 => u64;
+
pub Collection get(fn collection): map hasher(identity) u64 => CollectionType<T::AccountId>;
pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;
@@ -101,7 +120,6 @@
pub NftItemList get(fn nft_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;
pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;
pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;
- ItemListIndex get(fn item_index): map hasher(blake2_128_concat) u64 => u64;
pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;
}
@@ -132,36 +150,19 @@
collection_name: Vec<u16>,
collection_description: Vec<u16>,
token_prefix: Vec<u8>,
- mode: u8,
- decimal_points: u32,
- custom_data_size: u32) -> DispatchResult {
+ mode: CollectionMode) -> DispatchResult {
// Anyone can create a collection
let who = ensure_signed(origin)?;
- let collection_mode: CollectionMode;
- match mode {
- 1 => collection_mode = CollectionMode::NFT,
- 2 => collection_mode = CollectionMode::Fungible,
- 3 => collection_mode = CollectionMode::ReFungible,
- _ => collection_mode = CollectionMode::Invalid
- }
-
- // check type
- ensure!((collection_mode == CollectionMode::Fungible || collection_mode == CollectionMode::NFT || collection_mode == CollectionMode::ReFungible),
- "Collection mode must be Fungible, NFT or ReFungible");
-
- // NFT checks
- if collection_mode == CollectionMode::NFT
- {
- ensure!(decimal_points == 0, "Collection in NFT mode must have zero in decimal_points parameter");
- }
+ let custom_data_size = match mode {
+ CollectionMode::NFT(size) => size,
+ _ => 0
+ };
- // Fungible checks
- if collection_mode == CollectionMode::Fungible
- {
- ensure!(custom_data_size == 0, "Collection in Fungible mode must have zero in custom_data_size parameter");
- ensure!(decimal_points != 0, "Collection in Fungible mode must have not zero in decimal_points parameter");
- }
+ let decimal_points = match mode {
+ CollectionMode::Fungible(points) => points,
+ _ => 0
+ };
// check params
ensure!(decimal_points < 100, "decimal_points parameter must be lower than 100");
@@ -189,20 +190,23 @@
let new_collection = CollectionType {
owner: who.clone(),
name: name,
- mode: collection_mode.clone(),
+ mode: mode.clone(),
access: AccessMode::Normal,
description: description,
decimal_points: decimal_points,
token_prefix: prefix,
next_item_id: next_id,
+ offchain_schema: Vec::new(),
custom_data_size: custom_data_size,
+ sponsor: T::AccountId::default(),
+ unconfirmed_sponsor: T::AccountId::default(),
};
// Add new collection to map
<Collection<T>>::insert(next_id, new_collection);
// call event
- Self::deposit_event(RawEvent::Created(next_id, mode, who.clone()));
+ Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));
Ok(())
}
@@ -285,19 +289,21 @@
<Balance<T>>::insert(collection_id, owner.clone(), new_balance);
// TODO: implement other modes
- ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented");
-
- if target_collection.mode == CollectionMode::NFT
+ match target_collection.mode
{
+ CollectionMode::NFT(_) => {
// Create nft item
- let item = NftItemType {
- collection: collection_id,
- owner: owner,
- data: properties,
- };
-
- Self::add_nft_item(item)?;
- }
+ let item = NftItemType {
+ collection: collection_id,
+ owner: owner,
+ data: properties,
+ };
+
+ Self::add_nft_item(item)?;
+
+ },
+ _ => ()
+ };
// call event
Self::deposit_event(RawEvent::ItemCreated(collection_id, <ItemListIndex>::get(collection_id)));
@@ -336,12 +342,11 @@
let target_collection = <Collection<T>>::get(collection_id);
// TODO: implement other modes
- ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented");
-
- if target_collection.mode == CollectionMode::NFT
+ match target_collection.mode
{
- Self::transfer_nft(collection_id, item_id, recipient)?;
- }
+ CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, recipient)?,
+ _ => ()
+ };
Ok(())
}
@@ -395,13 +400,12 @@
let target_collection = <Collection<T>>::get(collection_id);
- // TODO: implement other modes
- ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented");
-
- if target_collection.mode == CollectionMode::NFT
+ match target_collection.mode
{
- Self::transfer_nft(collection_id, item_id, recipient)?;
- }
+ CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, recipient)?,
+ // TODO: implement other modes
+ _ => ()
+ };
Ok(())
}
@@ -420,6 +424,22 @@
Ok(())
}
+
+ #[weight = 0]
+ pub fn set_offchain_schema(
+ origin,
+ collection_id: u64,
+ schema: Vec<u8>
+ ) -> DispatchResult {
+ let sender = ensure_signed(origin)?;
+ Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
+
+ let mut target_collection = <Collection<T>>::get(collection_id);
+ target_collection.offchain_schema = schema;
+ <Collection<T>>::insert(collection_id, target_collection);
+
+ Ok(())
+ }
}
}
@@ -460,28 +480,14 @@
fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool{
- let mut result = false;
let target_collection = <Collection<T>>::get(collection_id);
- if target_collection.mode == CollectionMode::NFT
- {
- let item = <NftItemList<T>>::get(collection_id, item_id);
- result = item.owner == subject;
- }
-
- if target_collection.mode == CollectionMode::Fungible
- {
- let item = <FungibleItemList<T>>::get(collection_id, item_id);
- result = item.owner.contains(&subject);
- }
-
- if target_collection.mode == CollectionMode::ReFungible
- {
- let item = <ReFungibleItemList<T>>::get(collection_id, item_id);
- result = item.owner.iter().any(|i| i.owner == subject);
+ match target_collection.mode {
+ CollectionMode::NFT(_) => <NftItemList<T>>::get(collection_id, item_id).owner == subject,
+ CollectionMode::Fungible(_) => <FungibleItemList<T>>::get(collection_id, item_id).owner.contains(&subject),
+ CollectionMode::ReFungible => <ReFungibleItemList<T>>::get(collection_id, item_id).owner.iter().any(|i| i.owner == subject),
+ CollectionMode::Invalid => false
}
-
- result
}
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 {