So there is one big thing that is annoying about UTXOs. Namely, that in order to do anything you first need your very own UTXO. They're easy to get, and come in any size you want above 0... but you can't make them out of thin air if you don't already own one. Getting one involves you being friendly either with a staker who can create you one for free in the coinstake transaction, or having someone else pay the network fees and be willing to give you a few satoshi.
The way contracts figure out who sent the message (and authenticate it) is to check "ok, did this person spend a UTXO in this transaction" (even if they merely spent it and sent all the funds back to themselves). This sounds a bit wasteful, but the worse problem is that without a UTXO it's impossible to authenticate that you're sending a message to the contract. Even if someone else pays the fees and everything else for you, you still need a UTXO to really do anything with most contracts. This issue commonly comes up in other cases as well. Your wallet has multiple addresses and each address has it's own set of UTXOs. The blockchain is incapable of knowing that those addresses belong to the same wallet. So, what happens when you choose to send QRC20 tokens to some certain address, but then find out that address has no UTXOs. You will be incapable of spending the QRC20 tokens, since you have no way of proving to the contract that you are that certain address. The official workaround for this problem is to simply send that certain address any amount of coins (even 1 satoshi) so that it has a UTXO, and then you can withdraw your QRC20 tokens or whatever. Later, Qtum Core will (by default) make sure to use change addresses to ensure that address always has a UTXO.
This is wasteful of precious UTXO set space, but most of all it's incredibly annoying. Our Dapps have complained about it, their users, our users, myself. It's a problem... and it makes it harder to use a lot of different and otherwise awesome use cases unique to the UTXO model in Qtum.
My (definetely not 100% proven and thought out) proposal is to extend Bitcoin's fundamentals to support an otherwise boring edge case. In Bitcoin (and Qtum right now), in order to even prove a signature or anything like that on the blockchain, you must give a TXID and a Vout number, indicating which UTXO you will be spending, then you provide a signature that basically makes the UTXO's "vout script" evaluate to true. There's other cool stuff about this, but for the case we're interested in, it involves checking the signature of the public key in the UTXO for the hash of all inputs and outputs of the transaction. So, what if we gave another way of looking up that public key to check the signature of?
My proposal: Allow a TXID and Vout of 0 to be permissable and assumed to have 0 value, but otherwise to be infinitely spendable. To prevent duplicate transactions potentially being valid, all complete transactions must consist of at least one actual vin with a TXID that's not 0. It would probably be very ill-advised to use SIGHASH_ANYONECANPAY, as inputs created with this method could be used in any transaction without restriction (ie, duplicated). This gives no threat to the blockchain, but could be a huge security hole for users with no practical use. Thus, SIGHASH_ANYONECANPAY will most likely be prohibited when using this functionality. To be safest, it would probably be a requirement to only allow the SIGHASH_ALL (default) signature scheme. Otherwise, anyone with early knowledge of the transaction (such as nodes/stakers) could potentially rewrite the transaction to include another output that executes a contract and drains ERC20 balances or whatever.
No new opcodes need to be introduced and in theory this has no ill effect on Bitcoin or Qtum blockchains at this moment if allowed. Qtum would make use of this functionality though by extending the Account Abstraction Layer so that it can run these vin scripts that would otherwise be useless. It could check for pattern matching so that P2SH or PUBKEYHASH scripts could be identified and classified as an address, along with being run as a normal script to verify signatures of course. Thus, it would be possible to take an address never used on the blockchain, construct a vin that uses and verifies that address, but points to no UTXO. In theory this could be used for many purposes. You could use P2SH/Multisig addresses without UTXOs, send messages from contracts (pending attack vector verification), and even use it with Segwit addresses.
The pattern matching would probably be the most difficult part and might actually require an additional opcode for simplicity. The opcode could be something like OP_VOUTBEGINSHERE or whatever and actually do nothing other than be a marker for pattern matching.
A user wants to use a Dapp but has never used Qtum before. In order to begin using the Dapp, they must register an account on the blockchain. The Dapp maintainer has an off-chain registration portal to allow for someone to register on the Dapp for free. This works by the Dapp maintainer paying for the gas fees of on-chain registration.
This is possible today (though has not been used by anyone yet), but with a caveat. The new user must have a UTXO to prove their identity and complete the registration.. they don't actually need any money, but the only way to prove ownership of a certain address is by spending a UTXO. With this proposal, it'd be possible for the user to create a UTXO from nothing using only their public/private key.
The actual workflow is that the user would register off-chain or whatever to basically prove that they are worthy of the Dapp site paying for their gas fees (remember spam is still possible and must be handled somehow). The user would then provide their address to the Dapp site. The Dapp site would then send the user a partially completed transaction composing of the following:
- Input: Created user address utxo from txid 0. This is unsigned at this point. This the first input so that the user address will be the
msg.senderto contract code
- Input: Dapp UTXO that pays for keys; This is signed and marked SIGHASH_ALL
- Output: Dapp contract execution that does the registration process on-chain etc. The amount of gas given is chosen by the Dapp and is measured to be the correct amount.
- Output: Change address to send remaining funds back to the Dapp UTXO address
The user would receive this transaction and validate that it is as expected. They would check that the Dapp contract output only does registration. They would also ensure that no additional outputs are added to the transaction other than the change address UTXO (and they would check that to ensure there is not a hidden contract execution).
Once the user is satisfied and has determined the transaction is secure, the user will sign the first input and use the SIGHASH_ALL signature scheme to ensure nothing can be added or removed to the transaction. The user then broadcasts the transaction to the blockchain (or hands it to the Dapp site to broadcast if they aren't running a node).
Once the transaction is executed and confirmed, the address of the user will be registered with the Dapp on-chain, even though this address has never actually received any Qtum coins or had any other activity to "establish" the address.
Many identity based Dapps in the ecosystem right now struggle with this problem. Users might pay with Bitcoin or a credit card or some other off-chain method of payment for the Dapp to register them, but if the Dapp sends them Qtum (or ETH, whatever) to the address as a stipend for registering on-chain there is no method of actually enforcing that. In addition, the Dapp could get in serious legal trouble since exchanging fiat to cryptocurrency in most countries has a lot of legal regulation like money transmission licenses etc. With this method, gas and transaction fees can easily be paid by the Dapp in an enforced way. The user can't just run off with that stipend and choose to cash it out, or spend it on a different contract execution. Thus it is (btw, IANAL, don't take this as legal advice) probably safe legally to take fiat and use it to pay for the fees of a specific on-chain transaction.
Another simpler use case is for an ERC20 token provider to provide the gas fees for sending tokens to an address. If we're working in a world where people might not own Qtum, but do use the Dapps on the Qtum blockchain, then there needs to be systems for using Dapps without actually owning any Qtum to pay for your own transaction fees. This proposal is just the first step in making this a practical reality. There are various workarounds in Qtum and Ethereum to solve this problem, but they are clunky and definitely not ideal.