Bitcoin Forum
November 03, 2024, 05:11:22 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: How do I generate the transaction IDs used in createrawtransaction?  (Read 854 times)
arosca (OP)
Newbie
*
Offline Offline

Activity: 38
Merit: 0


View Profile
April 21, 2014, 02:00:59 AM
 #1

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!
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
April 21, 2014, 04:26:11 AM
 #2

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.
arosca (OP)
Newbie
*
Offline Offline

Activity: 38
Merit: 0


View Profile
April 21, 2014, 12:16:55 PM
 #3

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!
piotr_n
Legendary
*
Offline Offline

Activity: 2055
Merit: 1359


aka tonikt


View Profile WWW
April 21, 2014, 12:54:53 PM
 #4

"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

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
arosca (OP)
Newbie
*
Offline Offline

Activity: 38
Merit: 0


View Profile
April 21, 2014, 01:34:52 PM
 #5

That makes sense.

Thank you very much!
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
April 21, 2014, 02:44:43 PM
 #6

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.
arosca (OP)
Newbie
*
Offline Offline

Activity: 38
Merit: 0


View Profile
April 21, 2014, 03:21:21 PM
 #7

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!
DannyHamilton
Legendary
*
Offline Offline

Activity: 3472
Merit: 4801



View Profile
April 21, 2014, 03:32:39 PM
 #8

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 <pubKeyHash> 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 <pubKeyHash>, 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).

DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
April 21, 2014, 04:27:10 PM
Last edit: April 21, 2014, 05:34:49 PM by DeathAndTaxes
 #9

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 <pubKeyHash> 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").

arosca (OP)
Newbie
*
Offline Offline

Activity: 38
Merit: 0


View Profile
April 21, 2014, 06:17:33 PM
 #10


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://bitcointalk.org/index.php?topic=321051.0

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.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!