Bitcoin Forum
May 14, 2024, 02:26:27 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: 1 2 [All]
  Print  
Author Topic: [solved]How decode raw transaction?  (Read 3902 times)
Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 03, 2016, 06:08:16 AM
Last edit: May 03, 2016, 08:52:05 AM by Frodek
 #1

One solution is RPC method decoderawtransaction. But is is possible decode by myself? It would be faster and even easier decode from binary format than from JSON.
I found: http://bitcoin.stackexchange.com/questions/42510/how-to-decode-raw-tx-hex-programmatically
https://en.bitcoin.it/wiki/Transaction
1715696787
Hero Member
*
Offline Offline

Posts: 1715696787

View Profile Personal Message (Offline)

Ignore
1715696787
Reply with quote  #2

1715696787
Report to moderator
1715696787
Hero Member
*
Offline Offline

Posts: 1715696787

View Profile Personal Message (Offline)

Ignore
1715696787
Reply with quote  #2

1715696787
Report to moderator
Make sure you back up your wallet regularly! Unlike a bank account, nobody can help you if you lose access to your BTC.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715696787
Hero Member
*
Offline Offline

Posts: 1715696787

View Profile Personal Message (Offline)

Ignore
1715696787
Reply with quote  #2

1715696787
Report to moderator
1715696787
Hero Member
*
Offline Offline

Posts: 1715696787

View Profile Personal Message (Offline)

Ignore
1715696787
Reply with quote  #2

1715696787
Report to moderator
Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 03, 2016, 04:38:59 PM
Last edit: May 03, 2016, 04:50:59 PM by Frodek
 #2

But topic is not solved:
I don't know how read addresses from script.

block hash: 000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf
tx hash : 2871576bb636f71274736a65eeb897d94df7bab6ef9d9dc8eccde49a7658a7cc

block raw: 0100000001a7c3e111fcf6acf6d14a5ec90faedf03ba5fe589069a48113cddd3a43a866c4901000 0006a473044022050c91af9918b85525ebf8802d69a904e85abe6dee306201689107c63a41e7ae2 02206faa2bb6a4073f78672364db85bce6022686c5b604f789d9b9b6383d1086bc830121031d4a1 0c5ae03e291aaf1fced54b1848535fbd926b671726297dd3455c399d380ffffffff02f0874b0000 0000001976a914f5d7afc3df015ecfd309dd591acf1b8f1e0c4ec088acc095a905000000001976a 91475ce9ff7867baffecbb0e61f879bab9e976e9c1488ac00000000

https://blockexplorer.com/tx/2871576bb636f71274736a65eeb897d94df7bab6ef9d9dc8eccde49a7658a7cc

Input:
1 BTC 14cYFWwLHksk3226tUNs44rNpBJzNiPj8i
(scriptSig )

Output
0.0495 BTC (U) 1PQtwAZpv52PS9kgdsdd6hLHN9SCrv15UV Output is unspent
0.95 BTC (S) 1BjuazXd6pBtZpvDXwm76dueoiNJfXLj1p

No addresses in raw data. Is doc https://en.bitcoin.it/wiki/Script but i don't want proceed full interpretation, but find addresses.

I search full real example of interpretation data. What at start is at top of stack. At start each script is empty or is stuff of previous script?
johoe
Full Member
***
Offline Offline

Activity: 217
Merit: 241


View Profile
May 03, 2016, 05:20:18 PM
 #3

But topic is not solved:
I don't know how read addresses from script.

block raw: 0100000001a7c3e111fcf6acf6d14a5ec90faedf03ba5fe589069a48113cddd3a43a866c4901000 0006a473044022050c91af9918b85525ebf8802d69a904e85abe6dee306201689107c63a41e7ae2 02206faa2bb6a4073f78672364db85bce6022686c5b604f789d9b9b6383d1086bc830121031d4a1 0c5ae03e291aaf1fced54b1848535fbd926b671726297dd3455c399d380ffffffff02f0874b0000 0000001976a914f5d7afc3df015ecfd309dd591acf1b8f1e0c4ec088acc095a905000000001976a 91475ce9ff7867baffecbb0e61f879bab9e976e9c1488ac00000000

