Simple Fabriik Protocol for Tokens is, as the name indicates, a simple protocol that we have developed to add tokens capability to Money Button. The protocol goals are:
- To be integrated easily into wallets
- To be flexible
We don’t claim this protocol to be the best and the one that everybody should use, but a protocol that can be particularly good for business use cases.
|Authoriser||A service provider that runs the API endpoints needed by the protocol, being the one that can impose rules and restrictions to transactions|
|Issuer||The address that was used to create the first minting transaction|
|Owner||The address that holds UTXOs with a particular amount of tokens|
An asset is created by writing a first transaction in the blockchain that specifies the name and initial supply of tokens. In order to make a transfer, a transaction should use that UTXO and write new UTXOs in which an owner and and amount of tokens will be written. The protocol builds then a transactions tree that starts with the first (minting) transaction, that is completely and easily auditable. The UTXO is locked using bitcoin script to the owner and the authoriser’s addresses.
The protocol specifies that each asset will have assigned a paymail. This ensures a unique and user friendly name for each asset, and allows for any wallet to know which server it needs to query to get information about the asset and to perform the protocol oprations (request authorisation, see below).
firstname.lastname@example.org. A wallet will query moneybutton.com for the asset “abcde” and will get the asset’s name (Company Stocks Inc.), total initial supply of tokens, website and any other information related to the asset.
Transactions need to be approved by the authoriser, which will provide API endpoints added as paymail extensions. A wallet that receives a token transfer transaction, in addition to query the asset information will use those other API’s to build and authorise the next transfer transaction. Since every transaction needs to be authorised (UTXOs are locked with an address that the authoriser has), the service provider can enforce all kind of rules (see more on Custom Rules).
At the same time, we avoid any restriction regarding how many token UTXOs can be used as inputs, or how many outputs can be created, since the authoriser will validate that off-chain. This is an important difference with other protocols, where merging and splitting is limited.
Follows the Simplified Payment Protocol principles
The fact that the authoriser needs to approve every transaction before it can be sent, allows it to keep the transaction history without needing to listen to all transactions in the blockchain. This way it works with the same principle as the Simplified Payment Protocol, where a transaction is sent peer-to-peer avoiding the receiver to have to listen to all blockchain transactions, making it very scalable.
This has a significant implication when compared to other protocols, where a wallet needs to verify that a transaction that it receives is valid either by a) querying a service that will keep all the token's transactions, or b) traversing the transaction history to validate that it reaches the right minting transactions. Both options require someone to listen to all the transactions in the blockchain (either this 3rd party provider or the wallet itself). With SFP, a wallet only needs to query the asset information. If the inputs are signed by the authoriser, the wallet can be sure that the transaction is valid. And that signature can be verified by getting the public key while querying for the asset information using the asset’s paymail. No need for ‘Back to Genesis tx’ verification.
Uses OP_RETURN data
Each UTXO includes the amount of tokens and some text notes as data using OP_RETURN code. Since this allows to separate the tokens amount from the satoshis included in the UTXO, it allows for maximum flexibility to mint/burn tokens, and it also means that you don’t need to have the same amount in satoshis in order to create tokens. The notes allow to register any information regarding a particular UTXO, like invoice data or fees descriptions.
This protocol doesn’t set particular rules, but its architecture is prepared to include any type of rules as part of the authorisation operation, like calculating and including fees in a transaction, the option to mint or burn tokens, as well as freezing tokens or denying transfers to blacklisted addresses. This allows for different authorisers to implement different rules, and also to implement different rules in different assets, while keeping the same general protocol.
An output script is then quite small and has three parts: configuration, locking code and data.
|Configuration||Protocol version, Asset paymail, Owner address, Authoriser address||First part of the script, the configuration of the output. Which asset is it, who’s the owner and who’s the authoriser|
|Locking code||Script code that locks the output to the owner and authoriser signatures||Second part includes the actual locking script|
|Data||Tokens amount, Notes||Third part includes how many tokens this output has and any other text information related|
When a wallet receives a tokens transaction, it will need to verify that the transaction is valid. This is the same for all token protocols since no protocol is enforced by the blockchain, even if the locking script is. In our protocol we include the signed normalized tx ID in each new UTXO that is created, giving the receiving wallet the ability to check that the transaction is valid withough needing to have the previous UTXOs that are being spent.
A wallet will need to:
- Extract the asset paymail from the UTXOs data to get the operator’s API domain
- Query the operator’s API to get information about the asset, including its public key
- Calculate the normalized transaction ID for the transaction
- Verify that the signature included in the UTXOs is valid for the calculated normalized tx id using the public key
The second step can be avoided by caching the asset information, so future transactions can be verified without needing to query the operator’s API again
Here is an importante difference with other protocols. Since we know that this verification process will need to happen, meaning that wallets will need to do some operation to verify received tokens, we moved this need for a request to the wallet creating the transaction instead of the wallet receiving it. This gives us all the advantages mentioned before (imposing custom rules, work in a P2P model, and so on). The wallet receiving a tx will need to query the information for the asset anyway, and with our protocol it can also verify it. So there’s really no much overhead over other protocols, but a lot of flexibility is gained.
This verification prevents from anyone creating a transaction using the same locking script for the UTXO, since the UTXO itself includes a signature that cannot be created without the asset’s private key, and cannot be copied from other valid transaction since it’s signing the normalized tx id, which is created using the transaction’s inputs.
A transfer flow
To illustrate how the protocol works, let’s take a look into a transfer transaction. This steps description asumes that Wallet-1 already holds UTXOs for an asset using this protocol, which is identified by its paymail, which domain indicates the authoriser to query.
- Propose tx: Wallet-1 collects tokens UTXOs, builds a tx, and sends it to the authoriser together with the outputs description (to whom and how many tokens wants to send)
- Validate, modify tx: the authoriser can then validate those inputs, check that the sum of inputs equals the outputs, and can even add more outputs (for example for paying fees, this would be specific to each authoriser business model and requirements)
- Unsigned tx: Wallet-1 receives the transaction now with the outputs’s scripts and the signing instructions, without the authoriser’s signature
- Sign: the user signs first the transaction. This step would allow a wallet to also show the user the final transaction (in case of fees being added or any other modification was introduced)
- Request authorisation: the signed by the owner transaction is sent to the authoriser
- Validate inputs/outputs: the authoriser can then check everything again, sign the tx, and record its hash (ID) as valid for validating future transactions
- Signed tx: the complete tx, signed by both the owner and the authoriser is now returned to Wallet-1
- Send P2P tx: Wallet-1 can now send to Wallet-2 the transaction
- Get asset information: Wallet-2 would then need to extract the token’s paymail and use it to query the authoriser to get the asset information, which includes the authoriser’s public key. This step could be cached and only needed if the wallet is missing the information for the asset.
- Verify signatures: Wallet-2 can now verify the UTXO's signature with the authoriser’s public key to be sure that the transaction is valid for that asset.