Pages:
Author

Topic: [solved]How decode raw transaction? (Read 3932 times)

sr. member
Activity: 412
Merit: 287
May 12, 2016, 07:00:51 AM
#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.

staff
Activity: 3458
Merit: 6793
Just writing some code
May 11, 2016, 11:18:53 PM
#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.
member
Activity: 138
Merit: 25
May 11, 2016, 10:53:39 PM
#22
But in this case we don't have 65 byte key (nor 33 byte key) but only push 72-73 byte value.
staff
Activity: 3458
Merit: 6793
Just writing some code
May 11, 2016, 02: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.
member
Activity: 138
Merit: 25
May 11, 2016, 10:54:42 AM
#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
staff
Activity: 3458
Merit: 6793
Just writing some code
May 09, 2016, 03: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.
member
Activity: 138
Merit: 25
May 09, 2016, 02: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?
staff
Activity: 3458
Merit: 6793
Just writing some code
May 08, 2016, 09:52:34 AM
#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:
OP_CHECKSIG

When spending it, the input script is just
Code:

The stack becomes
Code:
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.
hero member
Activity: 793
Merit: 1026
May 08, 2016, 08:46:34 AM
#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.
staff
Activity: 3458
Merit: 6793
Just writing some code
May 08, 2016, 12: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
member
Activity: 138
Merit: 25
May 07, 2016, 11:33:36 PM
#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
staff
Activity: 3458
Merit: 6793
Just writing some code
May 07, 2016, 03: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.
member
Activity: 138
Merit: 25
May 07, 2016, 03: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
staff
Activity: 3458
Merit: 6793
Just writing some code
May 07, 2016, 01: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"?
member
Activity: 138
Merit: 25
May 07, 2016, 01:31:17 PM
#10
This explain a bit. How locate useful data? The block data before OP_CHECKSIG?
staff
Activity: 3458
Merit: 6793
Just writing some code
May 07, 2016, 01: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.
member
Activity: 138
Merit: 25
May 07, 2016, 12: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
staff
Activity: 3458
Merit: 6793
Just writing some code
May 04, 2016, 06: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.
member
Activity: 138
Merit: 25
May 04, 2016, 02: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
staff
Activity: 3458
Merit: 6793
Just writing some code
May 03, 2016, 05: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.
Pages:
Jump to: