Skip to content

Commit

Permalink
Merge pull request #213 from nevermined-io/feature/nft_metadata
Browse files Browse the repository at this point in the history
Adding support to NFTs metadata (ERC-721 & 1155)
  • Loading branch information
aaitor authored Jan 17, 2022
2 parents a26f27d + 0d49fbf commit 90b86f0
Show file tree
Hide file tree
Showing 11 changed files with 360 additions and 116 deletions.
110 changes: 89 additions & 21 deletions contracts/registry/DIDRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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(
Expand All @@ -72,22 +72,65 @@ 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,
_royalties,
_mint
_mint,
_nftMetadata
);
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 _nftMetadata refers to the url providing the NFT Metadata
* @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 _nftMetadata
)
public
onlyValidAttributes(_nftMetadata)
returns (uint size)
{
uint result = registerDID(_didSeed, _checksum, _providers, _url, _activityId, '');
enableAndMintDidNft721(
hashDID(_didSeed, msg.sender),
_royalties,
_mint,
_nftMetadata
);
return result;
}



/**
* @notice Register a Mintable DID.
*
Expand All @@ -101,7 +144,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(
Expand All @@ -112,19 +155,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.
Expand All @@ -134,42 +177,67 @@ 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)
returns (bool success)
{
didRegisterList.initializeNftConfig(_did, _cap, _royalties);

if (_mint) {

if (bytes(_nftMetadata).length > 0)
erc1155.setNFTMetadata(uint256(_did), _nftMetadata);

if (_royalties > 0)
erc1155.setTokenRoyalty(uint256(_did), msg.sender, _royalties);

if (_mint)
mint(_did, _cap);
}

return super.used(
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)
returns (bool success)
{
didRegisterList.initializeNft721Config(_did, _royalties);

if (_mint) {
if (bytes(_nftMetadata).length > 0)
erc721.setNFTMetadata(uint256(_did), _nftMetadata);

if (_royalties > 0)
erc721.setTokenRoyalty(uint256(_did), msg.sender, _royalties);

if (_mint)
mint721(_did);
}

return super.used(
keccak256(abi.encode(_did, 1, _royalties, msg.sender)),
Expand Down
2 changes: 1 addition & 1 deletion contracts/registry/DIDRegistryLibrary.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
92 changes: 92 additions & 0 deletions contracts/token/NFTBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
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';
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 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;

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
{
_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,
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;
}

}
Loading

0 comments on commit 90b86f0

Please sign in to comment.