For the output addresses, find the script_pub_key.  If you follow the instructions in the links you posted you should get

Code:
76a914f5d7afc3df015ecfd309dd591acf1b8f1e0c4ec088ac

for the first output.  Now this is a standard pay to pubkey hash script that decodes as:

Code:
OP_DUP OP_HASH160 f5d7afc3df015ecfd309dd591acf1b8f1e0c4ec0 OP_EQUALVERIFY OP_CHECKSIG

So the hex number is the 160 bit hash of the public key.  Follow the instructions on https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses (starting at step 4) to get the address in base58 encoding.

For the input, you can either take the script_pub_key from the previous transactioon, or extract the pubkey from the input script (the second pushed number), which in this case is
Code:
031d4a10c5ae03e291aaf1fced54b1848535fbd926b671726297dd3455c399d380
Then use the above page, starting at step 2.

Donations to 1CF62UFWXiKqFUmgQMUby9DpEW5LXjypU3
Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 03, 2016, 10:39:31 PM
 #4

Thanks, this explain a lot.
1.
OP_DUP duplicate top of stack? At start output, must something be on the stack. But may be many inputs and many outputs. Inputs pushes to stack and outputs duplicates?
For extract addresses for all cases I  must interprete opcodes?
2.
Daemon bitcoind often give error -5 for getrawtransaction method, why?
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 03, 2016, 10:51:48 PM
 #5

Thanks, this explain a lot.
1.
OP_DUP duplicate top of stack? At start output, must something be on the stack. But may be many inputs and many outputs. Inputs pushes to stack and outputs duplicates?
For extract addresses for all cases I  must interprete opcodes?
The input script is first pushed to the stack. Then then output script. Typically what happens is the signature is pushed, then the pubkey. Then the pubkey is duplicated and hashed to check if it is equal to the hash given in the output script. Then the signature and pubkey that are still in the stack are verified. This is for pay-to-pubkey-hash (p2pkh) outputs. Pay-to-script-hash (p2sh) outputs are different. Other non-standard outputs also have their own scripts that need to be interpreted.

For the addresses, you just do the base58check encoding of the hash160 provided in the output if it is p2sh or p2pkh.

2.
Daemon bitcoind often give error -5 for getrawtransaction method, why?
Because you can only use that method if the transaction is in your wallet or if you have txindex enabled. Otherwise bitcoind doesn't know about the transaction.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 04, 2016, 07:02:28 AM
 #6

1. input script pushes, output duplicates and compare; but if we have may inputs and many outputs, many inputs pushes, other number of output script compares?
2. how enable txindex? I want all historical transactions
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 04, 2016, 11:37:25 AM
 #7

1. input script pushes, output duplicates and compare; but if we have may inputs and many outputs, many inputs pushes, other number of output script compares?
I'm not sure what you are asking. Inputs explicitly reference a previous output and that is the output that it is checked against, not the outputs of the transaction.

2. how enable txindex? I want all historical transactions
Go to the data directory and open the bitcoin.conf file or create it if it doesn't exist. Add the following line
Code:
txindex=1
Restart bitcoin core. Enabling txindex requires that you reindex the blockchain so it will ask you if you want to reindex. Click yes.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 07, 2016, 05:58:14 PM
 #8

My example:
First transaction of block 200'000:
bitcoin-cli getrawtransaction dbaf14e1c476e76ea05a8b71921a46d6b06f0a950f17c5f9f1a03b8fae467f10

01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff4103400d0302ef02062f503253482f522cfabe6d6dd90d39663d10f8fd25ec88338295d4c6ce 1c90d4aeb368d8bdbadcc1da3b635801000000000000000474073e03ffffffff013c25cf2d01000 000434104b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576 782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7bac00000000

