Author

Topic: How do I generate the transaction IDs used in createrawtransaction? (Read 857 times)

newbie
Activity: 38
Merit: 0

Quote
Are you sure you need to use raw transactions?  There are higher level RPC calls.  If you don't care which specific unspent output is being referenced in the transaction, you could just use sendtoaddress (or sendmany) RPC call.  The created transaction still references the unspent output(s) of prior transaction(s) however it is handled internally by the client ("coin selection").

I am primarily trying to understand the RPC API better, and this entire post definitely accomplished that, as well as giving me a better understanding of the underlying protocol.

We may be getting off-topic in this post, but what got me started down this path is a project in which I need to keep track of balances in different accounts in the same wallet and move funds between them as part of a business workflow. The problem is that the actual account construct is not well-suited for this because apparently the client does not handle large numbers of accounts well:
https://bitcointalksearch.org/topic/bitcoind-accounts-best-practices-321051

So my next-best approach would have been to use addressed in lieu of accounts. In that situation sendtoaddress does not work because it does not give me control over which addresses (er... outputs, now that I know what I'm talking about thanks to you guys) the funds are coming from. This is why I started looking into creating raw transactions.
donator
Activity: 1218
Merit: 1079
Gerald Davis
Thank you for the explanation! It is very helpful.

It does seem odd at first that createrawtransaction needs prior transactions as inputs and addresses as outputs. It is a lot more intuitive to think of each transaction as transferring funds from one set of addresses into another set of addresses. But, in light of how you explained it, it does make sense.

Thank you again!

At the protocol level addresses are never used.  To create a transaction you need the PubKeyHash of the output.  There is a 1:1 relationship between the PubKeyHash and Address which is why clients (both in createrawtx and in a high level GUI client) can "send coins" to an address.  The first thing the client does is validate the address and then convert it to the PubKeyHash.  The protocol could care less about addresses however humans can make errors and the Address being the PubKeyHash encoded, versioned, and checked is useful for catching errors (like trying to send Bitcoins to a LiteCoin address, or catching a typo because the checksum now doesn't validate, or catching a truncated address because browser form cut off the last digit, etc).

On edit: Danny beat me again.

The "addresses as outputs" are just a shorthand way to talk about a particular type of transaction.

To emphasis the important point Danny made, the "OP_DUP OP_HASH160 BYTES_TO_PUSH OP_EQUALVERIFY OP_CHECKSIG" (i.e. "sending coins to an address") is by far the most common type of transaction output but it isn't the only type of output.


Are you sure you need to use raw transactions?  There are higher level RPC calls.  If you don't care which specific unspent output is being referenced in the transaction, you could just use sendtoaddress (or sendmany) RPC call.  The created transaction still references the unspent output(s) of prior transaction(s) however it is handled internally by the client ("coin selection").

legendary
Activity: 3472
Merit: 4801
It does seem odd at first that createrawtransaction needs prior transactions as inputs and addresses as outputs. It is a lot more intuitive to think of each transaction as transferring funds from one set of addresses into another set of addresses. But, in light of how you explained it, it does make sense.

The "addresses as outputs" are just a shorthand way to talk about a particular type of transaction.

createrawtransaction isn't actually transferring value "into another set of addresses".  Instead, it is creating new outputs, with a script in a particular form.  The only information that createrawtransaction needs from the user to create the script is the bitcoin address, however the actual output of createrawtransaction places the following script into the output:

Code:
OP_DUP OP_HASH160 BYTES_TO_PUSH  OP_EQUALVERIFY OP_CHECKSIG

You'll notice that there is no bitcoin address in that script at all.  The closest thing you see there to an address is , which can be calculated from a bitcoin address but which does not have the version byte in the beginning or the 4 bytes of checksum at the end (and isn't Base58check encoded).

newbie
Activity: 38
Merit: 0
Thank you for the explanation! It is very helpful.

It does seem odd at first that createrawtransaction needs prior transactions as inputs and addresses as outputs. It is a lot more intuitive to think of each transaction as transferring funds from one set of addresses into another set of addresses. But, in light of how you explained it, it does make sense.

Thank you again!
donator
Activity: 1218
Merit: 1079
Gerald Davis
I see. So if I understand correctly, the txids are in essence (indirectly) referencing addresses. I'm curious--why was the protocol not designed for transactions to simply contain the source addresses and the amounts to be withdrawn from each?

Also, is there a way to easily obtain the txids programatically? When building a new transaction record, I normally have the address I want to spend from, rather than transaction IDs of transactions that may have previously deposited funds to those addresses.

This is a very common and incorrect way of thinking how Bitcoin works.  It might work for someone talking on the news in the abstract but it completely falls apart when actually working with Bitcoin.

Bitcoin works on the concept of inputs and outputs.  There is no such thing as "an amount at an address" or "withdrawing funds from an address".   All inputs are references to prior unspent outputs. All outputs place conditions on what is required for that output to be used in a future transaction.  For "normal" txs this is the input will need to be signed by the correct private key however outputs are actually scripts so the conditions can be more complex. 

To reference a specific output requires two elements the transaction id (which gets you to the transaction containing the output) and the index (which specifies which of the n outputs is being referenced).  One way to think of it is transactions destroy unspent outputs (making them spent) and create new outputs.  

The reason for this is because is greatly simplifies the validation model.  To validate transactions only requires nodes to keep in memory the set of unspent outputs (UXTO).  If a node receives a tx which has as its input a reference to an output not in the UXTO then either the node is missing a prior tx (and it can query other nodes for the missing tx) or the tx is invalid.  If a node receives a tx which is not in the UXTO but has already been spent before then it is invalid.
newbie
Activity: 38
Merit: 0
That makes sense.

Thank you very much!
legendary
Activity: 2053
Merit: 1356
aka tonikt
"the txids are in essence (indirectly) referencing"... - not "addresses", but specific coins; coins which are known to be unspent.
in reality the blockchain protocol does not deal with such a thing as an "address" - instead it deals with a so called output scripts.
"address" is just a concept that made the technology more user-friendly, but the block-chain itself operates on unspent coins (described by txid+vout) that are protected by output scripts.

"to easily obtain the txids programatically?"
check out this RPC command:
Code:
listunspent
newbie
Activity: 38
Merit: 0
I see. So if I understand correctly, the txids are in essence (indirectly) referencing addresses. I'm curious--why was the protocol not designed for transactions to simply contain the source addresses and the amounts to be withdrawn from each?

Also, is there a way to easily obtain the txids programatically? When building a new transaction record, I normally have the address I want to spend from, rather than transaction IDs of transactions that may have previously deposited funds to those addresses.

I'm doing all this on testnet.

Thank you very much!
donator
Activity: 1218
Merit: 1079
Gerald Davis
You don't generate the tx ids.  They are the tx id(s) of the output(s) you are referencing in the input side of the tx.  All inputs are references to the unspent outputs of prior transactions.  If you are "playing around" I recommend playing around on testnet.  It is possible to create raw txs which are valid but also result in the permanent loss of your coins.
newbie
Activity: 38
Merit: 0
I am playing around with raw transactions. It's not clear to me however how I generate the txid parameters. I haven't been able to find any examples.

Thanks!
Jump to: