--- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -749,18 +749,24 @@ /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. + #[solidity(hide)] fn cross_owner_of(&self, token_id: U256) -> Result { + Self::owner_of_cross(&self, token_id) + } + + /// Returns the owner (in cross format) of the token. + /// + /// @param tokenId Id for the token. + fn owner_of_cross(&self, token_id: U256) -> Result { Self::token_owner(&self, token_id.try_into()?) .map(|o| eth::CrossAddress::from_sub_cross_account::(&o)) .map_err(|_| Error::Revert("token not found".into())) } /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. /// @param owner An cross address for whom to query the balance /// @return The number of NFTs owned by `owner`, possibly zero - fn cross_balance_of(&self, owner: eth::CrossAddress) -> Result { + fn balance_of_cross(&self, owner: eth::CrossAddress) -> Result { self.consume_store_reads(1)?; let balance = >::get((self.id, owner.into_sub_cross_account::()?)); Ok(balance.into()) --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -774,7 +774,7 @@ } /// @title Unique extensions for ERC721. -/// @dev the ERC-165 identifier for this interface is 0x323b1db8 +/// @dev the ERC-165 identifier for this interface is 0x307b061a contract ERC721UniqueExtensions is Dummy, ERC165 { /// @notice A descriptive name for a collection of NFTs in this contract /// @dev EVM selector for this function is: 0x06fdde03, @@ -803,12 +803,24 @@ return ""; } + // /// Returns the owner (in cross format) of the token. + // /// + // /// @param tokenId Id for the token. + // /// @dev EVM selector for this function is: 0x2b29dace, + // /// or in textual repr: crossOwnerOf(uint256) + // function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) { + // require(false, stub_error); + // tokenId; + // dummy; + // return CrossAddress(0x0000000000000000000000000000000000000000,0); + // } + /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. - /// @dev EVM selector for this function is: 0x2b29dace, - /// or in textual repr: crossOwnerOf(uint256) - function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) { + /// @dev EVM selector for this function is: 0xcaa3a4d0, + /// or in textual repr: ownerOfCross(uint256) + function ownerOfCross(uint256 tokenId) public view returns (CrossAddress memory) { require(false, stub_error); tokenId; dummy; @@ -816,13 +828,11 @@ } /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. /// @param owner An cross address for whom to query the balance /// @return The number of NFTs owned by `owner`, possibly zero - /// @dev EVM selector for this function is: 0x24e52cea, - /// or in textual repr: crossBalanceOf((address,uint256)) - function crossBalanceOf(CrossAddress memory owner) public view returns (uint256) { + /// @dev EVM selector for this function is: 0xec069398, + /// or in textual repr: balanceOfCross((address,uint256)) + function balanceOfCross(CrossAddress memory owner) public view returns (uint256) { require(false, stub_error); owner; dummy; --- a/pallets/refungible/src/erc.rs +++ b/pallets/refungible/src/erc.rs @@ -783,7 +783,15 @@ /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. + #[solidity(hide)] fn cross_owner_of(&self, token_id: U256) -> Result { + Self::owner_of_cross(&self, token_id) + } + + /// Returns the owner (in cross format) of the token. + /// + /// @param tokenId Id for the token. + fn owner_of_cross(&self, token_id: U256) -> Result { Self::token_owner(&self, token_id.try_into()?) .map(|o| eth::CrossAddress::from_sub_cross_account::(&o)) .or_else(|err| match err { @@ -795,11 +803,9 @@ } /// @notice Count all RFTs assigned to an owner - /// @dev RFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. /// @param owner An cross address for whom to query the balance /// @return The number of RFTs owned by `owner`, possibly zero - fn cross_balance_of(&self, owner: eth::CrossAddress) -> Result { + fn balance_of_cross(&self, owner: eth::CrossAddress) -> Result { self.consume_store_reads(1)?; let balance = >::get((self.id, owner.into_sub_cross_account::()?)); Ok(balance.into()) --- a/pallets/refungible/src/stubs/UniqueRefungible.sol +++ b/pallets/refungible/src/stubs/UniqueRefungible.sol @@ -774,7 +774,7 @@ } /// @title Unique extensions for ERC721. -/// @dev the ERC-165 identifier for this interface is 0x9780edce +/// @dev the ERC-165 identifier for this interface is 0x95c0f66c contract ERC721UniqueExtensions is Dummy, ERC165 { /// @notice A descriptive name for a collection of NFTs in this contract /// @dev EVM selector for this function is: 0x06fdde03, @@ -803,12 +803,24 @@ return ""; } + // /// Returns the owner (in cross format) of the token. + // /// + // /// @param tokenId Id for the token. + // /// @dev EVM selector for this function is: 0x2b29dace, + // /// or in textual repr: crossOwnerOf(uint256) + // function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) { + // require(false, stub_error); + // tokenId; + // dummy; + // return CrossAddress(0x0000000000000000000000000000000000000000,0); + // } + /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. - /// @dev EVM selector for this function is: 0x2b29dace, - /// or in textual repr: crossOwnerOf(uint256) - function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) { + /// @dev EVM selector for this function is: 0xcaa3a4d0, + /// or in textual repr: ownerOfCross(uint256) + function ownerOfCross(uint256 tokenId) public view returns (CrossAddress memory) { require(false, stub_error); tokenId; dummy; @@ -816,13 +828,11 @@ } /// @notice Count all RFTs assigned to an owner - /// @dev RFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. /// @param owner An cross address for whom to query the balance /// @return The number of RFTs owned by `owner`, possibly zero - /// @dev EVM selector for this function is: 0x24e52cea, - /// or in textual repr: crossBalanceOf((address,uint256)) - function crossBalanceOf(CrossAddress memory owner) public view returns (uint256) { + /// @dev EVM selector for this function is: 0xec069398, + /// or in textual repr: balanceOfCross((address,uint256)) + function balanceOfCross(CrossAddress memory owner) public view returns (uint256) { require(false, stub_error); owner; dummy; --- a/runtime/common/ethereum/sponsoring/refungible.rs +++ b/runtime/common/ethereum/sponsoring/refungible.rs @@ -227,7 +227,8 @@ | Symbol | Description | CrossOwnerOf { .. } - | CrossBalanceOf { .. } + | OwnerOfCross { .. } + | BalanceOfCross { .. } | Properties { .. } | NextTokenId | TokenContractAddress { .. } --- a/tests/src/eth/abi/nonFungible.json +++ b/tests/src/eth/abi/nonFungible.json @@ -177,6 +177,23 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct CrossAddress", + "name": "owner", + "type": "tuple" + } + ], + "name": "balanceOfCross", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", "name": "tokenId", "type": "uint256" } ], "name": "burn", @@ -381,42 +398,6 @@ "inputs": [], "name": "contractAddress", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "address", "name": "eth", "type": "address" }, - { "internalType": "uint256", "name": "sub", "type": "uint256" } - ], - "internalType": "struct CrossAddress", - "name": "owner", - "type": "tuple" - } - ], - "name": "crossBalanceOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "crossOwnerOf", - "outputs": [ - { - "components": [ - { "internalType": "address", "name": "eth", "type": "address" }, - { "internalType": "uint256", "name": "sub", "type": "uint256" } - ], - "internalType": "struct CrossAddress", - "name": "", - "type": "tuple" - } - ], "stateMutability": "view", "type": "function" }, @@ -557,6 +538,25 @@ }, { "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ownerOfCross", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct CrossAddress", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { "internalType": "string[]", "name": "keys", "type": "string[]" } ], --- a/tests/src/eth/abi/reFungible.json +++ b/tests/src/eth/abi/reFungible.json @@ -159,6 +159,23 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct CrossAddress", + "name": "owner", + "type": "tuple" + } + ], + "name": "balanceOfCross", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", "name": "tokenId", "type": "uint256" } ], "name": "burn", @@ -368,25 +385,6 @@ }, { "inputs": [ - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "crossOwnerOf", - "outputs": [ - { - "components": [ - { "internalType": "address", "name": "eth", "type": "address" }, - { "internalType": "uint256", "name": "sub", "type": "uint256" } - ], - "internalType": "struct CrossAddress", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ { "internalType": "string[]", "name": "keys", "type": "string[]" } ], "name": "deleteCollectionProperties", @@ -522,6 +520,25 @@ }, { "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ownerOfCross", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct CrossAddress", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { "internalType": "string[]", "name": "keys", "type": "string[]" } ], --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -533,7 +533,7 @@ } /// @title Unique extensions for ERC721. -/// @dev the ERC-165 identifier for this interface is 0x323b1db8 +/// @dev the ERC-165 identifier for this interface is 0x307b061a interface ERC721UniqueExtensions is Dummy, ERC165 { /// @notice A descriptive name for a collection of NFTs in this contract /// @dev EVM selector for this function is: 0x06fdde03, @@ -550,21 +550,26 @@ /// or in textual repr: description() function description() external view returns (string memory); + // /// Returns the owner (in cross format) of the token. + // /// + // /// @param tokenId Id for the token. + // /// @dev EVM selector for this function is: 0x2b29dace, + // /// or in textual repr: crossOwnerOf(uint256) + // function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory); + /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. - /// @dev EVM selector for this function is: 0x2b29dace, - /// or in textual repr: crossOwnerOf(uint256) - function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory); + /// @dev EVM selector for this function is: 0xcaa3a4d0, + /// or in textual repr: ownerOfCross(uint256) + function ownerOfCross(uint256 tokenId) external view returns (CrossAddress memory); /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. /// @param owner An cross address for whom to query the balance /// @return The number of NFTs owned by `owner`, possibly zero - /// @dev EVM selector for this function is: 0x24e52cea, - /// or in textual repr: crossBalanceOf((address,uint256)) - function crossBalanceOf(CrossAddress memory owner) external view returns (uint256); + /// @dev EVM selector for this function is: 0xec069398, + /// or in textual repr: balanceOfCross((address,uint256)) + function balanceOfCross(CrossAddress memory owner) external view returns (uint256); /// Returns the token properties. /// --- a/tests/src/eth/api/UniqueRefungible.sol +++ b/tests/src/eth/api/UniqueRefungible.sol @@ -533,7 +533,7 @@ } /// @title Unique extensions for ERC721. -/// @dev the ERC-165 identifier for this interface is 0x9780edce +/// @dev the ERC-165 identifier for this interface is 0x95c0f66c interface ERC721UniqueExtensions is Dummy, ERC165 { /// @notice A descriptive name for a collection of NFTs in this contract /// @dev EVM selector for this function is: 0x06fdde03, @@ -550,21 +550,26 @@ /// or in textual repr: description() function description() external view returns (string memory); + // /// Returns the owner (in cross format) of the token. + // /// + // /// @param tokenId Id for the token. + // /// @dev EVM selector for this function is: 0x2b29dace, + // /// or in textual repr: crossOwnerOf(uint256) + // function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory); + /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. - /// @dev EVM selector for this function is: 0x2b29dace, - /// or in textual repr: crossOwnerOf(uint256) - function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory); + /// @dev EVM selector for this function is: 0xcaa3a4d0, + /// or in textual repr: ownerOfCross(uint256) + function ownerOfCross(uint256 tokenId) external view returns (CrossAddress memory); /// @notice Count all RFTs assigned to an owner - /// @dev RFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. /// @param owner An cross address for whom to query the balance /// @return The number of RFTs owned by `owner`, possibly zero - /// @dev EVM selector for this function is: 0x24e52cea, - /// or in textual repr: crossBalanceOf((address,uint256)) - function crossBalanceOf(CrossAddress memory owner) external view returns (uint256); + /// @dev EVM selector for this function is: 0xec069398, + /// or in textual repr: balanceOfCross((address,uint256)) + function balanceOfCross(CrossAddress memory owner) external view returns (uint256); /// Returns the token properties. /// --- a/tests/src/eth/nonFungible.test.ts +++ b/tests/src/eth/nonFungible.test.ts @@ -663,21 +663,21 @@ await expect(collectionEvm.methods[testCase](receiver, 999999).send({from: sender})).to.be.rejected; })); - itEth('Check crossBalanceOf()', async ({helper}) => { + itEth('Check balanceOfCross()', async ({helper}) => { const collection = await helper.nft.mintCollection(minter, {}); const owner = await helper.ethCrossAccount.createAccountWithBalance(donor); const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId); const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner.eth); - expect(BigInt(await collectionEvm.methods.crossBalanceOf(owner).call({from: owner.eth})) === 0n).to.be.true; + expect(BigInt(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})) === 0n).to.be.true; for (let i = 1n; i < 100n; i++) { await collection.mintToken(minter, {Ethereum: owner.eth}); - expect(BigInt(await collectionEvm.methods.crossBalanceOf(owner).call({from: owner.eth})) === i).to.be.true; + expect(BigInt(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})) === i).to.be.true; } }); - itEth('Check crossOwnerOf()', async ({helper}) => { + itEth('Check ownerOfCross()', async ({helper}) => { const collection = await helper.nft.mintCollection(minter, {}); let owner = await helper.ethCrossAccount.createAccountWithBalance(donor); const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId); @@ -685,7 +685,7 @@ const {tokenId} = await collection.mintToken(minter, {Ethereum: owner.eth}); for (let i = 1n; i < 100n; i++) { - const ownerCross = await collectionEvm.methods.crossOwnerOf(tokenId).call({from: owner.eth}); + const ownerCross = await collectionEvm.methods.ownerOfCross(tokenId).call({from: owner.eth}); expect(ownerCross.eth).to.be.eq(owner.eth); expect(ownerCross.sub).to.be.eq(owner.sub); --- a/tests/src/eth/reFungible.test.ts +++ b/tests/src/eth/reFungible.test.ts @@ -591,15 +591,15 @@ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId); const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner.eth); - expect(BigInt(await collectionEvm.methods.crossBalanceOf(owner).call({from: owner.eth})) === 0n).to.be.true; + expect(BigInt(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})) === 0n).to.be.true; for (let i = 1n; i < 100n; i++) { await collection.mintToken(minter, 100n, {Ethereum: owner.eth}); - expect(BigInt(await collectionEvm.methods.crossBalanceOf(owner).call({from: owner.eth})) === i).to.be.true; + expect(BigInt(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})) === i).to.be.true; } }); - itEth.only('Check crossOwnerOf()', async ({helper}) => { + itEth('Check ownerOfCross()', async ({helper}) => { const collection = await helper.rft.mintCollection(minter, {}); let owner = await helper.ethCrossAccount.createAccountWithBalance(donor); const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId); @@ -607,7 +607,7 @@ const {tokenId} = await collection.mintToken(minter, 100n,{Ethereum: owner.eth}); for (let i = 1n; i < 100n; i++) { - const ownerCross = await collectionEvm.methods.crossOwnerOf(tokenId).call({from: owner.eth}); + const ownerCross = await collectionEvm.methods.ownerOfCross(tokenId).call({from: owner.eth}); expect(ownerCross.eth).to.be.eq(owner.eth); expect(ownerCross.sub).to.be.eq(owner.sub); @@ -620,7 +620,7 @@ const tokenContract = await helper.ethNativeContract.rftToken(tokenAddress, owner.eth, true); const newOwner = await helper.ethCrossAccount.createAccountWithBalance(donor); await tokenContract.methods.transferCross(newOwner, 50).send({from: owner.eth}); - const ownerCross = await collectionEvm.methods.crossOwnerOf(tokenId).call({from: owner.eth}); + const ownerCross = await collectionEvm.methods.ownerOfCross(tokenId).call({from: owner.eth}); expect(ownerCross.eth.toUpperCase()).to.be.eq('0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); expect(ownerCross.sub).to.be.eq('0'); }); --- a/tests/src/eth/tokens/minting.test.ts +++ b/tests/src/eth/tokens/minting.test.ts @@ -19,7 +19,7 @@ import {expect, itEth, usingEthPlaygrounds} from '../util'; -describe('Minting tokens', () => { +describe.only('Minting tokens', () => { let donor: IKeyringPair; let alice: IKeyringPair; @@ -63,7 +63,7 @@ const tokenId = event.returnValues.tokenId; expect(tokenId).to.be.equal('1'); expect(await helper.collection.getLastTokenId(collection.collectionId)).to.eq(1); - expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']); + expect(await contract.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']); } }); }); @@ -97,7 +97,7 @@ const tokenId = event.returnValues.tokenId; expect(tokenId).to.be.equal('1'); expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1); - expect(await collection.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']); + expect(await collection.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']); } }); }); @@ -131,7 +131,7 @@ const tokenId = event.returnValues.tokenId; expect(tokenId).to.be.equal('1'); expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1); - expect(await collection.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']); + expect(await collection.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']); } }); }); @@ -157,7 +157,7 @@ expect(event.returnValues.to).to.be.equal(receiver); expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI'); - expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']); + expect(await contract.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']); // TODO: this wont work right now, need release 919000 first // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send(); // const tokenUri = await contract.methods.tokenURI(nextTokenId).call();