Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EIP-5553: Intellectual Property Representation with Royalties #5553

Merged
merged 51 commits into from
Sep 1, 2022
Merged
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
64cc7d0
ERC821
royosherove Aug 28, 2022
e5f9442
wording
royosherove Aug 28, 2022
43d82ff
discussions link
royosherove Aug 28, 2022
ce12bbe
fixes for EIP checks
royosherove Aug 28, 2022
418331a
fix bot reeview changes
royosherove Aug 28, 2022
e4e409e
fix validator checks
royosherove Aug 28, 2022
13e73ca
typos
royosherove Aug 28, 2022
9bd2c24
typos
royosherove Aug 28, 2022
22199a5
Assign EIP-5553
Pandapip1 Aug 28, 2022
cd3b7b4
Update eip-5553.md
royosherove Aug 28, 2022
0bb0c0b
Update eip-5553.md
royosherove Aug 28, 2022
0cb9da7
Fix codespell errors
Pandapip1 Aug 29, 2022
fa3e6c8
* Added security considerations
royosherove Aug 29, 2022
25f7ec0
Reference implementation section
royosherove Aug 29, 2022
d2901eb
shorten abstract
royosherove Aug 29, 2022
ee45fd3
Merge branch 'master' into master
royosherove Aug 29, 2022
e506f19
fix link
royosherove Aug 29, 2022
fbabac0
Merge branch 'master' of https://github.com/royosherove/EIPs
royosherove Aug 29, 2022
57d9a22
link fix
royosherove Aug 29, 2022
6058021
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
9ef51b1
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
de8d343
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
085bbc0
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
4a38d7c
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
2c95a52
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
f02b882
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
77bc6bf
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
5934dd1
Fix wording
royosherove Aug 30, 2022
7d64638
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
eec4559
wording
royosherove Aug 30, 2022
8e5a2ab
Merge branch 'master' into master
royosherove Aug 30, 2022
659aa14
move rationale up
royosherove Aug 30, 2022
e0444d8
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
3b98f0d
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
388c586
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
5cc7c17
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
fb12f87
Update EIPS/eip-5553.md
royosherove Aug 30, 2022
b131471
Merge branch 'master' into master
royosherove Aug 30, 2022
d2d89b7
wording
royosherove Aug 30, 2022
dfed4f8
Merge branch 'master' into master
royosherove Aug 30, 2022
41a8e48
Merge branch 'master' into master
royosherove Aug 30, 2022
f0ca8b3
Update eip-5553.md
royosherove Aug 30, 2022
f7a6612
Update eip-5553.md
royosherove Aug 30, 2022
53fe79b
Update eip-5553.md
royosherove Aug 30, 2022
ab8e3a8
Wording.
royosherove Aug 31, 2022
6dcce25
Merge branch 'master' into master
royosherove Aug 31, 2022
8fe17d9
Grammar fix in specification
royosherove Aug 31, 2022
fedd2b0
Code renames
royosherove Aug 31, 2022
ce55307
Merge branch 'master' into master
royosherove Aug 31, 2022
42550bd
Merge branch 'master' into master
Pandapip1 Sep 1, 2022
215d74c
Fix grammar and spelling
Pandapip1 Sep 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 255 additions & 0 deletions EIPS/eip-5553.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
---
eip: 5553
title: Representing IP and its Royalty Structure
description: A way of representing intellectual property works and their respective royalty rights on chain
author: Roy Osherove (@royosherove)
discussions-to: https://ethereum-magicians.org/t/eip-821-simple-works-royalty-interest-representation-standard/10551
status: Draft
type: Standards Track
category: ERC
created: 2022-08-17
requires: 20, 721
---

## Abstract
royosherove marked this conversation as resolved.
Show resolved Hide resolved
This proposal introduces a generic way to represent intellectual works on chain, along with a refined royalty representation mechanism and associated metadata link. This standard is not associated with a specific type of work and could represent many types of works such as musical works, videos, books, images, and more.
The standard is kept very generic on purpose to allow the industry to evolve new ecosystems that can all rely on the same basic standard at their core.

This standard allows market participants to:
1) Observe the canonical on-chain representation of an intellectual work
2) Discover its attached metadata
3) Discover its related royalty rights holders
4) In the future, this will enable building registration, licensing, and payout mechanisms for intellectual property assets.

## Motivation

