If you're going to run a payment system this way, by generating addresses and then checking if they've confirmed, the better way to do it (rather than pre-generating a batch), is to use hierarchical deterministic (HD) wallets. This way, instead of having to re-generate a batch of one-time receiving addresses to use on a regular basis, you generate a master key and then use the algorithm to generate addresses without having to use a full Bitcoin node (there are libraries in Python, JS, and all the common languages, look for "BIP 32" or "HD Wallet"). All you need to generate the deterministic addresses on your server is the master public key, thus there's less security risk (if the master public key is disclosed, it threatens the privacy of your users, but not the integrity of your funds).
If you don't want to bother generating the deterministic keys online, you could pre-generate thousands, even millions of them if you want. And keep both the private and public master keys offline. It also is a safer approach since you can securely store the master private key in a offline hardware wallet and not have to worry about keeping track of hundreds of private keys.
Long time since I've been active in Bitcoin, but this is the way I would have run a payment service without using a full node.
Author here, surprised to see this on HN! I considered submitting it myself but didn't think this crowd was that into Bitcoin. Nice to be proven wrong :)
A couple of people mentioned HD wallets:
I initially tried using an HD wallet, but the mechanism for interacting with it was more inconvenient than generating keys manually - especially considering that you might have to generate hundreds of addresses in a row that never receive a payment.
> I initially tried using an HD wallet, but the mechanism for interacting with it was more inconvenient than generating keys manually - especially considering that you might have to generate hundreds of addresses in a row that never receive a payment.
Not sure I follow. The only difference between generating a HD-derived address and a traditional address should be that the former can be re-generated based on the master key alone. Not sure what difference not receiving payment at hundreds of addresses would make between the two.
21 Inc. (where I work) has a very easy to use python library [1] allowing you to accept bitcoin payments via HTTP 402. But you can also just use the library to serve up a fresh payout address in plaintext on a website.
If you like the CLI, it has that too; it's a fully-compliant HD wallet. Getting set up is as simple as it can be
$ curl https://21.co > setup.sh
$ sh setup.sh
$ wallet create
[write down mnemonic]
$ wallet payoutaddress
[printed payout address]
Then you can use `wallet history` or `wallet balance` to see incoming payments, and `wallet send` to send money to a recipient.
If you like the advanced stuff, it has support for micropayment channels, too.
+1. That ~1% fee is for merchants who want to accept btc but don't want to deal with the ecosystem. They just provide their bank info to the processor and get fiat deposited there.
This is reckless. If your hardware corrupts data too often to sync a full node, the solution is not to hack together a homemade payment processing system with only SPV-level security that will run on your faulty hardware. This approach and the attitude behind it will lead to losing money and losing track of customer payments, probably sooner rather than later. Rolling your own payment processor is a great way to learn more about bitcoin, but use testnet coins. If receiving real money is what you want, use a tested library written by someone who put in the time and experience to do it the right way, or use a 3rd party payment processor. Don't learn with real money; that's learning the hard way.
The author mentions being plagued by crashes/corruption, but I've never experienced this and I've been running a full node for a few years. Other than the large (well, not _that_ large) storage requirements (.bitcoin is currently 101G) I've not got any complaints...
Unless there's a bug in a recent version of bitcoind which causes it to crap out when initially catching up with the network?
I've been informed that crashes+corruption indicate either lack of memory or hardware faults. Bitcoin needs to do an awful lot of cryptography, and it all needs to come out perfectly for it to work, so it tends to be sensitive to hardware faults.
> Other than the large (well, not _that_ large) storage requirements (.bitcoin is currently 101G)
This has always been my complaint with bitcoin. Will the block chain download just keep getting larger and larger? Setting up a full node takes forever because of that. Is there any possible way to improve this?
> I use the keyconv program from vanitygen as a convenient way to do this. Simply running "keyconv -G" generates an address and private key and outputs them.
You have to really trust that vanitygen tool. If there's some bug where there's not enough entropy in the private key generation, ALL your temporary wallets become vulnerable (e.g. someone can generate your private keys).
I'm the original author of "Straight", a stand-alone opensource Bitcoin payment gateway - a software that allows you to accept Bitcoin payments: https://github.com/MyceliumGear/straight-server
It is now part of the Mycelium Gear project, which is a hosted commercial version of it, and I don't work for the company anymore, but the team behind it that I hired and worked with is really great and they keep working on the product.
A problem I'm currently addressing that maybe someone can help with:
I'm using a BIP32 HD wallet master pubkey to generate addresses on the payment front-end. Now, the ideal payment-watching solution would be the following; it maintains a set of "active" addresses, which I can add to whenever, and notifies me whenever one receives a confirmed payment. However, I'm not sure if this exists. I would also settle for me being able to query arbitrary address balances quickly.
Bitcoin-core doesn't work because adding an address causes a rescan of the entire blockchain (as it doesn't maintain an address-indexed UTXO dictionary for all addresses), which is too slow. I think electrum-server might work. Even though I'm following the same derivation path as electrum-client, I don't think I can use electrum-client for this (because I could conceivably be attacked with hundreds of thousands of address generation requests, which I doubt electrum-client will like). I also want to ignore adderesses more than, say, a week old, which I don't think electrum-client supports.
Article recommends creating private/public pair via vanitiygen but imo that's not the best way to do it.
Alternative:
Create HD wallet (via electrum e.g.), get "public master key" and use it everywhere. You can generate consequent public addresses using that key but you can't generate private keys (i.e. spend anything).
Now your server is protected from stealing any money and don't require any special backups for these new keys.
Hi jstanley great article I'm running similar system at https://inthebitcoin.com for few months and it works great for me. No need for any third-party payment system. Space (101GB) is cheap this days !
Seems http://www.nem.io have built their software separating in client and server components, the client using the rest api published by the server. Would that be a good approach?
If you don't want to bother generating the deterministic keys online, you could pre-generate thousands, even millions of them if you want. And keep both the private and public master keys offline. It also is a safer approach since you can securely store the master private key in a offline hardware wallet and not have to worry about keeping track of hundreds of private keys.
Long time since I've been active in Bitcoin, but this is the way I would have run a payment service without using a full node.