I explain a bit:
01000000 version = 1
01 - in counter varInt
0000000000000000000000000000000000000000000000000000000000000000 previous transaction hash
ffffffff - Previous Txout - index
41 - scriptlen = 65
script:
03400d0302ef02062f503253482f522cfabe6d6dd90d39663d10f8fd25ec88338295d4c6ce1c90d 4aeb368d8bdbadcc1da3b635801000000000000000474073e03 - script
ffffffff - sequence no
01 - out counter varInt
3c25cf2d01000000 - amount 5063517500 satoshi
43 - scriptlen = 67
4104b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6537a576782eb a668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7bac - script
00000000 - lock time

I don't know why in first script first opcode is 3? Pushes 3 bytes to stack? why?
Second script : 0x41: pushes 65 bytes? but while script has 65 bytes
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 07, 2016, 06:18:00 PM
 #9

My example:
First transaction of block 200'000:
bitcoin-cli getrawtransaction dbaf14e1c476e76ea05a8b71921a46d6b06f0a950f17c5f9f1a03b8fae467f10
This is a coinbase transaction so it is special. Conbase transactions are always the first transaction of a block.

I don't know why in first script first opcode is 3? Pushes 3 bytes to stack? why?
It pushes three bytes which is the block height in little endian format. The remainder of the script is arbitrary data that the miner includes in the script. This usually is where the extra nonce goes and the miner will put info to identify who mined the block.

Second script : 0x41: pushes 65 bytes? but while script has 65 bytes
The script is 67 bytes. Then 65 bytes are pushed. This pushes the pubkey of the address this output is for. The last byte is OP_CHECKSIG.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 07, 2016, 06:31:17 PM
 #10

This explain a bit. How locate useful data? The block data before OP_CHECKSIG?
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 07, 2016, 06:54:38 PM
 #11

This explain a bit. How locate useful data? The block data before OP_CHECKSIG?
What do you mean "block data before OP_CHECKSIG"?

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 07, 2016, 08:13:37 PM
 #12

"Then 65 bytes are pushed. This pushes the pubkey of the address this output is for. The last byte is OP_CHECKSIG."
Data block 65 bytes is before opcode OP_CHECKSIG
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 07, 2016, 08:14:32 PM
 #13

"Then 65 bytes are pushed. This pushes the pubkey of the address this output is for. The last byte is OP_CHECKSIG."
Data block 65 bytes is before opcode OP_CHECKSIG
Those 65 bytes are the public key for the address. It is a pay to pubkey output.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 08, 2016, 04:33:36 AM
 #14

In block 200'000 I notice two strange transactions.
Usually input script is signature + 33 or 65 key. These have signature alone :


First:
80efe43cf64a524d1417546a027786127ad87475f3af1c13b8f3719cd4268679
raw:
Quote
01000000017a38cfb70605d039c0528618b14d9f6a2a41fcaf407008cb32cc22aee78a2bdb00000 0004a493046022100d666783418029516503cfa10d7be7de6313a038fee3d035c589bed389e43fa 42022100fae2c2e3648d53436ea2afc801f0b7930a7c58cd4186dd3d9a9e86f26499241001fffff fff0100f2052a010000001976a9140568015a9facccfd09d70d409b6fc1a5546cecc688ac000000 00

01000000 version = 1
01 - in counter varInt
7a38cfb70605d039c0528618b14d9f6a2a41fcaf407008cb32cc22aee78a2bdb - previous transaction hash
00000000 - Previous Txout - index
4a - scriptlen = 74
script:
49 - len =73
3046022100d666783418029516503cfa10d7be7de6313a038fee3d035c589bed389e43fa - signature

