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

Creates EIP-5114: Soulbound Token #5114

Merged
merged 12 commits into from Jun 10, 2022
64 changes: 64 additions & 0 deletions EIPS/eip-5114.md
@@ -0,0 +1,64 @@
---
eip: 5114
title: Soulbound Token
description: A token that is attached to a "soul" at mint time and cannot be transferred after that.
author: Micah Zoltu (@MicahZoltu)
discussions-to: https://ethereum-magicians.org/t/eip-5114-soulbound-token/9417
status: Draft
type: Standards Track
category: ERC
created: 2022-05-30
requires: 721
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this requirement necessary? I believe you can bind EIP5114 to any address?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EIP references EIP-721, so it requires it (not all editors agree on this policy).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, in abstract it says that EIP5114 requires it to be bound to another NFT, and gives example of EIP721. In section "Backwards Compatibility" Its stated that EIP721 HAS to be used as a soul. I think the EIP should be more specific if EIP721 as a soul is mandatory, or is some other token or EIP also acceptable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any EIP that matches the interface ownerOf(uint256 id) I think is the actual requirement. EIP-721 is an example of that, as is EIP-5114.

---

## Abstract
A soulbound token is a token that is bound to another ERC-721 token when it is minted, and cannot be transferred/moved after that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why this EIP needs to exist. Are there many use cases for nontransferable tokens? Why should implementers prefer this EIP over, say, EIP-4973?

Seems like this EIP needs a Motivation section ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you did there. I may consider adding a motivation after this has merged as a draft, but as it isn't required I would like to move forward without it for now.

## Specification
```solidity
interface IERCXXXX {
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
// fired anytime a new instance of this token is minted
// this event **MUST NOT** be fired twice for the same `tokenId`
event Mint(uint256 indexed tokenId, address indexed erc721Token, uint256 indexed erc721TokenId);

// returns the ERC-721 token that owns this token.
// this function **MUST** throw if the token hasn't been minted yet
// this function **MUST** always return the same result every time it is called after it has been minted
// this function **MUST** return the same value as found in the original `Mint` event for the token
function ownerOf(uint256 index) external view returns (address erc721Token, uint256 erc721TokenId);

// returns a censorship resistant URI with details about this token collection
// the metadata returned by this is merged with the metata return by `tokenUri(uint256)`
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
// the tokenUri **MUST** be immutable and content addressable (e.g., ipfs://)
// the tokenUri **MUST NOT** point at mutable/censorable content (e.g., https://)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as much as I appreciate the sentiment, it seems out-of-scope to me to specify the nature of the storage, as it is outside the Ethereum network

the requirement for immutability is also questionable to me - I could see a use for a URI that can deliberately be changed or change itself over time

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't constrain the storage, then the tokens functionally become mutable. By asserting immutability throughout, we enable applications/users to build caching systems that they cannot built if we only encourage the behavior.

Copy link
Contributor

@TimDaub TimDaub May 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Immutable data doesn't exist. From what I understand, only content-integrity assuring identifiers exist that can indicate mutation. Replication can be used to fallback on non-mutated backups. IMO, e.g. asking to "content-address" resources in tokenURI would fit better.

"Censor"able is for sure the wrong term as it can mean all sorts of non technical stuff.

Anyways, I agree with @wschwab. For interoperability e.g. between wallets, whether data is mutable or not is out of scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following your claim here that immutable data doesn't exist. If you ask IPFS for something by content hash, you will get either that exact thing, or you will get nothing (if it can't be found on the network). There is no situation where you would get a different result from someone else or at a different point in time.

Regarding censorable content: I tend to agree that censorable content is fuzzy here, and I wish we could nail down something a bit more concrete. What I want to avoid is people linking to content that a provider can remove at a future point in time. The goal with these badges is that they are permanent, they aren't something that comes and goes over time. If you link out to a traditional https resource, the host of that resource/owner of the domain can remove it. Similarly, the domain may be seized and changed or taken away. Something like IPFS on the other hand allows anyone to ensure the content survives, you don't have to rely on a single operator.

Copy link
Contributor

@TimDaub TimDaub May 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"immutable data"/content-addressable criteria:

I agree with you that some networks of computers can create the illusion that some data is immutable. But on the basis of a principle, the data isn't immutable. E.g. on IPFS/Ethereum/Bitcoin when you run a full node, there's nothing stopping you from going into the chain data directory and switching a few bits. You can always mutate the data. It's likely though that the system maintaining the data will notice and e.g. notably fail or repair itself. That's what I meant by "Replication can be used to fallback on non-mutated backups (in a distributed system)."

How I'd describe it is that by requesting data using content-addressing, a user can guarantee to themselves that they'll either receive the exact data corresponding to the content-address, or nothing at all (e.g. when content-address and data don't align).

I think "content-addressing" is a better term than e.g. "immutable". I guess another usable term could be "tamper-proof" or "tamper-resistant."

data availability guarantees/non-censorable:

I'd strongly opt for e.g. "highly-available data" rather than "non-censorable." From my perspective, censorship is about withholding information in the interest of a few. Data availability, on the other hand, is a term from the blockchain research world that describes the concept of retaining and serving data within e.g. a p2p network. E.g. all EVM storage has high data availability, and anything stored in the Bitcoin blockchain too.

For IPFS, actually, it doesn't have data availability built-in. To pin an IPFS content hash, one has to personally deploy a dedicated node that continues to make the content hash available within the distributed hash table. IMO, if you wanted the ultimate data availability for Soulbound Badges, it'd probably be best to store the contents of tokenUri on-chain as e.g. a struct. I'm not kidding. It's because if you outsource delivering extremely high-quality data availability to other networks not aligned with Ethereum (e.g. IPFS), it may be that one day they just go down/stop working while Ethereum still works.

Now talking about storing the badge's metadata on-chain, I think it's obligatory I bring up #735

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets move this conversation over to the discussions-to link as I'm hoping this will get merged as a draft soon and I don't want this conversation to get lost.

// data from `tokenUri` takes precedent over data returned by this method
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
// any external links referenced by the content at `tokenUri` also **MUST** follow all of the above rules
function collectionUri() external view returns (string tokenUri);

// returns a censorship resistant URI with details about this token instance
// the tokenUri **MUST** be immutable and content addressable (e.g., ipfs://)
// the tokenUri **MUST NOT** point at mutable/censorable content (e.g., https://)
// data from this takes precedent over data returned by `collectionUri`
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
// any external links referenced by the content at `tokenUri` also **MUST** follow all of the above rules
function tokenUri(uint256 tokenId) external view returns (string tokenUri);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't using tokenURI here be better than tokenUri as then the bytes4 signature of the function address in Solidity is equal to e.g. that of EIP-721?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered it, but I don't think 721 compatibility matters much because the ownerOf signature is different and owner lookups require custom code, so this token won't natively work with existing ERC-721 tooling.

Perhaps there are specific tools that don't need to do owner lookups but do need to URI lookups that would benefit from consistency across methods?

Personally I would like to see a compelling reason to break the superior (IMO) naming convention of capitalizing only the first letter of acronyms (it avoids situations like XMLHTTPRPC with XmlHttpRpc).

Copy link
Contributor

@TimDaub TimDaub May 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO naming convention arguments should be out of scope of this EIP. But a separate EIP could make normative statements on function capitalization conventions.

I was mainly arguing for consistency with EIP-721 but it's not a hard objection from my side.

}
```

