It was suggested to me that when users withdraw, I should send bitcoins to users manually from an offline wallet. I was thinking of using Armory to do this and to install an Armory Watching-only wallet (
https://bitcoinarmory.com/about/using-our-wallet/) on the server. Have you looked into this? Did you use Armory's offline wallet for your "cold storage"?
Did you automate the sending of bitcoins to users?
We wanted withdrawals automated, so we don't use a watch-only wallet.
I read up on
https://en.bitcoin.it/wiki/Accounts_explained. It states:
Wallet backups are an issue; if you rely on a good backup of wallet.dat then a backup must be done every time an address is associated with an account and every time the 'move' command is used.
The accounts code does not scale up to thousands of accounts with tens of thousands of transactions, because by-account (and by-account-by-time) indices are not implemented. So many operations (like computing an account balance) require accessing every wallet transaction.
Most applications already have a customer database, implemented with MySQL or some other relational database technology. It is awkward at best to keep the bitcoin-maintained Berkely DB wallet database and the application database backed up and synchronized at all times.
Armory claims that one backup of their wallet is good enough forever. I wonder if their wallet backups have the same issue as stated above.
If the accounts code does not scale up to thousands of accounts, then what are you going to do if you get thousands of customers?
Do you try to synchronize your database with Bitcoin's wallet database?
We solve the wallet backup problem by keeping a copy of the private keys in the database. For now, we're using the account system with thousands of accounts and tens-of-thousands of transactions without issue. We have a secondary ledger than uses walletnotify and blocknotify to stay in sync. We still use the bitcoin account system as the place of record, but our side-by-side tests have been perfect so far. We could move off of the built-in account system if we needed to. But you asked the easiest way to do some testing - not the most robust
FWIW, this is also our cold-storage strategy. When a user logs in, we push funds from the holding account into their account so they can play. When they logout, we move it back to the holding account. Then, we only keep a percentage of the total funds in teh holding account to support the numebr of people on the site at any given time. This means if we got a rush of users, we would need to turn some away. If only that would happen
I'm not familiar enough with the armory system to comment on their wallet. Perhaps they create a large number of addresses instead of the 100 (default) created by the reference client? Not sure...
Thanks for your help and suggestions. I think I got my work cut out for me. I will do the following:
- Install Armory
- Add walletnotify and blocknotify options in bitcoin.conf
- Get Testnet coins from faucets
- Run Bitcoind with testnet=1 in bitcoin.conf
- Try executing Bitcoin API and Account commands and send Testnet coins to myself
That sounds about right. Note that you can do all of that without writing any software. *notify can just be echos to a text file. Also, bitcoind is a commandline version of the api, so you can do bitcoind getinfo, or bitcoind listtransactions, etc. to test out the api.
We user sendFrom so they funds are removed from the users account, rather than the wallet.
According to
https://bitcointalksearch.org/topic/bitcoind-create-accounts-via-api-300632, we should do this:
- Create a new account for each user to accept deposit from with getaccountaddress
- Then have a daemon that checks listsinceblock for any deposits.
- If deposit is found, use move to transfer the balance to the "bank" account and credit the user.
- Then the next time listsinceblock is called, they will show up as 0.
- All outgoing withdraw is sent via move from "bank" account to withdraw address.
Is the above what you did? Am I correct to assume that you use walletnotify and blocknotify instead of "a daemon that checks listsinceblock for any deposits"?
Pretty close. We create a new account for the user, then use walletnotify to watch for deposits. When a deposit comes in, it's "unverified".
We then use blocknotify to watch for new blocks. When a block comes in, we check the balance of the users account with 0 confirmations, then again with 4 confirmations. The delta is their "unconfirmed" balance.
We don't do the sweep currently on the live site, but that's how we handle cold storage.
I cannot find out anywhere how blocknotify tells me that a particular transaction is confirmed. Am I correct to assume that I will receive data from blocknotify once I test with Testnet coins and this data will contain the transaction ID (from which I can use gettransaction to get the customer's account, address and amount)?
It's not obvious.
You can call getbalance and pass in the number of confirmations you want. So if a user has 10 confirmations on their first 1btc deposit, and 2 confirmations on their second 5btc deposit:
getbalance 0 confirmations = 6btc
getbalance 4 confirmations = 1btc
From that, we can calculate that they have a balance of 1btc, and an additional 5btc unconfirmed.
So then blocknotify is only used to say, "A new block was received, and users' confirmations may have changed."
We just use it to trigger a re-check of the users that have unconfirmed funds. If the confirmed and unconfirmed balances are the same, we can stop checking their account with each new block.
Do I need SSL to run Testnet or main Bitcoin network?
According to
http://www.ideaexcursion.com/2013/09/18/developing-against-bitcoind/: "working with Bitcoin can be EXCRUCIATINGLY difficult" and there are a lot of things to do when using it. I think the adoption of Bitcoin for consumers and sellers of services/goods will be much more widespread if Bitcoin was easier. Hopefully, I can ask you more questions if I run into difficulty.
Only run on testnet. There's no need to run on mainNet until you're getting close to launch.
I'm happy to answer questions. Just know that you're only getting one team's opinion. There are a million ways to do things
Know that your server will be attacked, your faucet will be drained, your games will be botted, your service provider will let people in to your datacenter to install VKMs, etc.
What are VKMs? Virtual Knowledge Managers? What harm can they do?
Virtual Keyboard and Mouse. A well known bitcoin casino had their data center's maintenance site hacked. Someone put in an order to have a VKM installed. The machine rebooted and the attackers attempted to use the vkm to get console access. Thankfully, the casino used full-disk encryption, so reboots required a manual password step.
Attackers in this space are really, really clever.