They key bits of code are: fileout << FLATDATA(pchMessageStart) << nSize; ... fileout << *this; pchMessageStart are the four magic bytes, and those are written with FLATDATA. The CBlock itself is written by << *this, and that's done by the IMPLEMENT_SERIALIZE in main.h: IMPLEMENT_SERIALIZE ( READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(hashPrevBlock); READWRITE(hashMerkleRoot); READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce);
// ConnectBlock depends on vtx being last so it can calculate offset if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) READWRITE(vtx); else if (fRead) const_cast<CBlock*>(this)->vtx.clear(); )
The READWRITE macros Do The Right Thing, reading in or writing out the members in a machine-independent way. See http://github.com/gavinandresen/bitcointools for simplified Python code that can dump out transactions and blocks.
|
|
|
If a philanthropist wants to give away bitcoins to the bitcoin community, I'd be happy to reset the Bitcoin Faucet rules to whatever the philanthropist would like.
Could be: donate 10,000 Bitcoins and then have the Faucet distribute 10 per IP address (regardless of whether or not they got coins from the Faucet before) until they're gone.
|
|
|
BTW, I haven't tested it, but I hope having rpcpassword= in the conf file is valid. It's only if you use -server or -daemon or bitcoind that it should fail with a warning. If it doesn't need the password, it should be fine. Is that right?
Yes, that's right, rpcpassword is only required if you use -server or -daemon or bitcoind (I just tested to be sure). RE: what if the programmer can't figure out how to make their legacy COBOL code do HTTP authentication? Then I think another config file setting to explicitly turn off RPC authentication would be better than a magical "if you set a blank rpcpassword then that turns off authentication." But I wouldn't implement that until somebody really does have a problem or until we have more than one way of doing the authentication (maybe https someday...). lachesis: is supporting HTTP Basic Authentication a problem for you?
|
|
|
What's funny?
A server lying about whether or not your transactions are valid would be like your ISP lying about whether or not your HTTP requests are valid or not.
If they lie, you'll very quickly find another service provider (or download a Bitcoin iPhone app that doesn't suck and say that your transactions are invalid).
|
|
|
The password definitely shouldn't be required.
I strongly disagree; software should be secure by default, and running bitcoind without a password (or bitcoin -server) is definitely NOT secure. I just don't see somebody saying "Man, Bitcoin sucks because I have to add a password to a configuration file before running it as a daemon." I can see somebody saying "Man, Bitcoin sucks because I accidently ran it with the -server switch and somebody stole all my money."
|
|
|
Yes, I think that would be really good so each dev doesn't have to figure it out themselves. We need a simple example for each of Python, PHP and Java importing the json-rpc library and using it to do a getinfo or something, including doing the http authentication part.
OK, I did Python and PHP, and I added what I know about Java. Can somebody who has used Java JSON-RPC update the wiki page with a working example?
|
|
|
I've updated the RPC wiki page for how the password stuff will work in Bitcoin 0.3.3. One nice side effect: you can prepare for the changes now; create a bitcoin.conf file with a username and password and modify your JSON-RPC code to do the HTTP Basic Authentication thing. Old code will just ignore the .conf file and the Authorization: HTTP header. Question for everybody: should I add a section to the wiki page describing, in detail, how to do HTTP Basic authentication? PHP and Python make is really easy-- just use the http://user:pass@host:port/ URL syntax. I don't want to just duplicate the HTTP Basic authentication Wikipedia page.
|
|
|
TxIn: prev(82df...6428:1) means the second TxOut of transaction 82df...something...6428 (it abbreviates the full 256-bit transaction hash and starts counting at zero). To see that transaction: gavin$ dbdump.py --transaction=82df...6428 1 tx in, 2 out ['TxIn: prev(bfb0...cd16:1) pubkey: 17muZqKMEFqzefsqYhR9vqBjz1jNVcDcbh sig: 71:3044...0201 65:0480...af42'] ['TxOut: value: 0.05 pubkey: 1GVgigFDZ9pPLyYwxboEoaSDMDbsBQPVMx Script: DUP HASH160 20:a9f6...9268 EQUALVERIFY CHECKSIG', 'TxOut: value: 66.07 pubkey: 1LsvDRhoMmH5YeZDAxaP5rqwNTp3xFCF3Q Script: DUP HASH160 20:da0b...a345 EQUALVERIFY CHECKSIG']
This looks like bitnickels coins coming out of the Bitcoin Faucet. The transaction before THAT is: gavin$ dbdump.py --transaction=bfb0...cd16 1 tx in, 2 out ['TxIn: prev(b1dd...5cd9:1) pubkey: 1MQNsNwRHTu7MWPgFRGRRZfo58jU3RGxJv sig: 73:3046...8501 65:041b...6624'] ['TxOut: value: 0.05 pubkey: 1GVgigFDZ9pPLyYwxboEoaSDMDbsBQPVMx Script: DUP HASH160 20:a9f6...9268 EQUALVERIFY CHECKSIG', 'TxOut: value: 66.12 pubkey: 17muZqKMEFqzefsqYhR9vqBjz1jNVcDcbh Script: DUP HASH160 20:4a4e...e0c3 EQUALVERIFY CHECKSIG']
To compute the net transaction value, just add up the values of all the TxOuts; they have to equal the sum of all the TxIns (well, unless there are transaction fees). So for that first transaction, 66.07+0.05 = 66.12 (which is, indeed, bfb0...cd16:1)
|
|
|
I think this won't work because there is not a one-to-one relationship between "unspent transactions" and public keys.
Example: I start with 0 BTC. Two people each send me 50, to the same receiving address "GavinPubKey".
Balance Sheet: GavinPubKey: 100 I spend the first one: Balance Sheet: GavinPubKey: 50
If I'm dishonest, what stops me from waiting a few months and then spending that first 50 again instead of spending that second 50? Double-spending that first 50 will look like a perfectly valid transaction to any nodes using the balance sheet method who weren't around to see the first time I spent it.
|
|
|
I've implemented it so that all the command-line options can also be specified in the bitcoin.conf file.
Options given on the command line override options in the conf file. But I need to do more testing, especially with the "multiargs" options like "addnode".
|
|
|
I volunteered to implement this, and made good progress today. Satoshi: I should have patches for you tomorrow.
Done: teach Bitcoin to read settings from {BITCOIN_DIR}/bitcoin.conf file, and added -conf=path_to_config_file.conf command-line option. Done: teach Bitcoin RPC to require HTTP Basic authentication, and reject requests with the wrong username/password.
TODO: teach Bitcoin command-line RPC to add the Authorization: header. You won't have to give the username/password when controlling bitcoin from the command line, it'll read them from the bitcoin.conf file and Do the Right Thing. TODO: dialog box or debug.log warning if no rpc.user/rpc.password is set, explaining how to set. TODO: limit password guessing attempts if the rpc.password is < 15 characters long. TODO: update the JSON-RPC wiki page
After all that is done and I've sent patches to Satoshi, I'm going to add a couple more things to bitcoin.conf :
port= # to set the listen port (override default 8333) rpc.port= # to set the JSON-RPC port (override default 8332)
With the existing -datadir option, that'll make it easier for me to run multiple bitcoins on one box.
|
|
|
chroot: won't protect you.
Running as a separate VM: I think will protect you. But I thought browsers wouldn't allow XMLHTTPRequests to "localhost" from web pages fetched from the web, so my advice would be to test it. See if you can talk to the Bitcoin daemon from another VM on the same machine by running "bitcoind getinfo" or "bitcoin getinfo" on the non-bitcoin-vm.
|
|
|
You can still generate bitcoins, just don't run bitcoind or bitcoin -server or bitcoin -daemon on machine that you use to browse the Web.
As sirius says, if you do you could browse to a website that empties your Bitcoin wallet without your knowledge or permission.
|
|
|
I sent him 10 Bitcoins, and my hair grew back!
So I sent him 20 Bitcoins, and I won the lottery!
No Joke!!!! Now I'm hairy and rich!!!!
|
|
|
I think there's no such thing a a "typical" settings file on Linux!
I just did a quick survey of 20 .conf files in /etc on my debian system, and found: 1 file used "key value" 5 used "key=value" (actually, a couple were "key = value", allowing whitespace around the "=") 14 did their own thing.
The 14 that did their own thing were all over the map; from one-value-per-line to "key:value" to full-blown XML. # is the universal comment character in the Linux world.
My vote would be for:
# comment key1=value1
|
|
|
What happens in those few seconds if the coin was double spent? Are you notified before the next block comes in?
I'm not personally notified, no... But if I have a Bitcoin client connected to the network then yes, it (along with all the other connected clients) should be sent every transaction shortly after they happen. It has to-- it might be generating blocks, and the whole point of block generation is to record the valid transactions the client has seen that haven't been included in a previous block. There's a discussion in this thread of how likely it is that an attacker could "split the network" to successfully double-spend coins.
|
|
|
See the " Bitcoin snack machine" discussion. Real-world, ordinary-sized transactions should wait a few seconds for the transaction to propagate across the network.
|
|
|
For a gradual change I suppose a client could be released which understand both the old and new ways, but only uses the old way, then after some time (perhaps take some measurements and estimate what perentage of the network is running the new version) release a version which uses only the new version, and all the old versions would get kicked off the network?
There are already a few places in the source code where that is done. Are there any small changes which could be made to the client to make it more change proof, would they be worth considering implementing?
I think Satoshi's done a darn good job of anticipating future needs. The wire protocol and database serialization formats both have version numbers, as do bitcoin addresses. The core transaction mechanism is very flexible (I worry that it might be too flexible, but that's why we've got the TEST network to see if we can break it). I can't think of anything simple that would make it more future-proof. If you're worried about SHA256 getting broken or the 21quadrillion Bittiestcoins not being enough... then you worry too much. Stop worrying, you'll just suffer from analysis paralysis and get nothing done.
|
|
|
So you drop a settings file in the ~/.bitcoin directory, that sounds better. In the "no password is set" warning, it could tell you where the file is and what to do. What is the most popular and common settings file format?
You ask hard questions! Most common: probably Windows INI files, because Windows is most common OS. I'd lobby for using JSON; it's (mostly) a subset of YAML (which is a common choice for config files), so any JSON or YAML parser will read it. HTTP basic authentication should be considered. In actual practice though, it's more work for web developers to figure out how to specify the password through some extra parameter in the HTTP or JSON-RPC wrapper than to just stick an extra parameter at the beginning of the parameter list. What do you think? Does HTTP basic authentication get us any additional benefits?
I think the only big advantage is that it keeps authentication where it belongs in the transport layer, so if, in the future, you do want to go with full-fledged HTTPS with certificates the API doesn't have to change. I was confused for a bit because the password is given LAST on the command line, but FIRST in the JSON-RPC params list. I agree that reading the command-line password from a file would be more convenient and more secure.
You're also confusing me, what do you mean? Did I do something unintended? No, I just confused "command" with "parameter", and did this: > bitcoind help error: First parameter must be the password. > bitcoind <my password> help error: unknown command: <my password> >bitcoind help <my password> ... that works.
|
|
|
Heh, my mom works at Whole Foods, and they have a sign that says "We Accept ALL forms of payment."
I think that's a politically correct way of saying "we accept food stamps." Try going in with a fistful of Euros and see what happens.
|
|
|
|