Second:
7582c231b9a153c0f604601cc03f0b9f460dad704cb57fbd5330ee6b023e31c7
raw:
Quote
0100000001bada3f96d318ada8dc55bac7c2f6f5888e0ab1d7bae58b9ad058cd6b6bb433ad00000 000494830450220365977b2b6864b173a121dea14893ea67859a1ba22b1a00925fa8bd863232cc7 022100ce4700c597456bdc02d393153b5e2dd35c0979fc7767c0ce837e055b6231a19601fffffff f02678dcd2908000000434104a39b9e4fbd213ef24bb9be69de4a118dd0644082e47c01fd9159d3 8637b83fbcdc115a5d6e970586a012d1cfe3e3a8b1a3d04e763bdc5a071c0e827c0bd834a5ac000 93d00000000001976a9146589b34c908d86a50e13eaea1538a9244289a8a388ac00000000

01000000 - version = 1
01  - in counter varInt
bada3f96d318ada8dc55bac7c2f6f5888e0ab1d7bae58b9ad058cd6b6bb433ad - previous transaction hash
00000000 - Previous Txout - index
49 - scriptlen = 73
script:
48 - len =72
30450220365977b2b6864b173a121dea14893ea67859a1ba22b1a00925fa8bd863232cc7 - signature
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 08, 2016, 05:35:57 AM
 #15

In block 200'000 I notice two strange transactions.
Usually input script is signature + 33 or 65 key. These have signature alone
Those spend pay to pubkey outputs. Since the previous output already has the public key in it, and pushes it, there is no need to push the public key as part of the input script.script

luv2drnkbr
Hero Member
*****
Offline Offline

Activity: 793
Merit: 1016



View Profile
May 08, 2016, 01:46:34 PM
 #16

To expand, when you have the "signature" part of a transaction, in order to validate it, you need to concatenate the output script that it's spending.

So an output script might be:

OP_DUP OP_HASH160 XXXXXX OP_EQUALVERIFY OP_CHECKSIG

That script says duplicate the top stack item, hash it, put this XXX on top of the stack, verify that the top two stack items are equal and drop them if they are (or invalidate the tx), and then perform a signature verification on the top two remaining stack items.

So when you spend it, the signature area contains a signature and a public key.  So the stack looks like this:

pubkey
signature

Then the output script is exectued.  First, duplicate the top stack item, so now the stack is this:

pubkey
pubkey
signature

Now, hash160 the top stack item:

XXXX hash
pubkey
signature

Now push XXXX onto the stack

XXXX
XXXX
pubkey
signature

Now verify that the top two items are equal, and remove them from the stack if they are.  They are, so now the stack is:

pubkey
signature

Now do OP_CHECKSIG, which assumes the top two stack items are a public key and a signature, and validates the signature.  If it fails, the tx is invalid, if it passes, it drops them and puts the number one is on the stack.  So now the stack is:

1

And the script is finished.  If the script hasn't failed yet and 0/False aren't at the top of the stack when it's finished, then the transaction is valid.

In your transaction above only the signature, and NOT the public key, was in the signature area.  This means that the output script that it's spending was most likely "pubkey, OP_CHECKSIG".  So to spend it, all you do is provide a signature, and the the stack is just pukey+signature and the OP_CHECKSIG function runs.

That format is known as "pay to public key".  Nowadays, we use "pay to public key hash" which is the format I used my example with: OP_DUP OP_HASH160 XXXX OP_EQUALVERIFY OP_CHECKSIG.  And then the signature area needs to provide a signature AND a public key in order for the script to execute properly.  It doesn't need to do that in your transaciton because the public key was in the output.  But in the newer format, the public key isn't listed, only it's hash is, so you provide the public key yourself, and then the script hashes it and checks that it matches the output's hash before running the OP_CHECKSIG function.

It's done that way so that public keys can remain hidden before you spend the money, so in the event elliptic curves are compromised and a private key can be derived from a public key, your key is still hidden by a hash and you can wait for Bitcoin to roll out a fix.

achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 08, 2016, 02:52:34 PM
 #17

