@@ -100,31 +100,9 @@ pub mod pallet {
100100 ) -> DispatchResult {
101101 let owner = ensure_signed ( origin. clone ( ) ) ?;
102102
103- let new_cnt =
104- Self :: frunique_cnt ( ) . checked_add ( 1 ) . ok_or ( <Error < T > >:: FruniqueCntOverflow ) ?;
105103 // create an NFT in the uniques pallet
106- pallet_uniques:: Pallet :: < T > :: create ( origin. clone ( ) , class_id. clone ( ) , admin. clone ( ) ) ?;
107- pallet_uniques:: Pallet :: < T > :: mint (
108- origin. clone ( ) ,
109- class_id. clone ( ) ,
110- instance_id. clone ( ) ,
111- admin. clone ( ) ,
112- ) ?;
113- <FruniqueCnt < T > >:: put ( new_cnt) ;
114- if let Some ( n) = numeric_value {
115- let num_value_key =
116- BoundedVec :: < u8 , T :: KeyLimit > :: try_from ( r#"num_value"# . encode ( ) )
117- . expect ( "Error on encoding the numeric value key to BoundedVec" ) ;
118- let num_value = BoundedVec :: < u8 , T :: ValueLimit > :: try_from ( n. encode ( ) )
119- . expect ( "Error on encoding the numeric value to BoundedVec" ) ;
120- pallet_uniques:: Pallet :: < T > :: set_attribute (
121- origin. clone ( ) ,
122- class_id,
123- Some ( instance_id) ,
124- num_value_key,
125- num_value,
126- ) ?;
127- }
104+ Self :: do_create ( origin. clone ( ) , class_id, instance_id, numeric_value, admin. clone ( ) ) ?;
105+
128106 let admin = T :: Lookup :: lookup ( admin) ?;
129107 Self :: deposit_event ( Event :: FruniqueCreated ( owner, admin, class_id, instance_id) ) ;
130108
@@ -182,6 +160,49 @@ pub mod pallet {
182160 Ok ( ( ) )
183161 }
184162
163+ /// ## Create a frunique with given attributes.
164+ /// `origin` must be signed by the owner of the frunique.
165+ /// - `attributes` must be a list of pairs of `key` and `value`.
166+ /// `key` must be a valid key for the asset class.
167+ /// `value` must be a valid value for the asset class.
168+ /// `attributes` must not be empty.
169+ /// - `instance_id` must be a valid instance of the asset class.
170+ /// - `class_id` must be a valid class of the asset class.
171+ /// - `numeric_value` must be a valid value for the asset class.
172+ /// - `admin` must be a valid admin of the asset class.
173+ /// - `instance_id` must not be already in use.
174+ /// - `class_id` must not be already in use.
175+ /// - `numeric_value` must not be already in use.
176+ #[ pallet:: weight( 10_000 + T :: DbWeight :: get( ) . writes( 1 ) ) ]
177+ pub fn create_with_attributes (
178+ origin : OriginFor < T > ,
179+ class_id : T :: CollectionId ,
180+ instance_id : T :: ItemId ,
181+ numeric_value : Option < Permill > ,
182+ admin : <T :: Lookup as sp_runtime:: traits:: StaticLookup >:: Source ,
183+ attributes : Vec < ( BoundedVec < u8 , T :: KeyLimit > , BoundedVec < u8 , T :: ValueLimit > ) > ,
184+ ) -> DispatchResult {
185+ // ! Ensure the admin is the one who can add attributes to the frunique.
186+ ensure ! ( !attributes. is_empty( ) , Error :: <T >:: AttributesEmpty ) ;
187+
188+ let owner = ensure_signed ( origin. clone ( ) ) ?;
189+ // create an NFT in the uniques pallet
190+ Self :: do_create ( origin. clone ( ) , class_id, instance_id, numeric_value, admin. clone ( ) ) ?;
191+ for attribute in & attributes {
192+ Self :: set_attribute (
193+ origin. clone ( ) ,
194+ & class_id. clone ( ) ,
195+ Self :: u32_to_instance_id ( instance_id. clone ( ) ) ,
196+ attribute. 0 . clone ( ) ,
197+ attribute. 1 . clone ( ) ,
198+ ) ?;
199+ }
200+
201+ let admin = T :: Lookup :: lookup ( admin) ?;
202+ Self :: deposit_event ( Event :: FruniqueCreated ( owner, admin, class_id, instance_id) ) ;
203+ Ok ( ( ) )
204+ }
205+
185206 /// ## NFT Division
186207 ///
187208 /// PD: the Key/value length limits are inherited from the uniques pallet,
@@ -213,21 +234,14 @@ pub mod pallet {
213234 // Boilerplate (setup, conversions, ensure_signed)
214235 let owner = ensure_signed ( origin. clone ( ) ) ?;
215236 let encoded_id = instance_id. encode ( ) ;
216- let new_cnt =
217- Self :: frunique_cnt ( ) . checked_add ( 1 ) . ok_or ( <Error < T > >:: FruniqueCntOverflow ) ?;
218237 // TODO: Check if the instance_id exists?
219238 let parent_id_key = BoundedVec :: < u8 , T :: KeyLimit > :: try_from ( r#"parent_id"# . encode ( ) )
220239 . expect ( "Error on encoding the parent_id key to BoundedVec" ) ;
221240 let mut parent_id_val: BoundedVec < u8 , T :: ValueLimit > ;
222241 // Instance n number of nfts (with the respective parentId)
223242 let new_instance_id = Self :: frunique_cnt ( ) . try_into ( ) . unwrap ( ) ;
224243 // Mint a unique
225- pallet_uniques:: Pallet :: < T > :: mint (
226- origin. clone ( ) ,
227- class_id,
228- new_instance_id,
229- admin. clone ( ) ,
230- ) ?;
244+ Self :: mint ( origin. clone ( ) , & class_id, new_instance_id, admin. clone ( ) ) ?;
231245 // Set the respective attributtes
232246 if inherit_attrs {
233247 // TODO: Check all the parent's instance attributes
@@ -253,10 +267,10 @@ pub mod pallet {
253267 BoundedVec :: < u8 , T :: KeyLimit > :: try_from ( r#"num_value"# . encode ( ) )
254268 . expect ( "Error on encoding the num_value key to BoundedVec" ) ;
255269 // TODO: Call bytes_to_u32 & divide the numeric value before setting it
256- pallet_uniques :: Pallet :: < T > :: set_attribute (
270+ Self :: set_attribute (
257271 origin. clone ( ) ,
258- class_id,
259- Some ( Self :: u32_to_instance_id ( new_instance_id) ) ,
272+ & class_id,
273+ Self :: u32_to_instance_id ( new_instance_id) ,
260274 num_value_key,
261275 num_value,
262276 ) ?;
@@ -279,21 +293,31 @@ pub mod pallet {
279293 . expect ( "Error on converting the parent_id to BoundedVec" ) ;
280294 }
281295 // (for encoding reasons the parentId is stored on hex format as a secondary side-effect, I hope it's not too much of a problem).
282- pallet_uniques :: Pallet :: < T > :: set_attribute (
296+ Self :: set_attribute (
283297 origin. clone ( ) ,
284- class_id,
285- Some ( Self :: u32_to_instance_id ( new_instance_id) ) ,
298+ & class_id,
299+ Self :: u32_to_instance_id ( new_instance_id) ,
286300 parent_id_key,
287301 parent_id_val,
288302 ) ?;
289303 let _e = Self :: instance_exists ( origin, class_id, instance_id) ;
290304 //let final_test = pallet_uniques::Pallet::<T>::attribute(&class_id, &Self::u16_to_instance_id(new_instance_id ), &r#"parent_id"#.encode() );
291305 //println!("The parent_id of {} is now {:?}",new_instance_id, Self::bytes_to_u32(final_test.unwrap()) );
292- <FruniqueCnt < T > >:: put ( new_cnt) ;
293306 // TODO: set the divided value attribute. Numbers, divisions and floating points are giving a lot of problems
294307 let admin = T :: Lookup :: lookup ( admin) ?;
295308 Self :: deposit_event ( Event :: FruniqueDivided ( owner, admin, class_id, instance_id) ) ;
296309 // Freeze the nft to prevent trading it? Burn it? Not clear, so nothing at the moment
310+ // Freeze parent
311+
312+ // unique -> n parts of parent
313+ // unique is freezed
314+ // 1, 2, 3, 4, ..., n
315+ // alice 1 & bob 1 & carol 1 & ... & n
316+ // (n - 5) -> m parts of parent
317+ // m parts of the new frunique
318+ // n
319+
320+
297321 Ok ( ( ) )
298322 }
299323 }
0 commit comments