From ba7f7c77970c7e2d81e020b0ad4211f3d2f25dc8 Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Thu, 13 Jan 2022 17:23:44 +0100
Subject: [PATCH 1/7] v1.3.3
---
package.json | 2 +-
pom.xml | 2 +-
setup.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index b9c58402..c393e79a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@nevermined-io/contracts",
- "version": "1.3.2",
+ "version": "1.3.3",
"description": "Nevermined implementation of Nevermined in Solidity",
"bugs": {
"url": "https://github.com/nevermined-io/contracts/issues"
diff --git a/pom.xml b/pom.xml
index 98c86690..e46723ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
io.keyko.nevermined
contracts
jar
- 1.3.2
+ 1.3.3
Nevermined Contracts
Nevermined Data Platform Smart Contracts in Solidity
https://github.com/nevermined-io/contracts
diff --git a/setup.py b/setup.py
index 6eaac8a3..b86be491 100644
--- a/setup.py
+++ b/setup.py
@@ -39,6 +39,6 @@
test_suite='tests',
tests_require=test_requirements,
url='https://github.com/nevermined-io/contracts',
- version='1.3.2',
+ version='1.3.3',
zip_safe=False,
)
From 04a0d0c002fe68402b407d3b34244b69a67d1906 Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Thu, 13 Jan 2022 17:24:16 +0100
Subject: [PATCH 2/7] Adding support to EIP-2981
---
contracts/registry/DIDRegistry.sol | 6 +-
contracts/registry/DIDRegistryLibrary.sol | 2 +-
contracts/token/erc1155/NFTUpgradeable.sol | 36 +++++++++--
contracts/token/erc2981/ERC2981.sol | 63 ++++++++++++++++++++
contracts/token/erc721/NFT721Upgradeable.sol | 39 ++++++++++--
test/unit/registry/Mintable721DIDRegistry.js | 17 ++++++
test/unit/registry/MintableDIDRegistry.js | 14 +++++
7 files changed, 164 insertions(+), 13 deletions(-)
create mode 100644 contracts/token/erc2981/ERC2981.sol
diff --git a/contracts/registry/DIDRegistry.sol b/contracts/registry/DIDRegistry.sol
index 0986772a..e05d2637 100644
--- a/contracts/registry/DIDRegistry.sol
+++ b/contracts/registry/DIDRegistry.sol
@@ -146,7 +146,9 @@ contract DIDRegistry is DIDFactory {
returns (bool success)
{
didRegisterList.initializeNftConfig(_did, _cap, _royalties);
-
+
+ erc1155.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
+
if (_mint) {
mint(_did, _cap);
}
@@ -167,6 +169,8 @@ contract DIDRegistry is DIDFactory {
{
didRegisterList.initializeNft721Config(_did, _royalties);
+ erc721.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
+
if (_mint) {
mint721(_did);
}
diff --git a/contracts/registry/DIDRegistryLibrary.sol b/contracts/registry/DIDRegistryLibrary.sol
index 9fe4a6a3..a5a725f1 100644
--- a/contracts/registry/DIDRegistryLibrary.sol
+++ b/contracts/registry/DIDRegistryLibrary.sol
@@ -120,7 +120,7 @@ library DIDRegistryLibrary {
require(!_self.didRegisters[_did].nftInitialized, 'NFT already initialized');
- require(_royalties < 100, 'Invalid royalties number');
+ require(_royalties <= 100, 'Invalid royalties number');
require(_royalties >= _self.didRegisters[_did].royalties, 'Cannot decrease royalties');
_self.didRegisters[_did].mintCap = _cap;
diff --git a/contracts/token/erc1155/NFTUpgradeable.sol b/contracts/token/erc1155/NFTUpgradeable.sol
index 45b7aa8f..5ea81e55 100644
--- a/contracts/token/erc1155/NFTUpgradeable.sol
+++ b/contracts/token/erc1155/NFTUpgradeable.sol
@@ -5,17 +5,18 @@ pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
+import "../erc2981/ERC2981.sol";
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
*/
-contract NFTUpgradeable is ERC1155Upgradeable, OwnableUpgradeable, AccessControlUpgradeable {
+contract NFTUpgradeable is ERC1155Upgradeable, ERC2981, OwnableUpgradeable, AccessControlUpgradeable {
// Mapping from account to proxy approvals
mapping (address => bool) private _proxyApprovals;
-
+
bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
/**
@@ -35,7 +36,6 @@ contract NFTUpgradeable is ERC1155Upgradeable, OwnableUpgradeable, AccessControl
AccessControlUpgradeable.__AccessControl_init();
AccessControlUpgradeable._setupRole(MINTER_ROLE, msg.sender);
}
-
function setProxyApproval(address operator, bool approved) public onlyOwner virtual {
_proxyApprovals[operator] = approved;
@@ -63,9 +63,35 @@ contract NFTUpgradeable is ERC1155Upgradeable, OwnableUpgradeable, AccessControl
AccessControlUpgradeable._setupRole(MINTER_ROLE, account);
}
- function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, ERC1155Upgradeable) returns (bool) {
+ /**
+ * @dev Record the asset royalties
+ * @param tokenId the id of the asset with the royalties associated
+ * @param receiver the receiver of the royalties (the original creator)
+ * @param royaltyAmount percentage (no decimals, between 0 and 100)
+ */
+ function setTokenRoyalty(
+ uint256 tokenId,
+ address receiver,
+ uint256 royaltyAmount
+ )
+ public
+ {
+ require(hasRole(MINTER_ROLE, msg.sender), 'only minter');
+ _setTokenRoyalty(tokenId, receiver, royaltyAmount);
+ }
+
+ function supportsInterface(
+ bytes4 interfaceId
+ )
+ public
+ view
+ virtual
+ override(AccessControlUpgradeable, ERC1155Upgradeable, ERC2981)
+ returns (bool)
+ {
return AccessControlUpgradeable.supportsInterface(interfaceId)
- || ERC1155Upgradeable.supportsInterface(interfaceId);
+ || ERC1155Upgradeable.supportsInterface(interfaceId)
+ || ERC2981.supportsInterface(interfaceId);
}
}
diff --git a/contracts/token/erc2981/ERC2981.sol b/contracts/token/erc2981/ERC2981.sol
new file mode 100644
index 00000000..01946f3a
--- /dev/null
+++ b/contracts/token/erc2981/ERC2981.sol
@@ -0,0 +1,63 @@
+pragma solidity ^0.8.0;
+// Copyright 2020 Keyko GmbH.
+// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
+// Code is Apache-2.0 and docs are CC-BY-4.0
+
+import '@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol';
+
+/**
+ *
+ * @dev Implementation of the Royalties EIP-2981 base contract
+ * See https://eips.ethereum.org/EIPS/eip-2981
+ */
+abstract contract ERC2981 is IERC2981Upgradeable {
+
+ struct RoyaltyInfo {
+ address receiver;
+ uint256 royaltyAmount;
+ }
+
+ // Mapping of Royalties per tokenId (DID)
+ mapping(uint256 => RoyaltyInfo) internal _royalties;
+
+ function supportsInterface(bytes4 interfaceId)
+ public
+ view
+ virtual
+ override
+ returns (bool)
+ {
+ return
+ interfaceId == type(IERC2981Upgradeable).interfaceId ||
+ supportsInterface(interfaceId);
+ }
+
+ function _setTokenRoyalty(
+ uint256 tokenId,
+ address receiver,
+ uint256 royaltyAmount
+ )
+ internal
+ {
+ require(royaltyAmount <= 100, 'ERC2981Royalties: Too high');
+ _royalties[tokenId] = RoyaltyInfo(receiver, royaltyAmount);
+ }
+
+ /**
+ * @inheritdoc IERC2981Upgradeable
+ */
+ function royaltyInfo(
+ uint256 tokenId,
+ uint256 value
+ )
+ external
+ view
+ override
+ returns (address receiver, uint256 royaltyAmount)
+ {
+ RoyaltyInfo memory royalties = _royalties[tokenId];
+ receiver = royalties.receiver;
+ royaltyAmount = (value * royalties.royaltyAmount) / 100;
+ }
+
+}
diff --git a/contracts/token/erc721/NFT721Upgradeable.sol b/contracts/token/erc721/NFT721Upgradeable.sol
index b472eff2..5c38012a 100644
--- a/contracts/token/erc721/NFT721Upgradeable.sol
+++ b/contracts/token/erc721/NFT721Upgradeable.sol
@@ -5,12 +5,13 @@ pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
+import "../erc2981/ERC2981.sol";
/**
*
* @dev Implementation of the basic standard multi-token.
*/
-contract NFT721Upgradeable is ERC721Upgradeable, OwnableUpgradeable, AccessControlUpgradeable {
+contract NFT721Upgradeable is ERC721Upgradeable, ERC2981, OwnableUpgradeable, AccessControlUpgradeable {
// Mapping from account to proxy approvals
mapping (address => bool) private _proxyApprovals;
@@ -47,7 +48,11 @@ contract NFT721Upgradeable is ERC721Upgradeable, OwnableUpgradeable, AccessContr
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return super.isApprovedForAll(account, operator) || _proxyApprovals[operator];
}
-
+
+ function addMinter(address account) public onlyOwner {
+ AccessControlUpgradeable._setupRole(MINTER_ROLE, account);
+ }
+
function mint(address to, uint256 id) public {
require(hasRole(MINTER_ROLE, msg.sender), 'only minter can mint');
_mint(to, id);
@@ -58,13 +63,35 @@ contract NFT721Upgradeable is ERC721Upgradeable, OwnableUpgradeable, AccessContr
_burn(id);
}
- function addMinter(address account) public onlyOwner {
- AccessControlUpgradeable._setupRole(MINTER_ROLE, account);
+ /**
+ * @dev Record the asset royalties
+ * @param tokenId the id of the asset with the royalties associated
+ * @param receiver the receiver of the royalties (the original creator)
+ * @param royaltyAmount percentage (no decimals, between 0 and 100)
+ */
+ function setTokenRoyalty(
+ uint256 tokenId,
+ address receiver,
+ uint256 royaltyAmount
+ )
+ public
+ {
+ require(hasRole(MINTER_ROLE, msg.sender), 'only minter');
+ _setTokenRoyalty(tokenId, receiver, royaltyAmount);
}
- function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, ERC721Upgradeable) returns (bool) {
+ function supportsInterface(
+ bytes4 interfaceId
+ )
+ public
+ view
+ virtual
+ override(AccessControlUpgradeable, ERC721Upgradeable, ERC2981)
+ returns (bool)
+ {
return AccessControlUpgradeable.supportsInterface(interfaceId)
- || ERC721Upgradeable.supportsInterface(interfaceId);
+ || ERC721Upgradeable.supportsInterface(interfaceId)
+ || ERC2981.supportsInterface(interfaceId);
}
}
diff --git a/test/unit/registry/Mintable721DIDRegistry.js b/test/unit/registry/Mintable721DIDRegistry.js
index 5a1912e1..a60a49ef 100644
--- a/test/unit/registry/Mintable721DIDRegistry.js
+++ b/test/unit/registry/Mintable721DIDRegistry.js
@@ -114,6 +114,23 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
await assert.isRejected(nft.ownerOf(did))
})
+ it('The royalties should be initialized and retrieved (ERC-2981)', async () => {
+ const didSeed = testUtils.generateId()
+ const did = await didRegistry.hashDID(didSeed, owner)
+ const checksum = testUtils.generateId()
+ await didRegistry.registerAttribute(
+ didSeed, checksum, [], value, { from: owner })
+
+ await didRegistry.enableAndMintDidNft721(did, 10, true, { from: owner })
+
+ const nftOwner = await nft.ownerOf(did)
+ assert.strictEqual(owner, nftOwner)
+
+ const { receiver, royaltyAmount } = await nft.royaltyInfo(did, 500)
+ assert.strictEqual(owner, receiver)
+ assert.strictEqual(50, royaltyAmount.toNumber())
+ })
+
it('Should Mint automatically if is configured that way', async () => {
const didSeed = testUtils.generateId()
const did = await didRegistry.hashDID(didSeed, owner)
diff --git a/test/unit/registry/MintableDIDRegistry.js b/test/unit/registry/MintableDIDRegistry.js
index fc0bb203..fa3f0c0b 100644
--- a/test/unit/registry/MintableDIDRegistry.js
+++ b/test/unit/registry/MintableDIDRegistry.js
@@ -128,6 +128,18 @@ contract('Mintable DIDRegistry', (accounts) => {
assert.strictEqual(10, balance.toNumber())
})
+ it('The royalties should be initialized and retrieved (ERC-2981)', async () => {
+ const didSeed = testUtils.generateId()
+ const did = await didRegistry.hashDID(didSeed, owner)
+ const checksum = testUtils.generateId()
+ await didRegistry.registerMintableDID(
+ didSeed, checksum, [], value, 999, 10, constants.activities.GENERATED, '', { from: owner })
+
+ const { receiver, royaltyAmount } = await nft.royaltyInfo(did, 500)
+ assert.strictEqual(owner, receiver)
+ assert.strictEqual(50, royaltyAmount.toNumber())
+ })
+
it('Should Mint automatically if is configured that way', async () => {
const didSeed = testUtils.generateId()
const did = await didRegistry.hashDID(didSeed, owner)
@@ -141,6 +153,7 @@ contract('Mintable DIDRegistry', (accounts) => {
assert.strictEqual(5, balanceOwner.toNumber())
})
+
it('Should mint if is not capped', async () => {
const didSeed = testUtils.generateId()
const did = await didRegistry.hashDID(didSeed, owner)
@@ -233,6 +246,7 @@ contract('Mintable DIDRegistry', (accounts) => {
assert.isNotOk( // MUST BE FALSE. Original creator is not getting royalties
await didRegistryLibraryProxy.areRoyaltiesValid(did, [100], [other]))
+
})
})
})
From 488e1423bf16818fa60e2d39f98f476b3ca16240 Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Thu, 13 Jan 2022 17:48:58 +0100
Subject: [PATCH 3/7] linting
---
contracts/token/erc1155/NFTUpgradeable.sol | 2 +-
contracts/token/erc721/NFT721Upgradeable.sol | 2 +-
test/unit/registry/MintableDIDRegistry.js | 2 --
3 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/contracts/token/erc1155/NFTUpgradeable.sol b/contracts/token/erc1155/NFTUpgradeable.sol
index 5ea81e55..002781fd 100644
--- a/contracts/token/erc1155/NFTUpgradeable.sol
+++ b/contracts/token/erc1155/NFTUpgradeable.sol
@@ -5,7 +5,7 @@ pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
-import "../erc2981/ERC2981.sol";
+import '../erc2981/ERC2981.sol';
/**
*
diff --git a/contracts/token/erc721/NFT721Upgradeable.sol b/contracts/token/erc721/NFT721Upgradeable.sol
index 5c38012a..4f594637 100644
--- a/contracts/token/erc721/NFT721Upgradeable.sol
+++ b/contracts/token/erc721/NFT721Upgradeable.sol
@@ -5,7 +5,7 @@ pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
-import "../erc2981/ERC2981.sol";
+import '../erc2981/ERC2981.sol';
/**
*
diff --git a/test/unit/registry/MintableDIDRegistry.js b/test/unit/registry/MintableDIDRegistry.js
index fa3f0c0b..b12a6328 100644
--- a/test/unit/registry/MintableDIDRegistry.js
+++ b/test/unit/registry/MintableDIDRegistry.js
@@ -153,7 +153,6 @@ contract('Mintable DIDRegistry', (accounts) => {
assert.strictEqual(5, balanceOwner.toNumber())
})
-
it('Should mint if is not capped', async () => {
const didSeed = testUtils.generateId()
const did = await didRegistry.hashDID(didSeed, owner)
@@ -246,7 +245,6 @@ contract('Mintable DIDRegistry', (accounts) => {
assert.isNotOk( // MUST BE FALSE. Original creator is not getting royalties
await didRegistryLibraryProxy.areRoyaltiesValid(did, [100], [other]))
-
})
})
})
From 1800e52897af99263d9487c1ba0c70e863c1cb1b Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Thu, 13 Jan 2022 18:26:21 +0100
Subject: [PATCH 4/7] initializing royalties just when are necessary
---
contracts/registry/DIDRegistry.sol | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/contracts/registry/DIDRegistry.sol b/contracts/registry/DIDRegistry.sol
index e05d2637..df71aaf1 100644
--- a/contracts/registry/DIDRegistry.sol
+++ b/contracts/registry/DIDRegistry.sol
@@ -147,11 +147,11 @@ contract DIDRegistry is DIDFactory {
{
didRegisterList.initializeNftConfig(_did, _cap, _royalties);
- erc1155.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
+ if (_royalties > 0)
+ erc1155.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
- if (_mint) {
+ if (_mint)
mint(_did, _cap);
- }
return super.used(
keccak256(abi.encode(_did, _cap, _royalties, msg.sender)),
@@ -169,11 +169,11 @@ contract DIDRegistry is DIDFactory {
{
didRegisterList.initializeNft721Config(_did, _royalties);
- erc721.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
+ if (_royalties > 0)
+ erc721.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
- if (_mint) {
+ if (_mint)
mint721(_did);
- }
return super.used(
keccak256(abi.encode(_did, 1, _royalties, msg.sender)),
From a9d38825e0a1c176aca6076cacac5dabb601aa1d Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Thu, 13 Jan 2022 18:43:45 +0100
Subject: [PATCH 5/7] wip
---
contracts/registry/DIDRegistry.sol | 39 ++++++++++++++------
contracts/token/erc721/NFT721Upgradeable.sol | 7 ++++
2 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/contracts/registry/DIDRegistry.sol b/contracts/registry/DIDRegistry.sol
index df71aaf1..52a03ca4 100644
--- a/contracts/registry/DIDRegistry.sol
+++ b/contracts/registry/DIDRegistry.sol
@@ -60,7 +60,7 @@ contract DIDRegistry is DIDFactory {
* @param _royalties refers to the royalties to reward to the DID creator in the secondary market
* @param _mint if true it mints the ERC-1155 NFTs attached to the asset
* @param _activityId refers to activity
- * @param _attributes refers to the provenance attributes
+ * @param _nftMetadata refers to the url providing the NFT Metadata
* @return size refers to the size of the registry after the register action.
*/
function registerMintableDID(
@@ -72,13 +72,13 @@ contract DIDRegistry is DIDFactory {
uint8 _royalties,
bool _mint,
bytes32 _activityId,
- string memory _attributes
+ string memory _nftMetadata
)
public
- onlyValidAttributes(_attributes)
+ onlyValidAttributes(_nftMetadata)
returns (uint size)
{
- uint result = registerDID(_didSeed, _checksum, _providers, _url, _activityId, _attributes);
+ uint result = registerDID(_didSeed, _checksum, _providers, _url, _activityId, '');
enableAndMintDidNft(
hashDID(_didSeed, msg.sender),
_cap,
@@ -101,7 +101,7 @@ contract DIDRegistry is DIDFactory {
* @param _cap refers to the mint cap
* @param _royalties refers to the royalties to reward to the DID creator in the secondary market
* @param _activityId refers to activity
- * @param _attributes refers to the provenance attributes
+ * @param _nftMetadata refers to the url providing the NFT Metadata
* @return size refers to the size of the registry after the register action.
*/
function registerMintableDID(
@@ -112,19 +112,19 @@ contract DIDRegistry is DIDFactory {
uint256 _cap,
uint8 _royalties,
bytes32 _activityId,
- string memory _attributes
+ string memory _nftMetadata
)
public
- onlyValidAttributes(_attributes)
+ onlyValidAttributes(_nftMetadata)
returns (uint size)
{
return registerMintableDID(
- _didSeed, _checksum, _providers, _url, _cap, _royalties, false, _activityId, _attributes);
+ _didSeed, _checksum, _providers, _url, _cap, _royalties, false, _activityId, _nftMetadata);
}
/**
- * @notice enableDidNft creates the initial setup of NFTs minting and royalties distribution.
+ * @notice enableDidNft creates the initial setup of NFTs minting and royalties distribution for ERC-1155 NFTs.
* After this initial setup, this data can't be changed anymore for the DID given, even for the owner of the DID.
* The reason of this is to avoid minting additional NFTs after the initial agreement, what could affect the
* valuation of NFTs of a DID already created.
@@ -134,12 +134,14 @@ contract DIDRegistry is DIDFactory {
* @param _cap refers to the mint cap
* @param _royalties refers to the royalties to reward to the DID creator in the secondary market
* @param _mint if is true mint directly the amount capped tokens and lock in the _lockAddress
+ * @param _nftMetadata refers to the url providing the NFT Metadata
*/
function enableAndMintDidNft(
bytes32 _did,
uint256 _cap,
uint8 _royalties,
- bool _mint
+ bool _mint,
+ string memory _nftMetadata
)
public
onlyDIDOwner(_did)
@@ -157,11 +159,24 @@ contract DIDRegistry is DIDFactory {
keccak256(abi.encode(_did, _cap, _royalties, msg.sender)),
_did, msg.sender, keccak256('enableNft'), '', 'nft initialization');
}
-
+
+ /**
+ * @notice enableAndMintDidNft721 creates the initial setup of NFTs minting and royalties distribution for ERC-721 NFTs.
+ * After this initial setup, this data can't be changed anymore for the DID given, even for the owner of the DID.
+ * The reason of this is to avoid minting additional NFTs after the initial agreement, what could affect the
+ * valuation of NFTs of a DID already created.
+
+ * @dev update the DID registry providers list by adding the mintCap and royalties configuration
+ * @param _did refers to decentralized identifier (a byte32 length ID)
+ * @param _royalties refers to the royalties to reward to the DID creator in the secondary market
+ * @param _mint if is true mint directly the amount capped tokens and lock in the _lockAddress
+ * @param _nftMetadata refers to the url providing the NFT Metadata
+ */
function enableAndMintDidNft721(
bytes32 _did,
uint8 _royalties,
- bool _mint
+ bool _mint,
+ string memory _nftMetadata
)
public
onlyDIDOwner(_did)
diff --git a/contracts/token/erc721/NFT721Upgradeable.sol b/contracts/token/erc721/NFT721Upgradeable.sol
index 4f594637..c1b0ac44 100644
--- a/contracts/token/erc721/NFT721Upgradeable.sol
+++ b/contracts/token/erc721/NFT721Upgradeable.sol
@@ -63,6 +63,13 @@ contract NFT721Upgradeable is ERC721Upgradeable, ERC2981, OwnableUpgradeable, Ac
_burn(id);
}
+ function tokenURI(uint256 tokenId) public view override returns (string memory) {
+ require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
+
+ string memory baseURI = _baseURI();
+ return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
+ }
+
/**
* @dev Record the asset royalties
* @param tokenId the id of the asset with the royalties associated
From bd92d5f488acb22b94eff95bfe38e6ddc811cc1e Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Thu, 13 Jan 2022 19:13:00 +0100
Subject: [PATCH 6/7] NFT721 test was using 1155 tokens
---
contracts/registry/DIDRegistry.sol | 47 ++++++++++++++++++++++++++++--
test/int/nft/NFT721_e2e.Test.js | 39 ++++++-------------------
2 files changed, 53 insertions(+), 33 deletions(-)
diff --git a/contracts/registry/DIDRegistry.sol b/contracts/registry/DIDRegistry.sol
index df71aaf1..6e0450a2 100644
--- a/contracts/registry/DIDRegistry.sol
+++ b/contracts/registry/DIDRegistry.sol
@@ -47,7 +47,7 @@ contract DIDRegistry is DIDFactory {
}
/**
- * @notice Register a Mintable DID.
+ * @notice Register a Mintable DID using NFTs based in the ERC-1155 standard.
*
* @dev The first attribute of a DID registered sets the DID owner.
* Subsequent updates record _checksum and update info.
@@ -86,8 +86,49 @@ contract DIDRegistry is DIDFactory {
_mint
);
return result;
- }
-
+ }
+
+ /**
+ * @notice Register a Mintable DID using NFTs based in the ERC-721 standard.
+ *
+ * @dev The first attribute of a DID registered sets the DID owner.
+ * Subsequent updates record _checksum and update info.
+ *
+ * @param _didSeed refers to decentralized identifier seed (a bytes32 length ID).
+ * @param _checksum includes a one-way HASH calculated using the DDO content.
+ * @param _providers list of addresses that can act as an asset provider
+ * @param _url refers to the url resolving the DID into a DID Document (DDO), limited to 2048 bytes.
+ * @param _royalties refers to the royalties to reward to the DID creator in the secondary market
+ * @param _mint if true it mints the ERC-1155 NFTs attached to the asset
+ * @param _activityId refers to activity
+ * @param _attributes refers to the provenance attributes
+ * @return size refers to the size of the registry after the register action.
+ */
+ function registerMintableDID721(
+ bytes32 _didSeed,
+ bytes32 _checksum,
+ address[] memory _providers,
+ string memory _url,
+ uint8 _royalties,
+ bool _mint,
+ bytes32 _activityId,
+ string memory _attributes
+ )
+ public
+ onlyValidAttributes(_attributes)
+ returns (uint size)
+ {
+ uint result = registerDID(_didSeed, _checksum, _providers, _url, _activityId, _attributes);
+ enableAndMintDidNft721(
+ hashDID(_didSeed, msg.sender),
+ _royalties,
+ _mint
+ );
+ return result;
+ }
+
+
+
/**
* @notice Register a Mintable DID.
*
diff --git a/test/int/nft/NFT721_e2e.Test.js b/test/int/nft/NFT721_e2e.Test.js
index a6092113..4caed696 100644
--- a/test/int/nft/NFT721_e2e.Test.js
+++ b/test/int/nft/NFT721_e2e.Test.js
@@ -23,8 +23,7 @@ const NeverminedToken = artifacts.require('NeverminedToken')
const NFTAccessCondition = artifacts.require('NFTAccessCondition')
const NFTHolderCondition = artifacts.require('NFT721HolderCondition')
-const TestERC721 = artifacts.require('TestERC721')
-const VitaDAOERC721 = artifacts.require('IPNFT')
+const TestERC721 = artifacts.require('NFT721Upgradeable')
const constants = require('../../helpers/constants.js')
const { getBalance } = require('../../helpers/getBalance.js')
@@ -32,7 +31,6 @@ const testUtils = require('../../helpers/utils.js')
contract('End to End NFT721 Scenarios', (accounts) => {
const royalties = 10 // 10% of royalties in the secondary market
- const cappedAmount = 5
const didSeed = testUtils.generateId()
let did
const agreementId = testUtils.generateId()
@@ -92,8 +90,13 @@ contract('End to End NFT721 Scenarios', (accounts) => {
token = await NeverminedToken.new()
await token.initialize(owner, owner)
+ nft = await TestERC721.new({ from: deployer })
+ await nft.initialize({ from: owner })
+
didRegistry = await DIDRegistry.new()
- await didRegistry.initialize(owner, constants.address.zero, constants.address.zero)
+ await didRegistry.initialize(owner, constants.address.zero, nft.address)
+
+ await nft.addMinter(didRegistry.address)
conditionStoreManager = await ConditionStoreManager.new()
@@ -491,37 +494,13 @@ contract('End to End NFT721 Scenarios', (accounts) => {
describe('Test NFT721', () => {
describe('As an artist I want to register a new artwork', () => {
it('I want to register a new artwork and tokenize (via NFT). I want to get 10% of royalties', async () => {
- nft = await TestERC721.new({ from: deployer })
- await nft.initialize({ from: owner })
-
- const { didRegistry } = await setupTest()
-
- did = await didRegistry.hashDID(didSeed, artist)
-
- await didRegistry.registerMintableDID(
- didSeed, checksum, [], url, cappedAmount, royalties, constants.activities.GENERATED, '', { from: artist })
-
- await nft.mint(did, { from: artist })
- await nft.setApprovalForAll(transferCondition.address, true, { from: artist })
- })
- })
-
- runTests()
- })
-
- describe('VitaDAO NFT721', () => {
- describe('As an artist I want to register a new artwork', () => {
- it('I want to register a new artwork and tokenize (via NFT). I want to get 10% of royalties', async () => {
- nft = await VitaDAOERC721.new({ from: deployer })
- await nft.initialize('VitaNFT', 'VitaNFT', { from: owner })
const { didRegistry } = await setupTest()
did = await didRegistry.hashDID(didSeed, artist)
- await didRegistry.registerMintableDID(
- didSeed, checksum, [], url, cappedAmount, royalties, constants.activities.GENERATED, '', { from: artist })
+ await didRegistry.registerMintableDID721(
+ didSeed, checksum, [], url, royalties, true, constants.activities.GENERATED, '', { from: artist })
- await nft.mint(artist, did, url, { from: owner })
await nft.setApprovalForAll(transferCondition.address, true, { from: artist })
})
})
From 0d49fbf7c2fd6fa53d2406840f5d9c6c205f9ac8 Mon Sep 17 00:00:00 2001
From: Aitor <1726644+aaitor@users.noreply.github.com>
Date: Fri, 14 Jan 2022 14:37:01 +0100
Subject: [PATCH 7/7] Adding support to NFTs metadata (ERC-721 & 1155)
---
contracts/registry/DIDRegistry.sol | 20 +++++---
.../{erc2981/ERC2981.sol => NFTBase.sol} | 51 +++++++++++++++----
contracts/token/erc1155/NFTUpgradeable.sol | 47 +++++++++--------
contracts/token/erc721/NFT721Upgradeable.sol | 50 ++++++++----------
test/unit/registry/Mintable721DIDRegistry.js | 41 ++++++++++-----
test/unit/registry/MintableDIDRegistry.js | 12 +++--
6 files changed, 137 insertions(+), 84 deletions(-)
rename contracts/token/{erc2981/ERC2981.sol => NFTBase.sol} (51%)
diff --git a/contracts/registry/DIDRegistry.sol b/contracts/registry/DIDRegistry.sol
index 8a4e065f..322f2c8d 100644
--- a/contracts/registry/DIDRegistry.sol
+++ b/contracts/registry/DIDRegistry.sol
@@ -83,7 +83,8 @@ contract DIDRegistry is DIDFactory {
hashDID(_didSeed, msg.sender),
_cap,
_royalties,
- _mint
+ _mint,
+ _nftMetadata
);
return result;
}
@@ -101,7 +102,7 @@ contract DIDRegistry is DIDFactory {
* @param _royalties refers to the royalties to reward to the DID creator in the secondary market
* @param _mint if true it mints the ERC-1155 NFTs attached to the asset
* @param _activityId refers to activity
- * @param _attributes refers to the provenance attributes
+ * @param _nftMetadata refers to the url providing the NFT Metadata
* @return size refers to the size of the registry after the register action.
*/
function registerMintableDID721(
@@ -112,17 +113,18 @@ contract DIDRegistry is DIDFactory {
uint8 _royalties,
bool _mint,
bytes32 _activityId,
- string memory _attributes
+ string memory _nftMetadata
)
public
- onlyValidAttributes(_attributes)
+ onlyValidAttributes(_nftMetadata)
returns (uint size)
{
- uint result = registerDID(_didSeed, _checksum, _providers, _url, _activityId, _attributes);
+ uint result = registerDID(_didSeed, _checksum, _providers, _url, _activityId, '');
enableAndMintDidNft721(
hashDID(_didSeed, msg.sender),
_royalties,
- _mint
+ _mint,
+ _nftMetadata
);
return result;
}
@@ -190,6 +192,9 @@ contract DIDRegistry is DIDFactory {
{
didRegisterList.initializeNftConfig(_did, _cap, _royalties);
+ if (bytes(_nftMetadata).length > 0)
+ erc1155.setNFTMetadata(uint256(_did), _nftMetadata);
+
if (_royalties > 0)
erc1155.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
@@ -225,6 +230,9 @@ contract DIDRegistry is DIDFactory {
{
didRegisterList.initializeNft721Config(_did, _royalties);
+ if (bytes(_nftMetadata).length > 0)
+ erc721.setNFTMetadata(uint256(_did), _nftMetadata);
+
if (_royalties > 0)
erc721.setTokenRoyalty(uint256(_did), msg.sender, _royalties);
diff --git a/contracts/token/erc2981/ERC2981.sol b/contracts/token/NFTBase.sol
similarity index 51%
rename from contracts/token/erc2981/ERC2981.sol
rename to contracts/token/NFTBase.sol
index 01946f3a..7017c610 100644
--- a/contracts/token/erc2981/ERC2981.sol
+++ b/contracts/token/NFTBase.sol
@@ -4,34 +4,63 @@ pragma solidity ^0.8.0;
// Code is Apache-2.0 and docs are CC-BY-4.0
import '@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol';
+import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
+import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
+import '@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol';
/**
*
* @dev Implementation of the Royalties EIP-2981 base contract
* See https://eips.ethereum.org/EIPS/eip-2981
*/
-abstract contract ERC2981 is IERC2981Upgradeable {
+abstract contract NFTBase is IERC2981Upgradeable, OwnableUpgradeable, AccessControlUpgradeable {
+ // Mapping from account to proxy approvals
+ mapping (address => bool) internal _proxyApprovals;
+
+ bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
+
struct RoyaltyInfo {
address receiver;
uint256 royaltyAmount;
}
+ struct NFTMetadata {
+ string nftURI;
+ }
+
// Mapping of Royalties per tokenId (DID)
mapping(uint256 => RoyaltyInfo) internal _royalties;
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
+ mapping(uint256 => NFTMetadata) internal _metadata;
+
+ /**
+ * Event for recording proxy approvals.
+ */
+ event ProxyApproval(address sender, address operator, bool approved);
+
+
+ function setProxyApproval(
+ address operator,
+ bool approved
+ )
+ public
+ onlyOwner
+ virtual
{
- return
- interfaceId == type(IERC2981Upgradeable).interfaceId ||
- supportsInterface(interfaceId);
+ _proxyApprovals[operator] = approved;
+ emit ProxyApproval(_msgSender(), operator, approved);
}
-
+
+ function _setNFTMetadata(
+ uint256 tokenId,
+ string memory tokenURI
+ )
+ internal
+ {
+ _metadata[tokenId] = NFTMetadata(tokenURI);
+ }
+
function _setTokenRoyalty(
uint256 tokenId,
address receiver,
diff --git a/contracts/token/erc1155/NFTUpgradeable.sol b/contracts/token/erc1155/NFTUpgradeable.sol
index 002781fd..7c71660f 100644
--- a/contracts/token/erc1155/NFTUpgradeable.sol
+++ b/contracts/token/erc1155/NFTUpgradeable.sol
@@ -3,27 +3,15 @@
pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol';
-import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
-import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
-import '../erc2981/ERC2981.sol';
+import '../NFTBase.sol';
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
*/
-contract NFTUpgradeable is ERC1155Upgradeable, ERC2981, OwnableUpgradeable, AccessControlUpgradeable {
-
- // Mapping from account to proxy approvals
- mapping (address => bool) private _proxyApprovals;
-
- bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
+contract NFTUpgradeable is ERC1155Upgradeable, NFTBase {
- /**
- * Event for recording proxy approvals.
- */
- event ProxyApproval(address sender, address operator, bool approved);
-
/**
* @dev See {_setURI}.
*/
@@ -37,11 +25,6 @@ contract NFTUpgradeable is ERC1155Upgradeable, ERC2981, OwnableUpgradeable, Acce
AccessControlUpgradeable._setupRole(MINTER_ROLE, msg.sender);
}
- function setProxyApproval(address operator, bool approved) public onlyOwner virtual {
- _proxyApprovals[operator] = approved;
- emit ProxyApproval(_msgSender(), operator, approved);
- }
-
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
@@ -63,6 +46,26 @@ contract NFTUpgradeable is ERC1155Upgradeable, ERC2981, OwnableUpgradeable, Acce
AccessControlUpgradeable._setupRole(MINTER_ROLE, account);
}
+// function uri(uint256 id) external view returns (string memory)
+ function uri(uint256 tokenId) public view override returns (string memory) {
+ return _metadata[tokenId].nftURI;
+ }
+
+ /**
+ * @dev Record some NFT Metadata
+ * @param tokenId the id of the asset with the royalties associated
+ * @param nftURI the URI (https, ipfs, etc) to the metadata describing the NFT
+ */
+ function setNFTMetadata(
+ uint256 tokenId,
+ string memory nftURI
+ )
+ public
+ {
+ require(hasRole(MINTER_ROLE, msg.sender), 'only minter');
+ _setNFTMetadata(tokenId, nftURI);
+ }
+
/**
* @dev Record the asset royalties
* @param tokenId the id of the asset with the royalties associated
@@ -86,12 +89,12 @@ contract NFTUpgradeable is ERC1155Upgradeable, ERC2981, OwnableUpgradeable, Acce
public
view
virtual
- override(AccessControlUpgradeable, ERC1155Upgradeable, ERC2981)
+ override(ERC1155Upgradeable, IERC165Upgradeable)
returns (bool)
{
return AccessControlUpgradeable.supportsInterface(interfaceId)
- || ERC1155Upgradeable.supportsInterface(interfaceId)
- || ERC2981.supportsInterface(interfaceId);
+ || ERC1155Upgradeable.supportsInterface(interfaceId)
+ || interfaceId == type(IERC2981Upgradeable).interfaceId;
}
}
diff --git a/contracts/token/erc721/NFT721Upgradeable.sol b/contracts/token/erc721/NFT721Upgradeable.sol
index c1b0ac44..4e26297f 100644
--- a/contracts/token/erc721/NFT721Upgradeable.sol
+++ b/contracts/token/erc721/NFT721Upgradeable.sol
@@ -3,25 +3,13 @@
pragma solidity ^0.8.0;
import '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol';
-import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
-import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
-import '../erc2981/ERC2981.sol';
+import '../NFTBase.sol';
/**
*
* @dev Implementation of the basic standard multi-token.
*/
-contract NFT721Upgradeable is ERC721Upgradeable, ERC2981, OwnableUpgradeable, AccessControlUpgradeable {
-
- // Mapping from account to proxy approvals
- mapping (address => bool) private _proxyApprovals;
-
- bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
-
- /**
- * Event for recording proxy approvals.
- */
- event ProxyApproval(address sender, address operator, bool approved);
+contract NFT721Upgradeable is ERC721Upgradeable, NFTBase {
/**
* @dev See {_setURI}.
@@ -35,13 +23,7 @@ contract NFT721Upgradeable is ERC721Upgradeable, ERC2981, OwnableUpgradeable, Ac
AccessControlUpgradeable.__AccessControl_init();
AccessControlUpgradeable._setupRole(MINTER_ROLE, msg.sender);
}
-
- function setProxyApproval(address operator, bool approved) public onlyOwner virtual {
- _proxyApprovals[operator] = approved;
- emit ProxyApproval(_msgSender(), operator, approved);
- }
-
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
@@ -62,14 +44,26 @@ contract NFT721Upgradeable is ERC721Upgradeable, ERC2981, OwnableUpgradeable, Ac
require(hasRole(MINTER_ROLE, msg.sender), 'only minter can burn');
_burn(id);
}
-
+
function tokenURI(uint256 tokenId) public view override returns (string memory) {
- require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
+ return _metadata[tokenId].nftURI;
+ }
+
+ /**
+ * @dev Record some NFT Metadata
+ * @param tokenId the id of the asset with the royalties associated
+ * @param nftURI the URI (https, ipfs, etc) to the metadata describing the NFT
+ */
+ function setNFTMetadata(
+ uint256 tokenId,
+ string memory nftURI
+ )
+ public
+ {
+ require(hasRole(MINTER_ROLE, msg.sender), 'only minter');
+ _setNFTMetadata(tokenId, nftURI);
+ }
- string memory baseURI = _baseURI();
- return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
- }
-
/**
* @dev Record the asset royalties
* @param tokenId the id of the asset with the royalties associated
@@ -93,12 +87,12 @@ contract NFT721Upgradeable is ERC721Upgradeable, ERC2981, OwnableUpgradeable, Ac
public
view
virtual
- override(AccessControlUpgradeable, ERC721Upgradeable, ERC2981)
+ override(ERC721Upgradeable, IERC165Upgradeable)
returns (bool)
{
return AccessControlUpgradeable.supportsInterface(interfaceId)
|| ERC721Upgradeable.supportsInterface(interfaceId)
- || ERC2981.supportsInterface(interfaceId);
+ || interfaceId == type(IERC2981Upgradeable).interfaceId;
}
}
diff --git a/test/unit/registry/Mintable721DIDRegistry.js b/test/unit/registry/Mintable721DIDRegistry.js
index a60a49ef..71aeb639 100644
--- a/test/unit/registry/Mintable721DIDRegistry.js
+++ b/test/unit/registry/Mintable721DIDRegistry.js
@@ -17,6 +17,7 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
const other = accounts[2]
const consumer = accounts[3]
const value = 'https://nevermined.io/did/nevermined/test-attr-example.txt'
+ const nftMetadataURL = 'https://nevermined.io/metadata.json'
let didRegistry
let didRegistryLibrary
let didRegistryLibraryProxy
@@ -100,18 +101,32 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
await didRegistry.registerAttribute(
didSeed, checksum, [], value, { from: owner })
- await didRegistry.enableAndMintDidNft721(did, 0, true, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 0, true, nftMetadataURL, { from: owner })
const nftOwner = await nft.ownerOf(did)
assert.strictEqual(owner, nftOwner)
- await didRegistry.burn721(did,
- {
- from: owner
- }
- )
-
+ await didRegistry.burn721(did, { from: owner })
await assert.isRejected(nft.ownerOf(did))
+
+ const _nftURI = await nft.tokenURI(did)
+ assert.strictEqual(nftMetadataURL, _nftURI)
+ })
+
+ it('Should work with an empty NFT Metadata URL', async () => {
+ const didSeed = testUtils.generateId()
+ const did = await didRegistry.hashDID(didSeed, owner)
+ const checksum = testUtils.generateId()
+
+ await didRegistry.registerAttribute(
+ didSeed, checksum, [], value, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 0, true, '', { from: owner })
+
+ const nftOwner = await nft.ownerOf(did)
+ assert.strictEqual(owner, nftOwner)
+
+ const _nftURI = await nft.tokenURI(did)
+ assert.strictEqual('', _nftURI)
})
it('The royalties should be initialized and retrieved (ERC-2981)', async () => {
@@ -121,7 +136,7 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
await didRegistry.registerAttribute(
didSeed, checksum, [], value, { from: owner })
- await didRegistry.enableAndMintDidNft721(did, 10, true, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 10, true, nftMetadataURL, { from: owner })
const nftOwner = await nft.ownerOf(did)
assert.strictEqual(owner, nftOwner)
@@ -138,7 +153,7 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
await didRegistry.registerAttribute(
didSeed, checksum, [], value, { from: owner })
- await didRegistry.enableAndMintDidNft721(did, 0, true, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 0, true, nftMetadataURL, { from: owner })
const nftOwner = await nft.ownerOf(did)
assert.strictEqual(owner, nftOwner)
@@ -151,7 +166,7 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
await didRegistry.registerAttribute(
didSeed, checksum, [], value, { from: owner })
- await didRegistry.enableAndMintDidNft721(did, 0, false, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 0, false, nftMetadataURL, { from: owner })
await assert.isRejected(nft.ownerOf(did))
@@ -167,7 +182,7 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
const checksum = testUtils.generateId()
await didRegistry.registerAttribute(
didSeed, checksum, [], value, { from: owner })
- await didRegistry.enableAndMintDidNft721(did, 0, false, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 0, false, nftMetadataURL, { from: owner })
await didRegistry.mint721(did, { from: owner })
let nftOwner = await nft.ownerOf(did)
@@ -190,11 +205,11 @@ contract('Mintable DIDRegistry (ERC-721)', (accounts) => {
await assert.isRejected(
// Must not allow to initialize NFTs if not the owner
- didRegistry.enableAndMintDidNft721(did, 0, true, { from: other }),
+ didRegistry.enableAndMintDidNft721(did, 0, true, nftMetadataURL, { from: other }),
'Only owner'
)
- await didRegistry.enableAndMintDidNft721(did, 0, true, { from: owner })
+ await didRegistry.enableAndMintDidNft721(did, 0, true, nftMetadataURL, { from: owner })
await assert.isRejected(
// Must not allow to mint tokens without previous initialization
didRegistry.mint721(did, { from: other }),
diff --git a/test/unit/registry/MintableDIDRegistry.js b/test/unit/registry/MintableDIDRegistry.js
index b12a6328..1ef068ee 100644
--- a/test/unit/registry/MintableDIDRegistry.js
+++ b/test/unit/registry/MintableDIDRegistry.js
@@ -17,6 +17,7 @@ contract('Mintable DIDRegistry', (accounts) => {
const other = accounts[2]
const consumer = accounts[3]
const value = 'https://nevermined.io/did/nevermined/test-attr-example.txt'
+ const nftMetadataURL = 'https://nevermined.io/metadata.json'
let didRegistry
let didRegistryLibrary
let didRegistryLibraryProxy
@@ -100,7 +101,7 @@ contract('Mintable DIDRegistry', (accounts) => {
const checksum = testUtils.generateId()
await didRegistry.registerMintableDID(
- didSeed, checksum, [], value, 20, 0, constants.activities.GENERATED, '', { from: owner })
+ didSeed, checksum, [], value, 20, 0, constants.activities.GENERATED, nftMetadataURL, { from: owner })
await didRegistry.mint(did, 20, { from: owner })
let balance = await nft.balanceOf(owner, did)
@@ -114,6 +115,9 @@ contract('Mintable DIDRegistry', (accounts) => {
balance = await nft.balanceOf(owner, did)
assert.strictEqual(15, balance.toNumber())
+
+ const _nftURI = await nft.uri(did)
+ assert.strictEqual(nftMetadataURL, _nftURI)
})
it('Should initialize the NFT in the registration', async () => {
@@ -147,7 +151,7 @@ contract('Mintable DIDRegistry', (accounts) => {
await didRegistry.registerAttribute(
didSeed, checksum, [], value, { from: owner })
- await didRegistry.enableAndMintDidNft(did, 5, 0, true, { from: owner })
+ await didRegistry.enableAndMintDidNft(did, 5, 0, true, nftMetadataURL, { from: owner })
const balanceOwner = await nft.balanceOf(owner, did)
assert.strictEqual(5, balanceOwner.toNumber())
@@ -200,11 +204,11 @@ contract('Mintable DIDRegistry', (accounts) => {
await assert.isRejected(
// Must not allow to initialize NFTs if not the owner
- didRegistry.enableAndMintDidNft(did, 5, 0, true, { from: other }),
+ didRegistry.enableAndMintDidNft(did, 5, 0, true, nftMetadataURL, { from: other }),
'Only owner'
)
- await didRegistry.enableAndMintDidNft(did, 5, 0, true, { from: owner })
+ await didRegistry.enableAndMintDidNft(did, 5, 0, true, nftMetadataURL, { from: owner })
await assert.isRejected(
// Must not allow to mint tokens without previous initialization
didRegistry.mint(did, 1, { from: other }),