To expand, when you have the "signature" part of a transaction, in order to validate it, you need to concatenate the output script that it's spending.

So an output script might be:

OP_DUP OP_HASH160 XXXXXX OP_EQUALVERIFY OP_CHECKSIG
--snip--
OP is not asking about p2pkh outputs but rather p2pk outputs

A p2pk output looks like
Code:
<pubkey> OP_CHECKSIG

When spending it, the input script is just
Code:
<signature>

The stack becomes
Code:
<signature> <pubkey> OP_CHECKSIG
OP_CHECKSIG is the only action here and it checks that the signature and pubkey matches. Because the pubkey is already pushed to the stack by the output script, there is no need to include it in the input.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 09, 2016, 07:04:35 PM
 #18

In block 200'000 I notice two strange transactions.
Usually input script is signature + 33 or 65 key. These have signature alone
Those spend pay to pubkey outputs. Since the previous output already has the public key in it, and pushes it, there is no need to push the public key as part of the input script.script
1. How to fast find address in this case?
2. Keys in 33 byte from instead of 65 can this same way https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses create Base58 address?
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 09, 2016, 08:12:44 PM
 #19

1. How to fast find address in this case?
The same speed that it takes to find any address.

2. Keys in 33 byte from instead of 65 can this same way https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses create Base58 address?
Yes.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 11, 2016, 03:54:42 PM
 #20

1. How to fast find address in this case?
The same speed that it takes to find any address.
What is algorithm in this case? Usually are pushed two values: first 72-73 bytes, second 65 bytes - key, and we can change 65 key to address, but in this case it is impossible
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 11, 2016, 07:06:30 PM
 #21

1. How to fast find address in this case?
The same speed that it takes to find any address.
What is algorithm in this case? Usually are pushed two values: first 72-73 bytes, second 65 bytes - key, and we can change 65 key to address, but in this case it is impossible
What are you asking?

It is not impossible to change the 65 byte key to an address. It is done the same exact way that a 33 byte key is done. Read this: https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses for details and an example. Note how the example uses a 65 byte key, but the same thing can be done with a 33 byte compressed key.

Frodek (OP)
Member
**
Offline Offline

Activity: 138
Merit: 25


View Profile
May 12, 2016, 03:53:39 AM
 #22

But in this case we don't have 65 byte key (nor 33 byte key) but only push 72-73 byte value.
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6641


Just writing some code


View Profile WWW
May 12, 2016, 04:18:53 AM
 #23

But in this case we don't have 65 byte key (nor 33 byte key) but only push 72-73 byte value.
Yes we do. You are not understanding how the scripting system works. The 73 bye value counter tells the software that the next 73 bytes of the transaction is for the output script. It is not part of the script itself. That script then pushes 65 bytes to the stack. Then OP_CHECKSIG. OP_CHECKSIG interprets the previous item on the stack as the public key and the item before that as the signature. There is nothing that marks then as being the signature or public key.

fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 275


View Profile
May 12, 2016, 12:00:51 PM
 #24

OP is confusing two different serialization artifacts.

Outputs look like this:
[fixed 64bit integer][output script]

When writing a parser, your software needs to know how long the output script section is, so the length comes before it.
That way the system knows when it has finished, or if there was a problem. Assuming it's a valid transaction, the network
knows the 64bit integer is actually the number of satoshis, and second part is the output script.

The contents of output script are expressed as Bitcoin Script. This involves different length serialization, one involving PUSHDATA opcodes.

As OP saw, inside the output script, there's a public key with 0x41 (=65) as a length. If we start to use larger pieces of data, this would look like:
 PUSHDATA1 0xff [256 byte long input]
 PUSHDATA2 0xffff [65535 byte long input]

You don't have to explicitly declare the pushdata opcodes for short length, but for multi-byte length encoding, you use PUSHDATA1/2/4.


Bitwasp Developer.
Pages: 1 2 [All]
  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!