## Rationale
### Immutability
By requiring that tokens can never move, we both guarantee non-seperability and non-mergability among collections of soulbound tokens that are bound to a single NFT while simultaneously allowing users to aggressively cache results.
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
### Content Addressible URIs Required
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
Soulbound tokens are meant to be permanent badges/indicators attached to a persona. This means that not only can the user not transfer ownership, but the minter also cannot withdraw/transfer/change ownership as well. This includes mutating or removing any remote content as a means of censoring or manipulating specific users.
### No Specification for tokenUri Data Format
The format of the data pointed to by `collectionUri()` and `tokenUri(uint256)` is intentionally left out of this standard in favor of separate standards that can be iterated on in the future. The immutability constraints are the only thing defined by this to ensure that the spirit of this token is maintained, regardless of the specifics of the data format.

## Backwards Compatibility
This is a new tokene type and is not meant to be backward compatible with any existing tokens other than using ERC-721 as souls.
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved

## Security Considerations
Users of tokens that claim to implement this EIP must be diligent in verifying they actually do. A token author can create a token that, upon initial probing of the API surface, may appear to follow the rulse when in reality it doesn't. For example, the contract could allow transfers via some mechanism and simply not utilize them initially.
MicahZoltu marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use one space after each period.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


It should also be made clear that Soulbound tokens are not bound to a human, they are bound to a persona. A persona is any actor (which could be a group of humans) that collects multiple soulbound tokens over time to build up a collection of badges. This persona may transfer to another human, or to another group of humans, and anyone interacting with a persona should not assume that there is a single permanent immutable human behind that persona.

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