If there’s ever any interest in having tokens directly on the main network, I think it makes the most sense to have it be as unobtrusive as possible and have it work as closely to nano as possible.
My idea is simple: every account gets a single contract address field and a token balance, which means that any nano account can hold both nano and ONE other token. Send and receive blocks for tokens would work exactly the same as for nano (and in fact you could send both nano and the token in the same block) Accounts would only be able to receive tokens if the corresponding send block had the same token contract address. The only exception to this is if the account has no token balance whatsoever, in which case it could receive tokens from any contract address and that would allow the contract address to change.
How are token contracts created? New accounts, in their open block, can designate that the receipt of the open amount in nano be instead delegated to being a token with the very same account being the contract address. That account then holds the tokens for their contract and may distribute it at their discretion.
How would this work in practice?
Say you want to create an asset-backed wrapped Bitcoin, and you want the supply to be 10,000 (10^4) BTC. Since 1BTC=10^8 sats, 10,000 BTC is 10^4*10^8=10^12 sats.
To create this, all you need to do is make a new account, send it 10^12 raw (which is a mere 1/10^18 nano), and on the open block designate it as a token account. That account now has 10^12 token-raw (taw? Name can be workshopped) that it can distribute as needed.
What are the benefits of this implementation?
Low increase of storage requirement for nodes: the use of just two fields doesn’t massively change the size of a block. By permitting only one token contract per account, you don’t have to worry about keeping track of a million different tokens.
Pruning-resistant: the fact that sending is purely based on the token balance of the frontier (just like nano) means you don’t have to worry about whether or not you can trace to a genesis.
Prevents permanent loss of tokens: although an account can only hold one token at a time, the fact that the contract address the account uses can change if it holds no tokens means that sending the wrong type of token doesn’t make them lost forever. Say your nano account has a wrapped Bitcoin as its token, but you accidentally sent wrapped ethereum to it. To recover the wrapped ethereum, you can make a new account with wrapped Bitcoin as its token, send all your wrapped Bitcoin to it, and now that your token balance is zero, you can change your first account’s token contract and receive the pending wrapped ethereum.
Adds additional value to nano: even though the Bitcoin example only costs 10^12 raw, making lower value tokens with many digits of precision will cost more nano to create it. With this implementation, not only do you need to own nano to create contracts, the total supply of nano will go down over time as more contracts are created; both of these add value to nano.
Can be atomically swapped without trust: this implementation works with my Trustless Swap procedure.
Does not require a massive change to the current state of nano: all existing accounts can be considered to have a token balance of zero with a null contract address, which would allow a seamless transition to the new block format.
I would love to hear any thoughts/criticisms about this possible implementation!
Edit: another benefit is that the inability to set your contract address to anything random is that it prevents the ledger from being used to store unrelated data, a concern raised by NF about implementations that allow for that.