Tiers of token wallets
CashTokens on BCH is a unique facility that satisfies two value propositions at once:
- Traditional “tokens” where fungible or non-fungible tokens represent items of value, and are transferred and traded on a public blockchain to take advantage of its permissionless security properties.
- Computation “tokens” where information is passed among both onchain contracts and off-chain entities for more complex operations.
Generally when developers talk “CashTokens wallet” they refer to 1), which is better understood, and we’ll describe its requirements briefly. To unleash the full power of CashTokens on BCH though, we will need to address 2) in detail as well.
Traditional token-handling wallets shall be expected to have the following features:
- Easy identification of Category IDs
- Access to history and transaction details(for full featured wallets) or balance (for minimalists)
- Detailed description of NFT characteristics (mutable, mintable…)
- Ability to handle BCH in parallel
- Noncustodial backup, through seed words or otherwise
- Sending tokens to requests, such as a version of BIP21
It can also optionally have the following features that can immediately yield a large improvement to quality of life:
- Minting, if a standard is agreed upon
- Identification of tokens, perhaps through Metadata Protocol
- Sending BCH in a single output along with tokens
- Sending tokens to Payment Protocols (such as a version of BIP70 or json-payment-protocol).
Other advanced features available to BCH such as fusion, shuffle, coin-management are desirable, but may not be immediately needed for “ready to go” functionality.
Note that even in a setup where these advanced features are available for native BCH, they may not be available to fungible tokens due to liquidity, demand or general maintenance hurdles, even if the implementation is theoretically straightforward.
Information-carrying tokens and smart contracts
The primary advantage of CashTokens over other UTXO token protocols lies in its ability to interact as information-carrier within an expressive BCH context. Without at least one competent wallet to take advantage of that this functionality can be stunted for a very long time. Facilitating it requires, as prerequisite, that the wallet be able to:
- Contexts : Display different contexts in interface, depending on the contract being handled. More on this below.
- External Interactions :Ability to interactively exchange information with external, non-node entities. An external example here is MetaMask, which is able to interact with web pages; an existing BCH example is Cashfusion, which interacts with the Cashfusion server. Early wallets may want to weigh their scope on whether to include ability to interact with servers in general.
- Script-spending : Given a template and sufficient supporting information, spend a UTXO in a custom way, perhaps with interaction steps to fetch additional information.
- UTXO Discoverability : Given a template and private seed or backup, query servers using custom filter criteria and fetch spendable UTXOs, along with possible additional information required to spend them. This is important in the UTXO context, as there is no singular, per user abstracted account where everything goes to and from. For some contracts discoverability from seed may be impractical, in which case suitably secure wallet backups need to be specified.
- Interaction history backup : Conventional wallets generally converge onto backing up by BIP39 seeds, from which an entire P2PKH history can be retrieved directly from the blockchain. Interactive script wallets have no such luxury - just as in the case of UTXOs, the wallets must either backup its history directly, or have templates where custom discovery-from-seed methods are specified.
- Template verification and use : Custom interactions can be tremendously insecure, a problem which MetaMask worked around by prompting trust on individual website certificates. We can do better - a templating system independent from the Web such as Bitauth can facilitate a permissionless, trust-once-per-usecase system that is much more secure.
These capabilities shall form a generalized baseline upon which countless customizations are possible via templates, and the ability of CashTokens to transfer information will lie at the heart of many of these contracts. We’ll explore CashTokens primitives in custom contracts in another article.
Conventional wallets typically has one context, or at most two if we separate BCH and token spending, as seen in Electron-Cash-SLP. It is, however, impossible for one interface to account for all possible script usecases, many of whom will require customized input and output elements. It is therefore important for wallets to accommodate possible different interfaces, perhaps via tabbing, specified in each template’s context.
At the most basic, a “universal” interface is conceivable where templates specify all needed script input fields in their raw requirements such as num/binary-strings/public key…, and the wallet simply serializes the inputs to be used as-is in Script. This can, however, be very user unfriendly, especially for elements that gather from an external source, such as an oracle, instead of from the user. On the other hand, it would be unwise to allow arbitrary interaction and code-running with a remote server, as any vulnerabilities introduced by one template is no longer contained within its context.
On EVM wallets like MetaMask, contexts are usually granted by permitting access to web domains. The EVM/MetaMask model, however, suffers from high trust on domain name owners, as well as opaque and possibly unbounded permissions given to websites that can be changed in arbitrary ways. We assert that a trust-once-per-usecase “template” model, similar to how users traditionally trust downloaded software, is more appropriate for our purposes.
A good balance can be struck for a template-based wallet, if it adheres to the following rules:
- A template must not run arbitrary remote code. The only data that can be fetched from a remote server are direct inputs to Bitcoin Cash script, or (mutable) parts of Bitcoin Cash script itself. Any non-Script code must be local, and requires an explicit template update to change.
- Template contexts must be isolated. Templates shall not automatically pass information among themselves upon execution, without explicit user permission. They shall each have their isolated seed derivation path, backup file, interface instructions, etc. The wallet shall enforce this at low level design; failure to do so will result in contagion risk from a malicious template that the user inadvertently imported. While this contagion risk may be acceptable in a casual or small-community context, it is not scalable to wider, less sophisticated pools of users and developers.
- No persistent permissions for mutable interactions. Certain interactions, such as fetching a piece of Bitcoin Cash Script from external sources, are “mutable”: they do not simply fill inputs on already trusted Script, but may generate additional contexts that are not explicitly trusted yet. Each of these interactions must be explicitly granted permission each time. Developers who wish to streamline