[Draft / POC] Silent Payments - #24897
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
Concept ACK |
b97fee2 to
340f67d
Compare
|
Need some way to avoid users trying to send a silent payment to a wallet that doesn't support it... am I missing something? |
|
@luke-jr Yes, it will need to be further discussed if this concept proves to be valid. In this PR, all descriptor wallets support silent transactions as the As only Taproot addresses can be used for silent payments and only descriptor wallets support Taproot, this may suffice, but it certainly needs further discussion. |
@luke-jr When the recipient publishes their silent payment address, it needs to be clear that it is not a regular taproot address. The address format should be distinct. The tweaked silent payment address that is generated by the sender and is ultimately committed on-chain should be indistinguishable from a regular taproot output.
@w0xlt Note that nothing about the silent payment scheme is exclusive to taproot, but regardless I do think it's good to limit the specifications to creating taproot outputs only as it encourages taproot use and means transactions without taproot outputs (albeit hopefully rare in the eventual future) don't need to be scanned. |
But I don't see that in this current spec/code? |
340f67d to
0fe8e02
Compare
|
🐙 This pull request conflicts with the target branch and needs rebase. |
There was a problem hiding this comment.
Don't forget to rebase. The bech32 hrp stuff moved to kernel/chainparams.{h,cpp}.
The silentpayment index has been removed from the codebase. … A new PR, with the index, will be added soon.
That's nice. It's more important to prove functionality, can improve performance later.
The rawtr() functionality has been merged, so the dependency can be removed from the PR description. Either this PR description or a BIP should remind the reader why rawtr() is necessary (you can't know the untweaked key) and safe (there's no way for the sender to unilaterally add a hidden script path?).
Enabling the ECDH module in libsecp256k1 might be a reason to put silent payments behind a configure flag initially. Then again, we also need it for BIP324 P2P encryption #23561 and I'm not seeing any discussion there about enabling the module either. That PR also introduces fuzz tests, so maybe it's worth combining efforts and getting those merged jointly.
Most of the commits here are reasonably short. It might be worth splitting f0f9817f44fb8dc43c1f8ca0a456fcd3780350af a bit further.
I would suggest moving PSBT and light client support to a followup PR. It's important to prove that it works, but that can be done by just keeping it rebased on this PR with the minimum functionality.
There was a problem hiding this comment.
3742cc75571a60bda52a41923c8244535af9ff23: maybe move that above UNKNOWN?
There was a problem hiding this comment.
9143c7e1f1710f123072cc272b66ab2cad0eb57a: this commit won't compile, probably needs something from a later commit
There was a problem hiding this comment.
The term "identity" is confusing here. It's also confusing that you get this error when you generate a new silent payment address, but not when you request an existing one (by reusing a label).
I guess what you're trying to say here is that an outside observer can tell that two silent payment addresses belong to the same person? Maybe just say that:
The silent payment addresses are unique for accounting purposes only. They can be linked to the same wallet. For privacy a new wallet is required.
That said, I think this feature is a footgun. Also because poor coin control will eventually link funds from all labels.
This would be nice though, maybe in a followup. I was trying to test it with I guess one thing you need for that is the ability to dump the watch key. You could add an argument Finally I noticed that calling |
Co-authored-by: Aurèle Oulès <aurele@oules.com>
Co-authored-by: josibake <josibake@protonmail.com>
|
I've rebased and created a slimmed-down version of this PR in #27827. Most notably, I took out labels and removed some of the RPC support, and made several updates as the silent payments spec has changed a bit since this PR was last updated. For anyone reviewing this PR, I'd appreciate your feedback on #27827. Big thanks to @w0xlt for moving this draft along as far as they did! My plan is to keep cherry-picking commits from this draft for follow-up PRs to add back in label support, RPC coverage, etc |
|
Closing this, in favour of #27827. |
This PR proposes an early version of Silent Payment (author:@RubenSomsen).
In this scheme, the recipient generates a public address, but the sender tweaks the address and the recipient detects the payment by verifying all transactions on the blockchain. An example use case would be private donations.
The purpose of this PR is not a final version, but to start the discussion and get benchmarks based on a real implementation.
This version is built on top of #994 (bitcoin-core/secp256k1) for x-only ECDH support and #23480 (bitcoin/bitcoin) for
rawtr(). Each new silent transaction detected is stored in wallet as arawtr()descriptor.In this implementation, the sender can tweak the recipient address by passing the
silent_paymentoption to send RPC. The transaction output will be different from the address entered.For example
./src/bitcoin-cli -regtest -named send outputs="[{\"bcrt1pwlh5xuyrpgfunwyww8cfu78yfs2yqyevl7yturavahh5kgxwdd2q5hzgfu\": 1.1}]" fee_rate=1 options="{ \"silent_payment\": true}".will generate
voutwith completely unrelated outputs:Any wallet, as long as it has access to private keys, can send silent payments. Thus, this excludes watch-only wallets or wallets with external signers .
But the recipient's wallet needs a new flag called
SILENT_PAYMENT. This flag allows an additional scan that verifies that the wallet keys match the silent payment scheme. When it detects a silent payment that belongs to the wallet, it is stored in arawtr()descriptor../src/bitcoin-cli -regtest -named createwallet wallet_name="recipient" silent_payment=trueTherefore, scanning each address for each transaction is potentially prohibitive overhead, so the node can be initialized with
keypool=1or a descriptor with range [0,1] can be imported into a blank wallet. Until there is more benchmark data, it is the safest option. The proposal recommends one static address.I've been running some silent payments on signet using wallets with default keypool and default range, I haven't noticed any relevant performance drops on the signet node.
Apparently this implementation is working as expected but I can't guarantee that the scheme is implemented correctly or safely, so I'm opening this PR for reviews, modifications and improvements.
There is a new functional test (
test/functional/wallet_silentpayment.py) that can help to better understand the implementation.