Can I Make Non-Transferable (or selectively transferable) Tokens on Cardano?

Essentially I want to mint an NFT/NTT to use it as a part of an identity verification process.

The NFT would be minted in specific conditions and be used for governance and identity within an app ecosystem. I would like users to only be able to accumulate the NFT and the asset would only stay on the wallets/addresses that own the token as it helps prevent some undesirable consequences of having the NFT being transferable to different wallets.

1 Like

The NFT would have to reside at a smart-contract address, not an ordinary wallet address, if you want to control its transferability.


I see, so there is currently no way to make a token that only stays within a specific wallet. You would have to make each user have an entire smart contract address that is uniquely theirs and create NFTs in it.

I want them to be able to transfer the NFT to the addresses they have within that wallet though and just that wallet. Still no way to do such a thing so far?

No. Reported.

Each user would have it’s own smart contract that is uniquely theirs.

If “wallet” means the set of addresses derived from a seed, then wallets will never support non-transferable tokens. The only control on wallet addresses is that each transaction be signed by the owner of the wallet.

If “wallet” means the user interface that lets you view assets, submit transactions, etc., then I think that eventually there will be wallets where you can manage smart–contract addresses. Such software would support addresses in the wallet that are from keys and also addresses that are from contracts.


I see, so instead of thinking about it from a stop the tokens themselves moving in a different wallet perspective, I should think about it in the current moment from the perspective of issuing the user an address unique to them in a read-only format.

So essentially I can make the smart contract, make one contract address unique per user and ask the user to only purchase the NFT through their own issue SC and view it through the explorer.

So same contract parameters, different addresses per user.

Yes, I think what you describe is the decentralized approach to non-transferable tokens. (The centralized approach would be for you to manage private keys and not let the user have those keys.)

I could imagine a “smart wallet” user interface to handle non-transferable tokens:

  1. A user enters one of their regular wallet addresses—not their keys, just the public address.
  2. The user can then view the list of non-transferable-token address(es) they have, and they can view the tokens in those address(es).
  3. If they want to perform a transaction, the smart wallet would build the transaction. Depending on conditions, the underlying smart contract might or might not let them transfer tokens. The transaction would have to be signed by their regular wallet before it could be submitted.

Presumably, the Plutus Application Backend (PAB) and other emerging tools would make this use case easy.

1 Like

I think this nails the best compromise perfectly!

I’m struggling a little to conceptualise part 2, it sounds to me like:

  1. The user’s public address would be used to verify which NFT addresses they have - this is only at address level. This would allow the “smart-wallet” to show the NFT ownership for this wallet address only.
  2. Therefore, could I make the SC so that they can only spend from that specific address to purchase the NFT from the smart contract FOR that specific address “verifier?” (Not necessarily a problem, just helps with scalablility and flexibility). Ideally, I want individual addresses to be able to accumulate as much NFT as they need.
  3. If no to the above, all I would have to do is remind the user that in order to build the NFT amount on this address, they will need to perform the transaction from the same address. Other addresses will not build the NFT amount on the address but it will build it on a new address. Although this has the downside of incurring transaction fees to make sure the UTXO input is from the same address whenever the user does an intrawallet transfer.

However, this also may confer the advantage of allowing all wallet addresses to build NFT at different rates to help secure the ID verification process. At the end of the day, the wallet containing all the addresses has all of the total NFT.


This has been a wonderful talk. I might PM you for some more help :slight_smile: Thank you!

1 Like

Yes, items 1 and 2 in your last post are pretty much correct. There is a lot of flexibility possible, so the actual solution should be built around requirements and user experience.

Here are a couple more observations:

  1. One would start from a template for the smart contract (i.e., a smart contract parameterized by the public key hash of its “owner”), and that template can be specialized to actual smart contracts for the addresses of individual users.
  2. Discovering which contracts exist for an individual wallet might proceed as follows: (a) the user enters an address; (b) the service (web client, backend, or whatever) decomposes that address into the payment part and the staking part; (c) the service uses its knowledge of the staking part to query the blockchain to see which other addresses in that same wallet have ever been used; (d) the service combines each of those addresses with the smart-contract template to compute what the corresponding smart-contract address would be; (e) the service queries the blockchain to see if there are any tokens at any of those smart-contract addresses; (f) the service displays the results that list all of the tokens in smart-contract addresses derived from addresses in their wallet.
  3. The details of single vs multiple smart-contract addresses for the non-transferable NFTs are mostly just bookkeeping. In Daedalus and Yoroi, for instance, the user doesn’t see exactly which of their wallet addresses are holding which tokens. They just see the tokens are in the wallet. The wallet manages the details.

I’d be happy to discuss more directly.


This thread is more than a half year old - I wonder if there are any other Methods to create a non-transferable token. Something similar to a Soulbound Token.

1 Like