<p>Great question!</p>
<p>For each anonymous visitor who clicked [Donate]:</p>
<ul>
<li>generate a new, high-entropy URL that is public to access but impossible to guess (additionally, it can expire after some time)</li>
<li>derive a new Bitcoin address based on xpub and the counter; this address is dedicated to this specific donation attempt</li>
</ul>
<p>Even if anonymous visitor abandons the process without paying, her unique address is <strong>never reused</strong>. It is &quot;wasted&quot; in terms of the address space gap.</p>
<p>Other anonymous visitors <strong>will not</strong> be able to discover any past or future addresses because they can't guess the URL-s.</p>
<p>The only drawback is theoretical risk of pointless vandalism: one can click [Donate] in a loop, increasing the number of unused addresses in your wallet. This isn't really a big issue because most wallets can be configured to arbitrary gap. I also never heard of such vandalism attempts happening in practice.</p>
<p>Now, the most <strong>pragmatic</strong> way to go aobut it is use existing open source, self-hosted donations processors like:</p>
<ul>
<li><a href="https://cypherpunkpay.org/" rel="nofollow noreferrer">https://cypherpunkpay.org/</a> - the easiest to install and maintain with explicit focus on privacy (disclosure: I am the author)</li>
<li><a href="https://btcpayserver.org/" rel="nofollow noreferrer">https://btcpayserver.org/</a> - the legendary, most comprehensive and most established one</li>
</ul>

CC BY-SA 4.0
2021-06-27T17:13:19.313Z
Yeah, this is similar as my attempt with IP addresses - when someone wants to donate (clicks), generate a new address in case it is a new IP, and deliver same as before address if the IP has been seen before (and address not used). This does have the same problem with the funds recovery due to the gap. It is true that many wallets do have configurable gaps, but not all of them. And even without vandalism it will happen that the common gap of 20 will be reached. I guess that BTCPayServer and CPP do solve the gap for you here, right?
Wapac
CC BY-SA 4.0
2021-06-27T20:13:21.993Z
1) I wouldn't say it's similar, the IP based approach is incorrect. On one hand thousands of users can easily share the same public IP address in some circumstances. At the same time, a single user can have different IP address every couple seconds (just Ctrl+Shift+L in Tor Browser or reset VPN). 2) No, neither BTCPay nor CypherpunkPay "solve" the gap problem. The problem is inherent to never-reusing any address once shown and cannot be "solved" otherwise than on the donation recipient wallet side. The software can **guide the recipient** about minimum necessary gap though!
CypherpunkDev
CC BY-SA 4.0
2021-06-29T09:12:48.160Z
I do agree a user can obtain multiple IP addresses and many users can share one IP address. But it does not seem too relevant to the prevention of the attack I described. Point was to prevent attacker to reveal significant part of the donations of other people. Unless the attacker can possess (and repossess) many IP addresses that are used by people who actually donate, there is no problem. So the best the attacker could hope is to gain information about donations from Tor users. Of course if there is no solution then this is pointless and we can just assign new address each time.
Wapac
CC BY-SA 4.0
2021-06-25T08:38:14.183Z
2021-06-25T08:43:57.263Z
2021-06-25T08:43:57.263Z
CypherpunkDev
<p>Imagine a web page that wants to accept Bitcoin donations. A naive approach is to provide a single address on the page and that's it. The problem here is that the address is known to everyone and if the money ever moves, the address is being reused for new donations after the first spend.</p>
<p>OK, so how can we do better? We can have xpub and generate a new address every time ... every time what? The first basic strategy would be to generate a new address as soon as someone sends a donation to the previously generated one. The problem here is that an active monitoring of the web page by a robot simply reveals all the addresses again.</p>
<p>Can we do better? We can, for example, generate a new address per IP address. Doing this, the robot would always see one address that is dedicated to its IP address and unless someone from the robot's network under the same IP address donated, the robot could not reveal anything useful. The problem here is that if we assume not very high conversion rate, we generate a lot of addresses and most of them never receive any donation. This causes a problem with seed recovery, where there usually is a gap limit defined for the maximum number of empty addresses that are scanned before the scan is terminated. I assume this is quite wallet specific rule, but I assume in general, the problem exists here (does it really?).</p>
<p>So how can we do better? Say we want to use a cold storage using a 24 word seed + passphrase and we are happy to run Bitcoin Core together with the web page. How can we solve donation in a way that is manageable, can be recovered from seed, and at the same time optimizes for privacy? Does a solution already exists somewhere (for example BTCPayServer)? If so, how does it work and what are the privacy properties of such a solution?</p>

