Preserve security while simultaneously obscuring transaction values.
One of the most powerful new features being explored in Elements is Confidential Transactions. This keeps the amounts transferred visible only to participants in the transaction (and those they designate), while still guaranteeing that no more coins can be spent than are available in a cryptographic way.
This goes a step beyond the usual privacy offered by Bitcoin’s blockchain, which relies purely on pseudonymous (but public!) identities. This matters, because insufficient financial privacy can have serious security and privacy implications for both commercial and personal transactions. Without adequate protection, thieves and scammers can focus their efforts on known high-value targets, competitors can learn business details, and negotiating positions can be undermined.
The payment flow when using the Confidential Transactions Element is nearly identical to Bitcoin Core on the surface:
The key difference from Bitcoin is the addition of cryptographic privacy. These transactions differ in that the the amounts transferred are kept visible only to participants in the transaction (and those they designate).
createrawtransaction API in Elements works similar to Bitcoin’s raw
transactions with the following differences:
- The intent to create a confidential output is indicated by using a confidential address for the destination.
createrawtransactionRPC has the additional key
nValueper input which must be set to the value of the input. The value can be determined for example with the
- After calling
createrawtransactionthe user must call
blindrawtransactionon the transaction if a confidential input or output address is involved.
- If at least one of the inputs is confidential, at least one of the outputs must be confidential. Note that it is perfectly fine to create a 0-valued confidential output if otherwise there would be no confidential output.
- If all inputs are unconfidential, the number of confidential outputs must be
>= 2. Again, it’s fine to create a 0-valued confidential output.
The following example spends a confidential and an unconfidential output and
creates a confidential and unconfidential output. Due to the size of the
transaction it is not displayed here but saved in the variable
The implementation of Confidential Transactions as it appears in Elements has some important limitations to be aware of.
For example, the implementation only hides a certain number of the digits of the amount of each transaction output, dependent on the range proof’s “blinding coverage” at a desired precision level. Subsequently, there is a ‘minimum confidential amount’ that around 0.0001 BTC, and a ‘maximum confidential amount’ that is 232 times the minimum amount.
Digits smaller than the minimum will be revealed to observers; for example, if the minimum is 0.0001 BTC, a transaction output of 123.456789 BTC will look like “?.????89 BTC”. The tiny amount of information about the value leaked in this way is unlikely to be important, but be aware that this could allow observers to ‘follow’ coins by linking subsequent transactions with identical amounts. All values can be rounded to the minimum to avoid revealing information in this way if preferred.
A transaction output larger than the maximum will reveal the order of magnitude of the amount to observers, and will reveal additional digits at the bottom of the amount.
For example, if the maximum is 500k BTC, then all outputs under that amount will look the same, but an output between 500k and 5M BTC will be visible as such to observers (but not the exact amount within that range), and will also reveal one additional digit of the low end of the amount. Revealing the range in this way could be a very significant privacy leak; splitting such extremely large transactions to keep them under the maximum confidential amount is strongly recommended.