Title: Understanding Basic Transaction Structure Post by: bigbeninlondon on May 18, 2014, 01:01:51 PM I'm trying to understand the internal workings of a transaction, so I executed the following command against bitcoind
Code: bitcoind getrawtransaction fd3d049c9e75f96f9786b965b77b99fa0e7d39fa95e0b126682658299e71ac70 1 Here's the response: Code: { In a multi-sig scenario, I'm assuming the "reqSigs" under scriptPubKey (which is 1 in this example) would be higher than 1 and there'd be multiple addresses in the "addresses" array. So here's my questions
I've tried some preliminary googling but can't seem to get a straight answer on the JSON representation of a multi-sig transaction. Thanks. Title: Re: Understanding Basic Transaction Structure Post by: piotr_n on May 18, 2014, 02:07:41 PM Does anyone know of a multi-sig transaction I could look up on the blockchain to see it's structure? Sending to ma multisig address looks like this: https://blockchain.info/tx/a93bd9eeaebcf4cd28e5822d28dddeb3e766e65e01e140168a90f928144e1c38 (first output)And spending from it, like this: https://blockchain.info/tx/d9a2ef9c07ab71ac12680df72cbbbf6153e7bb7ea511eb8ca764f434d378bbea Actually this one spends from multisig address and sends the change to itself (6th output) Quote How do you determine the target address of the multi-sig output? The target address is basically a hash of the script that can spend it.Taking as an example the transaction from the previous link, inside the input script you can find the spend script: Code: 532102de57a0ac92a982903599cc1125f3ad6c360f5e091be2667bd2a07efae637d68a2102f0003265a9c7f5acdb7a40b9b98ace45f3111f421274c7b94f697faa337ac4c02103938fcd91c0a318876975a5648053eccb9ef275a0bade7b79f35d0f90694866652103a145418c25662a857248a9f49ff10ee4a53d28ce144a6954b19a71bbdc68c0c12103cf2e5b02d6f02340f5a9defbbf710c388b8451c82145b1419fe9696837b1cdef55ae Code: 0136d001619faba572df2ef3d193a57ad29122d9 To turn this Hash160 into a text-representation, you do this: https://en.bitcoin.it/wiki/Base58Check_encoding You will use 0x05 as the version byte for a multisig address. Title: Re: Understanding Basic Transaction Structure Post by: bigbeninlondon on May 18, 2014, 02:26:21 PM Ok, so it looks like multisig outputs each still only have one address in the "addresses" property of scriptPubKey property of the vout, and the only difference is the script that must be executed to unlock the output.
I guess I wrongly assumed that the vout.scriptPubKey.addresses[] property would list the addresses that can spend the output. What is this array for? It looks like it always just holds the output public key. Is that correct? In what scenario would this array have multiple addresses? Title: Re: Understanding Basic Transaction Structure Post by: piotr_n on May 18, 2014, 02:28:47 PM Sorry, this I don't know.
Seems like you are talking about specifics of some source code that I am not familiar with. Title: Re: Understanding Basic Transaction Structure Post by: bigbeninlondon on May 18, 2014, 02:33:56 PM Sorry, this I don't know. Seems like you are talking about specifics of some source code that I am not familiar with. No I'm referring to the bitcoind output. if you look at the output for the transaction spending "from" the multi-sig, you'll get this: Request: Code: bitcoind getrawtransaction d9a2ef9c07ab71ac12680df72cbbbf6153e7bb7ea511eb8ca764f434d378bbea 1 Response: Code: { The output has an array of "vouts". Each "vout" has a "scriptPubKey" property, and each "scriptPubKey" property has an array "addresses". I'm curious what the "addresses" array is in the serialized rawtransaction output from bitcoind. Title: Re: Understanding Basic Transaction Structure Post by: piotr_n on May 18, 2014, 02:38:10 PM Oh, I see.
You're right - it doesn't seem to make much sense, having multiple addresses record there. You'd need to ask then guys who put it in there. Title: Re: Understanding Basic Transaction Structure Post by: DeathAndTaxes on May 18, 2014, 02:39:57 PM There are two types of multisig. There is "native" multisig where the script and pubkeyhashes are in the vout however that makes for very large addresses. P2SH was added later. With P2SH the output is a hash of the script and that makes the address compact.
With native multisig there would be multiple pubkeyhashes in the output. With P2SH there is just a single scripthash in the output. While bitcoin may show addresses understand that addresses are encoded hashes (either PubKeyHashes or ScriptHashes) and they don't exist in the protocol itself. When you provide an address to a client it decodes the address to the reslting hashtype and the Hash is what is actually placed in the output of the transaction. Title: Re: Understanding Basic Transaction Structure Post by: bigbeninlondon on May 18, 2014, 04:44:13 PM There are two types of multisig. There is "native" multisig where the script and pubkeyhashes are in the vout however that makes for very large addresses. P2SH was added later. With P2SH the output is a hash of the script and that makes the address compact. With native multisig there would be multiple pubkeyhashes in the output. With P2SH there is just a single scripthash in the output. While bitcoin may show addresses understand that addresses are encoded hashes (either PubKeyHashes or ScriptHashes) and they don't exist in the protocol itself. When you provide an address to a client it decodes the address to the reslting hashtype and the Hash is what is actually placed in the output of the transaction. I'm sorry I'm not quite sure I understand. Maybe if I tell you my intent it'll help understand where I'm lost. I'm trying to write an algorithm to calculate the balance of a public key. I had figured to add up all the inputs and subtract out all the outputs as I scanned along the block chain. From what I gather I'll have to decode the address to the resulting hash type and compare that to the hash that is placed in the output of each transaction I parse? Title: Re: Understanding Basic Transaction Structure Post by: DeathAndTaxes on May 18, 2014, 05:10:53 PM Well there is no address in any transaction so you don't need to decode the address (but you will need to decode the output script). There is no such thing as a balance, when a wallet says it has an X balance it means the sum of the value of the unspent outputs it has the ability to spend is X. There are just inputs and outputs. Inputs reference a prior unspent output so you don't need to add them. Outputs are either spent or unspent. If an output is referenced is a future transaction input then it is spent. Only unspent outputs can be spent in the future so your "balance" is just the sum of the outputs which are not yet referenced in an existing transaction's input.
There isn't necessarily a 1:1 relationship between outputs and public keys as outputs are actually scripts and can be in a variety of formats. So if you want to handle all possible outputs your parser will need to decode the scripts. The most common formats are PayToPubKey (obsolete was used in early generation "coinbase" transactions) PayToPubKeyHash (what most people think of as a "normal" transaction) PayToScriptHash (aka P2SH, the address encodes a script hash not a pubkeyhash so payments are locked by the terms of a specific script) Native Multisig (output script contains multiple public keys and OP_CHECKMULTISIG opcode) P2SH and native Multisig are both methods to encumber an output with multiple keys. They do the same thing in different ways. In native, the output contains the actual script. In P2SH the output contains the hash of the script needed to "spend" the output. P2SH is more common now and is often just called multisig which can make it complicated. Here is a transaction with a native multisig (1 of 2) in the output (vout[0]): 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1 Here is a transaction with a P2SH output (vout[5]): d9a2ef9c07ab71ac12680df72cbbbf6153e7bb7ea511eb8ca764f434d378bbea Yes Bitcoin is complicated. We often talk about "sending coins to this address" but that kinda breaks down at the actual protocol level. All outputs (as in all even "normal" transactions) are scripts. The script defines what is required to spend that output. If you use term like "balance of pubkey" in the case of multisig (either native or P2SH) which PubKey "has" the balance of the output? With native multisig there are multiple pubkeys and a single output. With P2SH you may not even know the script yet (just a hash of the script) so you have no way to determine which PubKey(s) can spend it. If you wanted to limit it to "normal" transactions (PayToPubKeyHash) you could just ignore all outputs which don't match this template OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG This may be a good first step. Title: Re: Understanding Basic Transaction Structure Post by: bigbeninlondon on May 18, 2014, 05:35:59 PM Well there is no address in any transaction so you don't need to decode the address (but you will need to decode the output script). Ok, so when I see the "addresses" array in the bitcoind verbose output, is the bitcoind server doing some calculating for me? There is no such thing as a balance, when a wallet says it has an X balance it means the sum of the value of the unspent outputs it has the ability to spend is X. I understand that the protocol itself does not keep track of balances, which is part of the reason I'm tackling this issue. When I say "bitcoind getbalance", it sums up all the unspent outputs I have available to me. I'd like to programatically do the same for an arbitrary list of public keys. If I have to parse the scripts then I'll do so, I'm just trying to get a handle on exactly what is required to calculate the available unspent outputs. For now I'll stub out all other script formats besides the "normal" one, and tackle those later. We often talk about "sending coins to this address" but that kinda breaks down at the actual protocol level. All outputs (as in all even "normal" transactions) are scripts. The script defines what is required to spend that output. If you use term like "balance of pubkey" in the case of multisig (either native or P2SH) which PubKey "has" the balance of the output? Exactly my question. I feel like I'm missing something fundamental here; how would a client calculate a 'balance' to be displayed in this kind of situation? I'll probably have to do some testnet transaction creation to understand a bit more how this all works. If you wanted to limit it to "normal" transactions (PayToPubKeyHash) you could just ignore all outputs which don't match this template OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG This may be a good first step. For the moment I'll probably do this just so I can have some info to work with, but eventually I'll need to handle all the cases. Title: Re: Understanding Basic Transaction Structure Post by: DeathAndTaxes on May 18, 2014, 05:53:01 PM Quote Exactly my question. I feel like I'm missing something fundamental here; how would a client calculate a 'balance' to be displayed in this kind of situation? It wouldn't unless the wallet had the required number of private keys.Quote When I say "bitcoind getbalance", it sums up all the unspent outputs I have available to me. I'd like to programatically do the same for an arbitrary list of public keys. When you decode the output PayToPubKeyHash are easy it is a 1:1 relationship between unspent outputs and the pubkey.To properly show the "balance" for native multisig you would need to decode the script and follow the "instructions". If the script requires 2 of 5 signatures from a list of PubKeys (P1 to P5) and you have P1 and P4 in your wallet then you can "spend" that output so it would be logical to say that balance is available. If you only have 1 of those keys P1 well how you show it will depend on what you are trying to show. You could just consider it unspendable as 1 of 5 keys is insufficient. You could show it as a seperate balance (additional keys/signatures needed). P2SH works very similar except the script is not in the output. You will need a copy of the redeem script which hashes to produce the ScriptHash in the output. If you do not have the redeem script you can't even verify if you have the required PubKeys (as they are unknown). If you do have the redeem script it would be parsed similar to multisig above. As for how do existing clients do it. My understanding is that the bitcoin-core client's "balance" reflects all unspent outputs which can be spent. For single key it means the private key is in the wallet, for native multisig it means the required private keys are in the wallet, for P2SH the P2SH address, redeem script, and required private keys are in the wallet. It may help to think of "balance" as the sum of value of all outputs the wallet has the ability to spend. Title: Re: Understanding Basic Transaction Structure Post by: bigbeninlondon on May 18, 2014, 10:13:55 PM Ok, that makes a bit more sense. Thank you for clearing that up for me. Do you have a tip address?
|