There is no accepted standard mechanism to license a work or to represent it, except using traditional NFTs. But regular NFTs only represent a collectible item use case, and cannot easily represent more complicated use cases of licensing a work for different types of uses.
To enable such mechanisms, a more robust mechanism is needed to:
1) Declare that a work exists, SEPARATELY from its purchase ability
2) Declare possibly multiple interested parties to be paid for such work

For 1, no standard exists today.

For 2, there are regular split standards based on NFT purchases, or through mechanisms like 0xsplits. While these solve the main problem, they do not contain the ability to name multiple types of collaboration participants.



## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

**contracts that want to represent a work on chain MUST implement [EIP-721](./eip-721.md) AND this Proposal**

This standard extends [EIP-721](./eip-721.md) with the following `IWorksRegistration` interface.
Implementers of this standard **MUST** have all of the following functions:

### royaltyRightsTokens() function
This function MUST return an array of addresses related to [EIP-20](./eip-20.md) tokens that MUST represent royalty rights to different types of interested parties. These royalty rights tokens represent a more granular and streamlined way to declare royalty splits for multiple collaboration participants for the creation of the work.

For example, for a musical work, we might have two tokens representing the composition/writing/publishing royalty rights side, and the recording/master side. These royalty rights tokens are distributed to the collaboration participants and can later be queried by the various holders, for purposes of distribution of royalties - i.e if you hold 10% of a royalty rights token, you will get 10% of financial distribution related to that type of royalty.

### metadataURI() function
This function MUST return the URI to a metadata file containing any required metadata for the work, or an empty string. Each work type MAY implement its metadata standard, defined separately. The file MUST be hosted in IPFS or Arweave or other decentralized content-addressable systems in which the file's contents are not changeable without changing the URI.

### changeMetadataURI() function
This function allows changing the metadata URI to point to a new version of the metadata file. Calling this function MUST trigger the event `MetadataChanged` in case of success.

### ledger() function
This function MUST return the address of the registry or registrar contract, or an EOA account that initialized the work and associated royalty tokens. A work MAY be registered in multiple places by different actors for different purposes. This enables market participants to discover which registry mechanism is the parent of the work and might have special access rights to manage the work.

```solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/interfaces/IERC165.sol';


///
/// @dev Interface for Simple Works Registration Standard
///
interface IWorksRegistration is IERC165 {

/// @notice Called with the new URI to an updated metadata file
/// @param _newUri - the URI pointing to a metadata file (file standard is up to the implementer)
/// @param _newFileHash - The hash of the new metadata file, for future reference and verification
function changeMetadataURI(string memory _newUri, string memory _newFileHash) external ;
royosherove marked this conversation as resolved.
Show resolved Hide resolved

/// @return array of addresses of ERC20 tokens representing royalty rights in the work
/// @dev i.e implementing ERC5501 (IRoyaltyInterestToken interface)
function royaltyRightsTokens() external view returns (address[] memory) ;

/// @return the address of the contract or EOA that initialized the work registration
/// @dev i.e a registry or registrar, to be implemented in the future
function ledger() external view returns (address) ;

/// @return the URI of the current metadata file for the work
function metadataURI() external view returns (string memory) ;

/// @dev event to be triggered whenever metadata URI is changed
/// @param byAddress the addresses that triggered this operation
/// @param oldURI the URI to the old metadata file before the change
/// @param oldFileHash the hash of the old metadata file before the change
/// @param newURI the URI to the new metadata file
/// @param newFileHash the hash of the new metadata file
event MetadaDataChanged(address byAddress, string oldURI, string oldFileHash, string newURI, string newFileHash);
}
```


## Rationale

### Returning an array of EIP-20 tokens presents a more robust royalty rights structure/

Current royalty implementations deal only with a single type of royalty payment: NFT sales. They also only allow a single type of royalty - i.e you cannot have different royalty rights owners receive a royalty based on different licensing types.
In other words, currently, a royalty split works the same way no matter what type of purchase or license deal has happened, for all parties involved.

With this proposal, multiple **types** of royalty rights are allowed. A classic case is the music industry in which you have writing/composition royalties, and recording/master royalties. Different licensing types will pay different percentages to different parties based on context.

In the case of a song cover, a license payment formula can be created so that that
a) Original work's writers get paid for using the lyrics or composition of the song
b) recording artists of the original song do not get paid since their recording is not used
c) recording artists of the new work will get paid
d) there are no writing royalties for the creators of the cover.