CC BY-SA 4.0
2021-06-26T12:10:40.167Z
Why are you against reuse?
MCCCS
CC BY-SA 4.0
2021-06-27T17:07:50.150Z
Reusing is primarily known to be bad for privacy. For example, let's say you don't want everyone to know how much you received from the donations in total. If you reuse just one address, everyone will know. The primary concern in this question is to keep such information from an attacker who actively monitors your donation page.
Wapac
<privacy><xpub><donation>
How to accept donation correctly?
Wapac
# How to accept donation correctly?

(Asked by: username_0 on 2021-06-12)

Imagine a web page that wants to accept Bitcoin donations. A naive approach is to provide a single address on the page and that's it. The problem here is that the address is known to everyone and if the money ever moves, the address is being reused for new donations after the first spend.

OK, so how can we do better? We can have xpub and generate a new address every time ... every time what? The first basic strategy would be to generate a new address as soon as someone sends a donation to the previously generated one. The problem here is that an active monitoring of the web page by a robot simply reveals all the addresses again.

Can we do better? We can, for example, generate a new address per IP address. Doing this, the robot would always see one address that is dedicated to its IP address and unless someone from the robot's network under the same IP address donated, the robot could not reveal anything useful. The problem here is that if we assume not very high conversion rate, we generate a lot of addresses and most of them never receive any donation. This causes a problem with seed recovery, where there usually is a gap limit defined for the maximum number of empty addresses that are scanned before the scan is terminated. I assume this is quite wallet specific rule, but I assume in general, the problem exists here (does it really?).

So how can we do better? Say we want to use a cold storage using a 24 word seed + passphrase and we are happy to run Bitcoin Core together with the web page. How can we solve donation in a way that is manageable, can be recovered from seed, and at the same time optimizes for privacy? Does a solution already exists somewhere (for example BTCPayServer)? If so, how does it work and what are the privacy properties of such a solution?

**Tags:** privacy, xpub, donation

> **Comments:**
> **username_1**: Why are you against reuse?  
> **username_0**: Reusing is primarily known to be bad for privacy. For example, let's say you don't want everyone to know how much you received from the donations in total. If you reuse just one address, everyone will know. The primary concern in this question is to keep such information from an attacker who actively monitors your donation page.  

---

## 1 answers

### Answer by username_2 on 2021-06-25. Score: 2

Great question!

For each anonymous visitor who clicked [Donate]:

* generate a new, high-entropy URL that is public to access but impossible to guess (additionally, it can expire after some time)
* derive a new Bitcoin address based on xpub and the counter; this address is dedicated to this specific donation attempt

Even if anonymous visitor abandons the process without paying, her unique address is **never reused**. It is "wasted" in terms of the address space gap.

Other anonymous visitors **will not** be able to discover any past or future addresses because they can't guess the URL-s.

The only drawback is theoretical risk of pointless vandalism: one can click [Donate] in a loop, increasing the number of unused addresses in your wallet. This isn't really a big issue because most wallets can be configured to arbitrary gap. I also never heard of such vandalism attempts happening in practice.

Now, the most **pragmatic** way to go aobut it is use existing open source, self-hosted donations processors like:

* <https://cypherpunkpay.org/> - the easiest to install and maintain with explicit focus on privacy (disclosure: I am the author)
* <https://btcpayserver.org/> - the legendary, most comprehensive and most established one

> **Comments:**
> **username_0**: Yeah, this is similar as my attempt with IP addresses - when someone wants to donate (clicks), generate a new address in case it is a new IP, and deliver same as before address if the IP has been seen before (and address not used). This does have the same problem with the funds recovery due to the gap. It is true that many wallets do have configurable gaps, but not all of them. And even without vandalism it will happen that the common gap of 20 will be reached. I guess that BTCPayServer and CPP do solve the gap for you here, right?  
> **username_2**: 1) I wouldn't say it's similar, the IP based approach is incorrect. On one hand thousands of users can easily share the same public IP address in some circumstances. At the same time, a single user can have different IP address every couple seconds (just Ctrl+Shift+L in Tor Browser or reset VPN). 2) No, neither BTCPay nor CypherpunkPay "solve" the gap problem. The problem is inherent to never-reusing any address once shown and cannot be "solved" otherwise than on the donation recipient wallet side. The software can **guide the recipient** about minimum necessary gap though!  
> **username_0**: I do agree a user can obtain multiple IP addresses and many users can share one IP address. But it does not seem too relevant to the prevention of the attack I described. Point was to prevent attacker to reveal significant part of the donations of other people. Unless the attacker can possess (and repossess) many IP addresses that are used by people who actually donate, there is no problem. So the best the attacker could hope is to gain information about donations from Tor users. Of course if there is no solution then this is pointless and we can just assign new address each time.  

---

