Bitcoind transaction data verification

4

1

I find myself a victim of either my poor googling skills, or the lack of detail in the bitcoind docs.

I have a walletNotify script running on a full node that whenever a transaction to / from my wallet arrives, performs a getRawTransaction(txid, 1) on the passed transaction ID.

Now, if any of my addresses appears inside the vout array, I know that that transaction is a deposit. What I'd like to verify, is that I can indeed spend those bitcoins.

I read about non-standard transactions (specifically, unspendable transactions) and kinda panicked, so my questions are:

  1. Does bitcoind perform any sort of verification on the "spendability" of the arriving bitcoins?
  2. Is there any easy way of verifying this myself? is there any not-necessarily-easy way?

Thank you very much in advance!

mpr

Posted 2014-10-27T23:23:02.960

Reputation: 153

Answers

1

Bitcoind only scrapes the blockchain for a few transaction types: Pay-to-pubkey, pay-to-pubkey-hash, and pay-to-script-hash. If you check https://en.bitcoin.it/wiki/Script you'll see many more script operators that can be used, so the protocol isn't just those three script types.

Since the scripts have a very definite form, your client will look for the cases where the payments are to address YOU own instead of others.

OP_DUP OP_HASH160 <20 byte hash> OP_EQUALVERIFY OP_CHECKSIG

If bitcoins were sent to this script but with other script operations at the end, your node wouldn't report them as spendable.

  1. Verifying this yourself is easy if you already have a working and completely correct script interpreter. You could look for non-standard outputs, since they do get mined on occasion.

However, reproducing bitcoind's script interpreter, with bug-for-bug compatibility is tricky. Certain clients have been forked from the blockchain by not following every quirk in the reference implementation.

But if you have this, you could write your own node if you liked. Listen for new blocks from the network, or just from bitcoind. Use your script interpreter to ensure that transactions in new blocks are valid, are correctly signed, and so on. Once you're confident the blockchain you end up with is correct, you can parse for the cases that bitcoind ignores and spend them if you can.

karimkorun

Posted 2014-10-27T23:23:02.960

Reputation: 763

Hi! sorry for the delay. So what you mean is that I won't even get notified when one such nonstandard transaction arrives? or that they won't appear among my UTXOs? Having a working (bug-for-bug) script interpreter is not even not-necessarily-easy :Pmpr 2014-12-15T20:04:53.333

No, your node wouldn't be able to identify it as having anything to do with your wallet. Depending on your use case, maybe you could use txindex=1, and the blocknotify callback? It would trigger a script, passing the block hash as an argument. Decode every raw transaction (why you need txindex), look for outputs whose scripts match what you want, and build your redeem transaction then?karimkorun 2014-12-17T02:03:15.613

0

Don't worry about unspendable outputs too much, those are mainly a way to store a little bit of extra data in the blockchain, or to destroy bitcoins. If someone sent you a transaction that had one unspendable TX output, that wouldn't be bad, as long as the actual coins it was sending took place in the other TX outputs.

  1. Does bitcoind perform any sort of verification on the "spendability" of the arriving bitcoins?

Yes, it needs to in order to determine your wallet balance. For example, if I send to a 2 of 3 multisig address that I only have one of the keys for, the bitcoind client will not register that into your balance, but if I have 2 out of the 3 addresses then it will include transactions to that address in my balance.

  1. Is there any easy way of verifying this myself? is there any not-necessarily-easy way?

There is an easy way! If your balance changes, then you received coins. If you're trying to do a watch-only address, where you're trying to look for changes to an 'address balance' (for lack of a better term) of an address that you don't have the private key for, then then you might try getting the scriptPubKeys hex, which should match exactly with the scriptPubKey you expect.

morsecoder

Posted 2014-10-27T23:23:02.960

Reputation: 12 624

Thanks for answering! But I'm interested in knowing what would happen if someone would send me, say, 1BTC with a script such that I may never spend such a coin... does bitcoind process the script in order to update the balance? any script whatsoever? even nonstandard ones? (multisig scripts are kinda-standard-scripts in this respect)mpr 2014-10-28T01:15:48.243

Well, it does make sure it can spend them so that it can add them to your balance, but it only knows how to spend standard transactions. What kind of a transaction are you thinking of that would credit your address but not be a standard transaction?morsecoder 2014-10-28T01:17:41.603

Well, either of: https://en.bitcoin.it/wiki/Script#Provably_Unspendable.2FPrunable_Outputs, https://en.bitcoin.it/wiki/Script#Anyone-Can-Spend_Outputs, or https://en.bitcoin.it/wiki/Script#Transaction_puzzle would be problematic :P Now, I'm not saying someone will merrily throw their coins away just to try to annoy me, but it's better to be safe than sorry :)

mpr 2014-10-28T01:57:36.037

Agreed, better safe than sorry. Those are not standard transaction, so they won't register to your balance. I think your solution is to just see when your balance changes.morsecoder 2014-10-28T02:34:51.120

Hmm, what if I have many transactions at the same time? Checking for balance changes sounds like it could mistakenly mark a transaction a received when many are happening concurrently.mpr 2014-10-28T14:31:59.007

Not sure what you mean, but you can trust the daemon to do its job, try it! :) If your walletnotify script checks its last balance and if different from current balance, saves the new balance and gives you a notification. I hope my answer helped.morsecoder 2014-10-28T14:39:51.017

What I meant was: while I'm processing walletNotify for nonstandard Tx "A", standard Tx "B" come in as well, the balance gets updated, by the time I check the balance while processing "A", I assume everything worked fine, and accept "A", when, in reality, it was "B" the one changing the balance. I do trust the daemon, the fact of the matter is that it's hard to trust what you don't know much about ;)mpr 2014-10-28T18:34:48.453

@mpr, please mark this as the answer if it helped you.morsecoder 2014-10-29T03:26:46.467

Although your answer provided some clarity, it is still guesswork and not a complete answer in and of itself. If you care to provide a full answer with verifiable sources (either a new one or an edit of this very answer), I'll gladly mark it as accepted and feed you the rep :)mpr 2014-10-29T16:09:51.263