## Note: ordering NFT transactions with txpool tags
This note describes how the transaction *provides* and *requires* tags can be used to order transactions involving a single item in an NFT collection.
### The problem
The issue arises when multiple transactions initiated by different accounts involve the same NFT item.
*Example:*
Alice mints NFT, transfers it to Bob, Bob sells it Charlie, Charlie to Dave, and so on.
While it is straightforward to order Alice's transactions (as they originate from the same account), properly ordering transactions from different accounts can be challenging. Ordering by nonce obviously won't work here.
The transaction pool lacks information about the dependencies between those transactions. As a result, when these transaction are added to the pool, they may be executed in arbitrary order (using priority, transaction insertion time etc.) which may not guarantee the correct order. This could lead to some transactions failing.
While there may be other mechanisms ensuring proper ordering (e.g. batching, or sending transaction from proxy accounts), this note focuses on using transaction *tags*.
### What are tags?
For more information about tags, refer to [what are tags](https://hackmd.io/69SiexjfTY2xv-kvxNac9Q?view#What-are-tags) or [initial proposal](https://github.com/paritytech/substrate/issues/728).
### Proposal: tags for NFT items
Tags can be used to order transactions involving NFT items.
#### `Requires` tags
Each transaction requiring an item to be owned by specific account (e.g. *account-x*) should *require* a following tag:
```
[account-x][collection-id][item-id]
```
*Example* of such transaction would be an item transfer from Alice to Bob. Alice needs to own the item, before it can be transfered.
By reporting *requires* tags runtime informs the transaction pool that this particular transaction is future, and it is waiting for some other transaction that will provide required tag.
If all the prerequisites of the transactions are already satisfied (what is checked by runtime in the `validate_transaction` call), the *requires* tags shall be an empty array.
#### `Provides` tags
Every transaction that changes the ownership of the item to the specific account (e.g. *account-y*) should *provide* the tags in the same format:
```
[account-y][collection-id][item-id]
```
This information should be provided by runtime, in the [`TransactionValidity`](https://github.com/paritytech/polkadot-sdk/blob/d591b16f6b1dec88003323cdae0c3abe3b5c9cbe/substrate/primitives/runtime/src/transaction_validity.rs#L255-L284) provided by [`TaggedTransactionQueue` API](https://github.com/paritytech/polkadot-sdk/blob/c77095f51119d2eccdc54d2f3518bed0ffbd6d53/substrate/primitives/transaction-pool/src/runtime_api.rs#L25-L55).
This approach allows a transaction that delivers an item to the account to provide a tag, while transaction that sends out or otherwise interacts with the item can require the tag.
### Tag format
Tag format may require some extra work to accommodate broader NFT related use-cases (e.g. leases or approvals).
### Conclusion
Using this system, the transaction pool can execute transactions related to a specific `item-id` in the correct order.
This is an initial proposal that can be evaluated and extended further as needed.