No:
1. Each node would generate a new public key after installation.
2. The node publicizes it for future communications.
3. It is not changed later on.
Hence an attacker cannot generate a new one as mtgox, your brother and friend for instance would always be using the same public keys.
The attacker would have to steal each of these along with your upstream connection to pull off his attack.
But that is as I have been saying. Trusting any public key would not do, you would need to trust the particular public keys. i.e. You need to trade public keys with your brother in person. Not something you should expect ordinary people to do. This is where hard coded node keys, and maybe PKI comes in.
How do you even know whether or not you have "valid previous inputs"? You don't.
This is the sort of thing Merkle trees were used for. I'm sure you meant to say output. What is needed to validate a transaction is a previous output of another transaction.
You ALWAYS have to know about ALL of them, both in and out to know the real balance of an address. If you don't you can't "verify" a transaction because you don't know if prior inputs have been spent or not.
You can't spend inputs. The money "available to a bitcoin address" (Which is not a very accurate picture) is the unspent outputs that can be redeemed by the private key related to the address. You simply add up all the unspent transaction outputs that the private key can spend. Clients will form the balance by adding up all outputs spendable by the keys in the wallet. Simple stuff then really.
However by only looking at only some of the addresses on the block chain you can both verify blocks (the parts you are watching anyway) AND avoid having to download, process and store the entire block.
I think you have a fundamental misunderstanding of the bitcoin protocol. Transaction inputs are not parts of a transaction that say "put xyz into this address" and outputs are not the opposite. Inputs link previous outputs to a transaction so you can spend those outputs. The outputs define who can spend the money next. The next people will need the correct inputs to spend those outputs and so on. It's all very simple. The money spendable by you, are all the unspent outputs that you recognise can be spent by you. You just need to provide the correct input (The usual case is a signature followed by a public key). The bitcoin client looks for standard transactions and finds the outputs that have any of your bitcoin addresses in them.
In the standard bitcoin address transactions the previous output script will be like:
OP_DUP OP_HASH160 <your address> OP_EQUALVERIFY OP_CHECKSIG
This output describes how to spend the bitcoins. All outputs have a value to them, so they apply to a certain amount of bitcoins.
This can be spent with the input script:
<your signature for the spend><your public key>
Inputs simply prove you can spend an output. Transactions are signed so that only you can spend money owned to you. The input is run first, pushing the signature and public key onto the stack:
stack: <your signature for the spend><your public key>
The output is run, to verify the public key is what the previous spender wanted in the output by comparing hashes. The signature is then checked to verify that the spender owns the public key and the transaction contents cannot be changed without invalidating the signature.
program pointer: OP_DUP OP_HASH160 <your address> OP_EQUALVERIFY OP_CHECKSIG
stack: <your signature for the spend><your public key>
Duplicate top stack item.
program pointer: OP_HASH160 <your address> OP_EQUALVERIFY OP_CHECKSIG
stack: <your signature for the spend><your public key><your public key>
Hash top stack item with SHA-256 and then RIPEMD-160
program pointer: <your address> OP_EQUALVERIFY OP_CHECKSIG
stack: <your signature for the spend><your public key><your address (hash of public key)>
Push <your address> onto stack.
program pointer: OP_EQUALVERIFY OP_CHECKSIG
stack: <your signature for the spend><your public key><your_address><your_address>
Verify that the top two stack items are equal. If not, exit with failure.
program pointer: OP_CHECKSIG
stack: <your signature for the spend><your public key>
Take off the top item from the stack as the public key and the next as the signature and check the signature for the public key. If OK, push OP_TRUE onto the stack, else push OP_FALSE.
program pointer:
stack: OP_TRUE
The stack is left with true and had no failures, hence the input correctly spends the output.
I beg to differ.
A client that breaks protocol is simply ignored in bitcoin.
The rest is hard as nails cryptography.
Imagine that over 50% of the mining power is owned by people who are willing to collude to reverse transactions? Unlikely, but we trust that will not happen. A very easy thing to trust. And you need to trust your connection is safe. Saying bitcoin needs trust most of the time is quite pedantic.
I don't know all the details, but if you have ONE router connecting to the internet through ONE phone/fiber cable then "all" I need is to cut it and splice it into my fake internet-portal-hack-machine.
Not likely to happen though, is it?
I suppose you are building a light client like electrum or you shouldn't have to rely on trust.
My client will place trust in difficulty using the SPV model. The server will be used as a trusted node but also to offer special (and currently secret) bitcoin services.
PKI is a nonsolution to the connection hijacking problem since they can also spoof the certificate authority.
So in other words, the security of the entire internet is doomed?... How does an attacker spoof a CA? They'd need the private keys of the CA....?