EIP-4973 - Account-bound Tokens

Just for the record, I disagree that a “Soulbound Sword” makes sense as address bound. The sword is bound to a character usually, sometimes to an account, but the account can undergo credential changes, unlike an Ethereum address.

This statement is misinformation. An Ethereum account (e.g. a contract) can undergo credential changes, e.g. different EOAs can manage a contract’s functionality. It depends on the implementation of the contract but it is entirely possible.

Have we lost our path with this specification? I’m actively asking myself this question these days: Why? Because originally, I set up to define a token standard that is “ownership concept” neutral or non-skeuomorphic: And since we’re now defining consensual mintWithPermission instead of bumping the document’s status to “Review.”

Here’s what I deem immediately useful to the Ethereum community today.

A token standard document that carries as little implicit notion of private property as possible - the goal being to innovate on different kinds of property, e.g., “Harberger Property,” [1,2,3] partial common ownership [4], and to, e.g., replicate the true nature of bits on the internet [5, 6].

It may not be entirely clear to many, and we probably haven’t done the best job at communicating: But it’s clear that if we had configurable property that isn’t implicitly biased towards, e.g., giving all possible rights to the “owner,” at least in the self-referential digital space many call “web3,” we could attack such interesting problems.

Buterin et al.'s “Decentralized Society” contributes to the Account-bound tokens specification, despite scope-creeping the entire field: It unbundles the concept of ownership as a bucket of interaction rights.

“4.7”, the “Plural Property” section brilliantly identifies the challenges we want to address [7]:

  • web3 overemphasized the notion of “transferability” of property, making it impossible to represent simple and ubiquitous property contracts like an apartment lease.
  • Traditionally, property rights are defined in Roman tradition as bundles of rights:
    • rights to use property (“usus”)
    • rights to consume and destroy (“abusus”)
    • rights to profit (“fructus”)
  • In the real world, someone rarely possesses the “full bucket” of ownership rights.

So to re-iterate on the introduction of this post: I’ve become unsure if we haven’t lost our path here. For E.g. the argument that ABTs discourage key rotation is blatantly false and misguided in the actual context. It’s because truly our intent isn’t to “bind” to accounts: But more to establish a new and unbiased relationship between on-chain property and their subjects (users).

Consider the tables and chairs in a bar. They’re owned by the bar: But then nobody really owns a chair in a bar. You get up (e.g. to the toilet) and then in some social contexts and depending who you are and what peers are with you in the bar - your chair is free when you come back or it isn’t.

This is the type of new ownership experience I’m talking about. E.g. making a differentiation between possessing, squatting, and owning. Using, profiting, transferring, lending, destroying, remixing, etc.

For that, my initial design goal was to strip EIP-721 of all implicit notions of transferability and private property. Yes, we could have used more proper terminology like: “function controllerOf” rather than e.g. “function ownerOf” - but to me, there has always been the question of backward compatibility.

E.g. If we end up creating an entirely original token standard in a vacuum, like EIP-5114 - will there be adoption? Having recently been exposed to the “worse is better” idea [8], I’m still of the opinion that “worse” and hence backward-compatible, is better.

Still, now that we’ve successfully implemented function mintWithPermission in the reference implementation and since we’re now making normative statements about a user’s “abusus” rights (namely when it should be burnable), I’m wondering if we’re not getting overly biased again.

Here’s what I want for EIP-4973: I want to create the most minimal and backward compatible version of a token that carries as few implicit skeuomorphic ownership biases from our modern world as possible. I deliberately don’t want to replicate existing ownership experiences.

Then, and even though this may be to the detriment of some EIP editors that e.g. are asking for “censorship-resistant” tech (looking at you @MicahZoltu), I’d want to “finalize” EIP-4973 as a base token such that others can e.g. re-implement new and existing ownership experiences.

So how would we get there? E.g. I’d be happy to remove function burn again. I’d also be happy to put a statement in saying that this standard shouldn’t be used to bind tokens non-separable to an account. And I wanna frame it where this standard becomes the bare minimum boilerplate standard for an on-chain property.

I hope that sounds reasonable to everyone! How do we get there?



What was the motivation behind mintWithPermission ? Isn’t the goal already achieved by adding burn into the standard?

I would say mintWithPermission is too opinionated to be added in the specification, as it reduces the scope of application quite a bit.

I still feel like burn should stay in the standard as a way to publicly react to a specific SBT, and I think it would enlarge the scope of applications, without making any unnecessary assumption.

1 Like

I like mintWithPermission.
Means that the receiver can decide to mint it or not. If it’s from someone they know or are expecting it then this works for that.

It’s stops being tarnished with sh*t ABT tokens that you don’t want to spend the time and expense to burn, so you leave it and people get the wrong impression.

Therefore, I think burn is no longer necessary.

Agree that it can be a good way to use ABTs but I think it’s too opinionated to be put into the standard, imo it restrict use-cases for it quite a bit.

Entities can choose to implement the standard with mintWithPermission if they want to but ABT’s scope is way larger than that.

Btw, it’s not easy to decide where we draw the line between interface and implementation, but I feel like specific behavior like minWithPermission should be dealt with at impl. level

I suggest that we standardize mintWithPermission outside of this standard (in another EIP). It can also be useful for any EIP-721 token. And generally, we probably also want another variant of mintWithPermission where the from mints for the to (mintWithPermission is implemented where to needs permission from from).