Moreover, this EIP has a single structure that connects to all types of royalty types and allows finding them more easily.
Lastly, moving EIP-20 tokens around is much easier than managing an 0xsplits contract.

### Separating the work from the sellable NFT enables scaling licensing types
By separating the canonical version of the work from its various licensed uses (NFT purchase, streaming, usage of art, etc..) this EIP introduces a path for an ecosystem of various license types and payment distributions to evolve.
In other words, when people use this scheme, they won't start by creating music NFT or art NFT, they start by creating the works registration and then create types of licenses for it, each as its own sellable NFT, possible in the form of [EIP-5218](./eip-5218.md) or other formats.

### A single pointer to the work's metadata
The work points to metadata housed in IPFS or Arweave and allows changing it and keeping track of the changes in a simple and standard way. Today the only metadata standard is NFT metadata extension, but we do not know which standard the document adheres to. With different work types, different metadata standards for different work types can be formulated and have a simple easy place to discover attached metadata.

## Reference Implementation

#### Implementing a Musical IP Representation (MIPR for short) based on IWorksRegistration
```solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import "./interfaces/IWorksRegistration.sol";
import "./interfaces/Structs.sol";


contract MusicalIP is ERC721, IWorksRegistration {
address public songLedger;
address public compToken;
address public recToken;
string public metadataURI;
string public fileHash;
uint256 public tokenId;
bool public activated =false;

function supportsInterface(bytes4 interfaceId) public view virtual override( ERC721, IERC165) returns (bool) {
return
interfaceId == type(IWorksRegistration).interfaceId ||
super.supportsInterface(interfaceId);
}

function getInterfaceId() public pure returns (bytes4){
return type(IWorksRegistration).interfaceId;
}

constructor (
uint256 _tokenId,
address _songLedger,
SongMintingParams memory _params,
address _compAddress,
address _recAddress
)
ERC721(_params.shortName, _params.symbol){

songLedger = _songLedger;
compToken = _compAddress;
recToken = _recAddress;
metadataURI = _params.metadataUri;
fileHash = _params.fileHash;
tokenId = _tokenId;

_safeMint(_songLedger, _tokenId);
emit Minted(_params.shortName,_songLedger,_compAddress,_recAddress,_msgSender(),tokenId,_params.metadataUri);
}

function changeMetadataURI(string memory _newURI,string memory _newFileHash) public
{
string memory oldURI = metadataURI;
string memory oldHash = fileHash;
metadataURI = _newURI;
fileHash = _newFileHash;

emit MetadataChanged(oldURI, oldHash,_newURI,_newFileHash);
}

function royaltyRightsTokens() external view returns (address[] memory) {
address[] memory items = new address[](2);
items[0] = compToken;
items[1] = recToken;
return items;
}
function ledger() external view returns (address) {
return songLedger;
}

event MetadataChanged(
string oldUri, string oldFileHash,
string newUri, string newFileHash
);
event Minted(
string abbvName,
address ledger,
address compToken,
address recToken,
address creator,
uint256 tokenId,
string metadataUri
);
}



```

#### Deploying a new work of music using a simple song registry contract

```solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/utils/Counters.sol";
import "./MusicalIP.sol";
import "./CompositionRoyaltyToken.sol";
import "./RecordingRoyaltyToken.sol";


contract SimpleSongLedger is IERC721Receiver {
using Counters for Counters.Counter;
Counters.Counter private mipIds;
function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}

function mintSong(SongMintingParams memory _params) public {
CompositionRoyaltyToken comp = new CompositionRoyaltyToken(address(this),"SONGCOMP","COMP");
RecordingRoyaltyToken rec = new RecordingRoyaltyToken(address(this),"SONGREC","REC");
mipIds.increment();

MusicalIP mip = new MusicalIP(
mipIds.current(),
address(this),
_params,
address(comp),
address(rec)
);
}
}


```
## Security Considerations

There might be potential security challenges of attackers persuading holders of royalty rights tokens to send them those tokens and gaining royalty rights in various works. However, these are not specific to royalties and are a common issue with EIP-20 tokens.

In the case of the works registration ownership, it will be recommended that registry contracts will own the works registration and it will be non-transferrable (account bound to the registry that created it).

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).