git.delta.rocks / unique-network / refs/commits / 0c121c74a848

difftreelog

feat add a way to split RFT between multiple owners on mint

Grigoriy Simonov2023-09-22parent: #9425c0a.patch.diff
in: master

12 files changed

modifiedpallets/common/src/eth.rsdiffbeforeafterboth
632 }632 }
633}633}
634
635/// Token minting parameters
636#[derive(AbiCoder, Default, Debug)]
637pub struct MintTokenData {
638 /// Minted token owner
639 pub owner: CrossAddress,
640 /// Minted token properties
641 pub properties: Vec<Property>,
642}
643634
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
26 char::{REPLACEMENT_CHARACTER, decode_utf16},26 char::{REPLACEMENT_CHARACTER, decode_utf16},
27 convert::TryInto,27 convert::TryInto,
28};28};
29use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};29use evm_coder::{abi::AbiType, AbiCoder, ToLog, generate_stubgen, solidity_interface, types::*};
30use frame_support::BoundedVec;30use frame_support::BoundedVec;
31use up_data_structs::{31use up_data_structs::{
32 TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId, PropertyKey,32 TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId, PropertyKey,
64 },64 },
65}65}
66
67/// Token minting parameters
68#[derive(AbiCoder, Default, Debug)]
69pub struct MintTokenData {
70 /// Minted token owner
71 pub owner: eth::CrossAddress,
72 /// Minted token properties
73 pub properties: Vec<eth::Property>,
74}
6675
67frontier_contract! {76frontier_contract! {
68 macro_rules! NonfungibleHandle_result {...}77 macro_rules! NonfungibleHandle_result {...}
984 /// @notice Function to mint a token.993 /// @notice Function to mint a token.
985 /// @param data Array of pairs of token owner and token's properties for minted token994 /// @param data Array of pairs of token owner and token's properties for minted token
986 #[weight(<SelfWeightOf<T>>::create_multiple_items(data.len() as u32) + <SelfWeightOf<T>>::set_token_properties(data.len() as u32))]995 #[weight(<SelfWeightOf<T>>::create_multiple_items(data.len() as u32) + <SelfWeightOf<T>>::set_token_properties(data.len() as u32))]
987 fn mint_bulk_cross(&mut self, caller: Caller, data: Vec<eth::MintTokenData>) -> Result<bool> {996 fn mint_bulk_cross(&mut self, caller: Caller, data: Vec<MintTokenData>) -> Result<bool> {
988 let caller = T::CrossAccountId::from_eth(caller);997 let caller = T::CrossAccountId::from_eth(caller);
989 let budget = self998 let budget = self
990 .recorder999 .recorder
991 .weight_calls_budget(<StructureWeight<T>>::find_parent());1000 .weight_calls_budget(<StructureWeight<T>>::find_parent());
9921001
993 let mut create_nft_data = Vec::with_capacity(data.len());1002 let mut create_nft_data = Vec::with_capacity(data.len());
994 for eth::MintTokenData { owner, properties } in data {1003 for MintTokenData { owner, properties } in data {
995 let owner = owner.into_sub_cross_account::<T>()?;1004 let owner = owner.into_sub_cross_account::<T>()?;
996 create_nft_data.push(CreateItemData::<T> {1005 create_nft_data.push(CreateItemData::<T> {
997 properties: properties1006 properties: properties
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
1055 string uri;1055 string uri;
1056}1056}
10571057
1058/// Token minting parameters
1058struct MintTokenData {1059struct MintTokenData {
1060 /// Minted token owner
1059 CrossAddress owner;1061 CrossAddress owner;
1062 /// Minted token properties
1060 Property[] properties;1063 Property[] properties;
1061}1064}
10621065
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
26 char::{REPLACEMENT_CHARACTER, decode_utf16},26 char::{REPLACEMENT_CHARACTER, decode_utf16},
27 convert::TryInto,27 convert::TryInto,
28};28};
29use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};29use evm_coder::{abi::AbiType, AbiCoder, ToLog, generate_stubgen, solidity_interface, types::*};
30use frame_support::{BoundedBTreeMap, BoundedVec};30use frame_support::{BoundedBTreeMap, BoundedVec};
31use pallet_common::{31use pallet_common::{
32 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,32 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
71 },71 },
72}72}
73
74/// Token minting parameters
75#[derive(AbiCoder, Default, Debug)]
76pub struct OwnerPieces {
77 /// Minted token owner
78 pub owner: eth::CrossAddress,
79 /// Number of token pieces
80 pub pieces: u128,
81}
82
83/// Token minting parameters
84#[derive(AbiCoder, Default, Debug)]
85pub struct MintTokenData {
86 /// Minted token owner and number of pieces
87 pub owners: Vec<OwnerPieces>,
88 /// Minted token properties
89 pub properties: Vec<eth::Property>,
90}
7391
74/// @title A contract that allows to set and delete token properties and change token property permissions.92/// @title A contract that allows to set and delete token properties and change token property permissions.
75#[solidity_interface(name = TokenProperties, events(ERC721TokenEvent), enum(derive(PreDispatch)), enum_attr(weight))]93#[solidity_interface(name = TokenProperties, events(ERC721TokenEvent), enum(derive(PreDispatch)), enum_attr(weight))]
1027 fn mint_bulk_cross(1045 fn mint_bulk_cross(
1028 &mut self,1046 &mut self,
1029 caller: Caller,1047 caller: Caller,
1030 token_properties: Vec<eth::MintTokenData>,1048 token_properties: Vec<MintTokenData>,
1031 ) -> Result<bool> {1049 ) -> Result<bool> {
1032 let caller = T::CrossAccountId::from_eth(caller);1050 let caller = T::CrossAccountId::from_eth(caller);
1033 let budget = self1051 let budget = self
1034 .recorder1052 .recorder
1035 .weight_calls_budget(<StructureWeight<T>>::find_parent());1053 .weight_calls_budget(<StructureWeight<T>>::find_parent());
10361054
1037 let mut create_rft_data = Vec::with_capacity(token_properties.len());1055 let mut create_rft_data = Vec::with_capacity(token_properties.len());
1038 for eth::MintTokenData { owner, properties } in token_properties {1056 for MintTokenData { owners, properties } in token_properties {
1039 let owner = owner.into_sub_cross_account::<T>()?;
1040 let users: BoundedBTreeMap<_, _, _> = [(owner, 1)]1057 let users: BoundedBTreeMap<_, _, _> = owners
1041 .into_iter()1058 .into_iter()
1059 .map(|data| Ok((data.owner.into_sub_cross_account::<T>()?, data.pieces)))
1042 .collect::<BTreeMap<_, _>>()1060 .collect::<Result<BTreeMap<_, _>>>()?
1043 .try_into()1061 .try_into()
1044 .map_err(|_| "too many users")?;1062 .map_err(|_| "too many users")?;
1045 create_rft_data.push(CreateItemData::<T> {1063 create_rft_data.push(CreateItemData::<T> {
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
800}800}
801801
802/// @title Unique extensions for ERC721.802/// @title Unique extensions for ERC721.
803/// @dev the ERC-165 identifier for this interface is 0x3e828d60803/// @dev the ERC-165 identifier for this interface is 0x4abaabdb
804contract ERC721UniqueExtensions is Dummy, ERC165 {804contract ERC721UniqueExtensions is Dummy, ERC165 {
805 /// @notice A descriptive name for a collection of NFTs in this contract805 /// @notice A descriptive name for a collection of NFTs in this contract
806 /// @dev EVM selector for this function is: 0x06fdde03,806 /// @dev EVM selector for this function is: 0x06fdde03,
988988
989 /// @notice Function to mint a token.989 /// @notice Function to mint a token.
990 /// @param tokenProperties Properties of minted token990 /// @param tokenProperties Properties of minted token
991 /// @dev EVM selector for this function is: 0xab427b0c,991 /// @dev EVM selector for this function is: 0xdf7a5db7,
992 /// or in textual repr: mintBulkCross(((address,uint256),(string,bytes)[])[])992 /// or in textual repr: mintBulkCross((((address,uint256),uint128)[],(string,bytes)[])[])
993 function mintBulkCross(MintTokenData[] memory tokenProperties) public returns (bool) {993 function mintBulkCross(MintTokenData[] memory tokenProperties) public returns (bool) {
994 require(false, stub_error);994 require(false, stub_error);
995 tokenProperties;995 tokenProperties;
1056 string uri;1056 string uri;
1057}1057}
10581058
1059/// Token minting parameters
1059struct MintTokenData {1060struct MintTokenData {
1061 /// Minted token owner and number of pieces
1060 CrossAddress owner;1062 OwnerPieces[] owners;
1063 /// Minted token properties
1061 Property[] properties;1064 Property[] properties;
1062}1065}
1066
1067/// Token minting parameters
1068struct OwnerPieces {
1069 /// Minted token owner
1070 CrossAddress owner;
1071 /// Number of token pieces
1072 uint128 pieces;
1073}
10631074
1064/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension1075/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
1065/// @dev See https://eips.ethereum.org/EIPS/eip-7211076/// @dev See https://eips.ethereum.org/EIPS/eip-721
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
451 "inputs": [451 "inputs": [
452 {452 {
453 "components": [453 "components": [
454 {
455 "components": [
454 {456 {
455 "components": [457 "components": [
456 { "internalType": "address", "name": "eth", "type": "address" },458 {
459 "internalType": "struct CrossAddress",469 "internalType": "struct CrossAddress",
460 "name": "owner",470 "name": "owner",
461 "type": "tuple"471 "type": "tuple"
462 },472 },
473 { "internalType": "uint128", "name": "pieces", "type": "uint128" }
474 ],
475 "internalType": "struct OwnerPieces[]",
476 "name": "owners",
477 "type": "tuple[]"
478 },
463 {479 {
464 "components": [480 "components": [
465 { "internalType": "string", "name": "key", "type": "string" },481 { "internalType": "string", "name": "key", "type": "string" },
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
711 string uri;711 string uri;
712}712}
713713
714/// Token minting parameters
714struct MintTokenData {715struct MintTokenData {
716 /// Minted token owner
715 CrossAddress owner;717 CrossAddress owner;
718 /// Minted token properties
716 Property[] properties;719 Property[] properties;
717}720}
718721
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
551}551}
552552
553/// @title Unique extensions for ERC721.553/// @title Unique extensions for ERC721.
554/// @dev the ERC-165 identifier for this interface is 0x3e828d60554/// @dev the ERC-165 identifier for this interface is 0x4abaabdb
555interface ERC721UniqueExtensions is Dummy, ERC165 {555interface ERC721UniqueExtensions is Dummy, ERC165 {
556 /// @notice A descriptive name for a collection of NFTs in this contract556 /// @notice A descriptive name for a collection of NFTs in this contract
557 /// @dev EVM selector for this function is: 0x06fdde03,557 /// @dev EVM selector for this function is: 0x06fdde03,
670670
671 /// @notice Function to mint a token.671 /// @notice Function to mint a token.
672 /// @param tokenProperties Properties of minted token672 /// @param tokenProperties Properties of minted token
673 /// @dev EVM selector for this function is: 0xab427b0c,673 /// @dev EVM selector for this function is: 0xdf7a5db7,
674 /// or in textual repr: mintBulkCross(((address,uint256),(string,bytes)[])[])674 /// or in textual repr: mintBulkCross((((address,uint256),uint128)[],(string,bytes)[])[])
675 function mintBulkCross(MintTokenData[] memory tokenProperties) external returns (bool);675 function mintBulkCross(MintTokenData[] memory tokenProperties) external returns (bool);
676676
677 // /// @notice Function to mint multiple tokens with the given tokenUris.677 // /// @notice Function to mint multiple tokens with the given tokenUris.
712 string uri;712 string uri;
713}713}
714714
715/// Token minting parameters
715struct MintTokenData {716struct MintTokenData {
717 /// Minted token owner and number of pieces
716 CrossAddress owner;718 OwnerPieces[] owners;
719 /// Minted token properties
717 Property[] properties;720 Property[] properties;
718}721}
722
723/// Token minting parameters
724struct OwnerPieces {
725 /// Minted token owner
726 CrossAddress owner;
727 /// Number of token pieces
728 uint128 pieces;
729}
719730
720/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension731/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
721/// @dev See https://eips.ethereum.org/EIPS/eip-721732/// @dev See https://eips.ethereum.org/EIPS/eip-721
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
216 name: 'A',216 name: 'A',
217 description: 'B',217 description: 'B',
218 tokenPrefix: 'C',218 tokenPrefix: 'C',
219 collectionMode: 'rft',219 collectionMode: 'nft',
220 adminList: [callerCross],220 adminList: [callerCross],
221 tokenPropertyPermissions: [221 tokenPropertyPermissions: [
222 {key: 'key_0_0', permissions},222 {key: 'key_0_0', permissions},
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
131 const callerCross = helper.ethCrossAccount.fromAddress(caller);131 const callerCross = helper.ethCrossAccount.fromAddress(caller);
132 const receiver = helper.eth.createAccount();132 const receiver = helper.eth.createAccount();
133 const receiverCross = helper.ethCrossAccount.fromAddress(receiver);133 const receiverCross = helper.ethCrossAccount.fromAddress(receiver);
134 const receiver2 = helper.eth.createAccount();
135 const receiver2Cross = helper.ethCrossAccount.fromAddress(receiver2);
134136
135 const permissions = [137 const permissions = [
136 {code: TokenPermissionField.Mutable, value: true},138 {code: TokenPermissionField.Mutable, value: true},
157 },159 },
158 ).send();160 ).send();
159161
160 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', caller);162 const contract = await helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
161 {163 {
162 const nextTokenId = await contract.methods.nextTokenId().call();164 const nextTokenId = await contract.methods.nextTokenId().call();
163 expect(nextTokenId).to.be.equal('1');165 expect(nextTokenId).to.be.equal('1');
164 const result = await contract.methods.mintBulkCross([166 const result = await contract.methods.mintBulkCross([
165 {167 {
168 owners: [{
166 owner: receiverCross,169 owner: receiverCross,
170 pieces: 1,
171 }],
167 properties: [172 properties: [
168 {key: 'key_0_0', value: Buffer.from('value_0_0')},173 {key: 'key_0_0', value: Buffer.from('value_0_0')},
169 ],174 ],
170 },175 },
171 {176 {
177 owners: [{
172 owner: receiverCross,178 owner: receiverCross,
179 pieces: 2,
180 }],
173 properties: [181 properties: [
174 {key: 'key_1_0', value: Buffer.from('value_1_0')},182 {key: 'key_1_0', value: Buffer.from('value_1_0')},
175 {key: 'key_1_1', value: Buffer.from('value_1_1')},183 {key: 'key_1_1', value: Buffer.from('value_1_1')},
176 ],184 ],
177 },185 },
178 {186 {
187 owners: [
188 {
179 owner: receiverCross,189 owner: receiverCross,
190 pieces: 1,
191 },
192 {
193 owner: receiver2Cross,
194 pieces: 2,
195 },
196 ],
180 properties: [197 properties: [
181 {key: 'key_2_0', value: Buffer.from('value_2_0')},198 {key: 'key_2_0', value: Buffer.from('value_2_0')},
182 {key: 'key_2_1', value: Buffer.from('value_2_1')},199 {key: 'key_2_1', value: Buffer.from('value_2_1')},
190 const event = events[i];207 const event = events[i];
191 expect(event.address).to.equal(collectionAddress);208 expect(event.address).to.equal(collectionAddress);
192 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');209 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
210 if(i == 0 || i == 1)
193 expect(event.returnValues.to).to.equal(receiver);211 expect(event.returnValues.to).to.equal(receiver);
212 else
213 expect(event.returnValues.to).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');
214
194 expect(event.returnValues.tokenId).to.equal(`${+nextTokenId + i}`);215 expect(event.returnValues.tokenId).to.equal(`${+nextTokenId + i}`);
195 }216 }