1 Like

The tokens definitely do need to be transferrable, in case people want to rotate keys or if they want to move to a more effective system of organizing things.

But one should not be able to transfer tokens to a different human

One simple way to do it is to allow transfers only to accounts with the same label, where the label is a fully qualified name of the human.

In this case “Alice XYZ” will be able to transfer her tokens to another wallet with a label “Alice XYZ” but not to a wallet with a label "Bob 123’

1 Like

That is easy to overcome.
I set the sub-domain, I transfer the NFT, then I reset the sub-domain.

I don’t think there is a way to enforce that limitation. So, the possibilities are either to allow transfers (maybe blocking approvals) or to disallow them.

It seems to me a solution similar to the attempts of forcing a royalty on ERC721, despite that the standard does not support it.
If I want to abuse that, how can someone block me from implementing a “mintWithPermission” function that actually does not require any permission?

Major changes are coming to ERC4973: We’re extending the Soulbound item capabilities of World of Warcraft. Namely, because you can “give” and “take” items to others.

  • You can “take” an item from a dragon
  • You can “give” an item to a friend
  • You can “equip” an item, showing it to everyone in Ogrimar/Stormwind or you can choose to “unequip” it.
  • I’ve rolled back the Attest/Revoke events. It’s now Transfer again.

I’ll take some time to adjust the standard’s document, but the new interface is actively being developed over in the reference implementations GitHub: Language develop standard towards Soulbound items · rugpullindex/ERC4973@27a62d1 · GitHub

In case you’re looking for a naive implementation of “Soulbound tokens” that non-separably binds an EIP-721 to an account, I recommend you check out EIP-5192 - Minimal Soulbound NFTs

1 Like

Have been thinking more about the inclusion of balanceOf. The original argument about it needing it to inform the reputation based on number of ABTs you have seems flawed.

For example, if you have 5 ABTs, with 5 different tokenURIs, it may not very useful to know that a user has 5 ABTs in total. It is perhaps rather more useful to know if a user has an ABT of a certain type of tokenURI :thinking:

It is perhaps rather more useful to know if a user has an ABT of a certain type of tokenURI :thinking:

I believe it was me that mentioned the use case for balanceOf. I can imagine that doing the spec for this EIP is particularly difficult as it has to be loose enough to fit many use cases, and remain as minimal as possible.

You’re saying that tokenURI indicates a “certain type” but that I believe is implementation specific. For example, each student receives individual tokenURI’s that says they passed (with additional info like grade etc.) but they could be for the same qualification type. It could be that the ABT contract address represents a type (of qualification), or does it? There could be separate ABT token contracts for each school year, or departments etc. Again, implementation specific.

For a community giving the same type of ABT token to an address (the use case I mentioned earlier), balanceOf would indicate strength of e.g. approval/trust given from the community; each tokenURI could point to text input of why a particular community member decided to give this ABT token. In this case, the ABT contract address could indicate a certain type. Still an implementation detail I feel that can work within the spec.


I know that the latest spec has removed Revoke but I believe a rethink is necessary.

Hard to predict of course without running this in the wild but imagine a scenario that an ABT has built great reputation but was somehow duped by an outfit that then did something terrible, like a rugpull. Then anyone who had built up a good reputation/business from holding that ABT would then be affected unfairly.

A worse scenario could be that the community is unaware about the bad actor, since they still hold the ABT that continues to affirm them as a good actor, unknowingly, relationships would continue as normal.

I believe in these scenarios, the issuer should be able to recall the ABT from the bad actor, in order to save the ABT’s trust level and for it not to affect all others holding and the issuer of the token unduly.

I understand the argument that it can be used by the issuer for manipulation but any well functioning community would devalue that ABT token anyway.

So a rethink to introduce Revoke again in some form, I believe is necessary, else it could seriously affect trust/adoption if the above type of scenarios happen often.

Hey, we just renamed Revoke to Transfer(owner, address(0), tokenId) in the reference implementation. It’s syntactically it’s different, semantically it is the same.

1 Like

Updated EIP-4973 with the long-intended changes here: Adjust EIP-4973 interface to add `function give(...)` and `function take(...)` by TimDaub · Pull Request #5209 · ethereum/EIPs · GitHub

  • Added a function give and a function take that both respectively allow minting a token consensually between two addresses using EIP-2098 and EIP-1271 (so can be used to proxy consent too)
  • Backtrack to event Transfer
  • Introduce the mental model of “equipping” and “unequipping” tokens as metaphor for “on-chain” vs “off-chain.” Hence, rename function burn(...) to function equip(...)

As there have been questions about how to generate the compact signature required to pass function give(...) and function take(...) and since specifying the code within the .md document, I’ve opted to create a JavaScript function using ethers that can generate the signature and also informs the structure of the inputs.

The resulting section “EIP-712 Typed Structured Data Hashing and EIP-2098 Compact Signature Creation” is more concise now and points to the .mjs files: EIP-4973: Account-bound Tokens

Just released v0.4.0 of the ABT reference implementation to catch up with the specification: ERC4973/changelog.md at master · rugpullindex/ERC4973 · GitHub

posted a rant on Twitter about the toxicity of working on SBTs in the Ethereum community: https://mobile.twitter.com/timdaub/status/1557997701874286593

1 Like

We moved EIP-4973 into “Review”.