With this QIP, it would be possible for a user to sign and prove their identity to a contract without owning any UTXOs/coins owned. This would primarily be useful only to contracts so that msg.sender can be set to an address that owns no coins or UTXOs. This would not allow free transactions, someone else must still pay for the transaction to be placed into the blockchain
Motivation
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 for user experience of both Dapps and Qtum users.
Specification
A new opcode named OP_SENDER will be added. This opcode is only valid when used within vouts that contain either an OP_CALL or OP_CREATE opcode. OP_SENDER takes three arguments:
UniversalAddress type -- the type of sender
UniversalAddress data -- the address data for the sender (to account for this later being dynamic length)
scriptSig -- the serialized scriptSig necessary to complete the signature of the address
Example vout
1 // pubkeyhash address type
address // pubkeyhash address
{signature, pubkey} //serialized scriptSig pushed
OP_SENDER
1 //EVM version
10 //gas price
100000 //gas limit
1234 //contract data to send
OP_CALL
OP_SENDER will cause an internal script execution. It will fail if the end result is not 1. For this example, it would look like so:
The serialized scriptSig would be treated the same as if it were a normal scriptSig for validation purposes. If the end result evaluates to 0, the transaction is invalid and can not be included in a block. For pay-to-scripthash senders, the scriptSig would be treated the same as normally, with the script being executed twice. First, to check the hash is the same as the scripthash, and then again to execute the redeemScript for spending P2SH outputs.
Signatures
The actual data to be signed will be a special case. Normally in Bitcoin and Qtum, only scriptSig scripts within the vin contains signatures, thus it is easy to come up with a signing scheme to avoid the "signing signed data" problem. However, this scheme breaks that assumption by having signatures inside of vout scripts. In order to avoid breaking existing Bitcoin based paradigms, signing will thus be split into two separate steps:
Sign vouts containing OP_SENDER
Sign vins
The vin signing process will be untouched, and thus signatures within the vouts will be signed by vin signatures. This is suboptimal, but is much safer and less complex.
The vouts will be signed as normally done for vins, but with the OP_SPENDER scriptSig changed to a zero size value. See https://en.bitcoin.it/wiki/OP_CHECKSIG for the signature signing schemes. The following modifications must be made however:
ANYONECANPAY -- Only the first vin will be signed
ALL/NONE/SINGLE -- All vins will be signed
NONE -- invalid and/or non-standard. There is no practical use for this, as even the current output would not be signed. Any data could be sent as the specified sender by modifying the vout data after
SINGLE -- only the current vout will be signed
ALL -- all vouts will be signed
Rationale
This method supports all of the features of the previous iteration of this proposal while including the following improvements:
Significantly less likely to affect consensus. No modifying code that has never been touched, constrained functionality to only contract containing transactions
Same transaction format and functionality with no specialized meanings
No risk of a bug potentially allowing a UTXO set spam attack
Allows for multiple contract executions to happen in a single transaction with different senders for each one
Allows for less back and forth for proposed fee-provider and dapp-fee-paid services
Should be significantly easier to implement
Extensible to support any UniversalAddress type in the future
However, it does carry the following downsides:
Special signature attaching tools and RPC calls must be supplied to make use of this functionality
Vout scripts must be checked for OP_SENDER and parsed to remove the scriptSig field when checking signatures. Normally vout scripts can be left alone when doing signature checking
Strategy
This would require a hardfork and could potentially be bundled into the x86 hardfork in 2019.
This is written as a counter proposal to QIP-2.
Abstract
With this QIP, it would be possible for a user to sign and prove their identity to a contract without owning any UTXOs/coins owned. This would primarily be useful only to contracts so that msg.sender can be set to an address that owns no coins or UTXOs. This would not allow free transactions, someone else must still pay for the transaction to be placed into the blockchain
Motivation
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 for user experience of both Dapps and Qtum users.
Specification
A new opcode named
OP_SENDER
will be added. This opcode is only valid when used within vouts that contain either an OP_CALL or OP_CREATE opcode. OP_SENDER takes three arguments:Example vout
OP_SENDER will cause an internal script execution. It will fail if the end result is not 1. For this example, it would look like so:
The serialized scriptSig would be treated the same as if it were a normal scriptSig for validation purposes. If the end result evaluates to 0, the transaction is invalid and can not be included in a block. For pay-to-scripthash senders, the scriptSig would be treated the same as normally, with the script being executed twice. First, to check the hash is the same as the scripthash, and then again to execute the redeemScript for spending P2SH outputs.
Signatures
The actual data to be signed will be a special case. Normally in Bitcoin and Qtum, only scriptSig scripts within the vin contains signatures, thus it is easy to come up with a signing scheme to avoid the "signing signed data" problem. However, this scheme breaks that assumption by having signatures inside of vout scripts. In order to avoid breaking existing Bitcoin based paradigms, signing will thus be split into two separate steps:
The vin signing process will be untouched, and thus signatures within the vouts will be signed by vin signatures. This is suboptimal, but is much safer and less complex.
The vouts will be signed as normally done for vins, but with the OP_SPENDER scriptSig changed to a zero size value. See https://en.bitcoin.it/wiki/OP_CHECKSIG for the signature signing schemes. The following modifications must be made however:
Rationale
This method supports all of the features of the previous iteration of this proposal while including the following improvements:
However, it does carry the following downsides:
Strategy
This would require a hardfork and could potentially be bundled into the x86 hardfork in 2019.