Bitcoin Forum
May 02, 2024, 09:46:09 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: help transforming signed tx to unsigned for OP_CHECKSIG  (Read 1532 times)
luv2drnkbr (OP)
Hero Member
*****
Offline Offline

Activity: 793
Merit: 1016



View Profile
November 26, 2014, 10:50:49 PM
 #1

I'm attempting to use this picture to transform a tx in order to manually verify the signature.

The tx I'm working on is 60b20eca2285b7ed8b64a1f98277c16fcc205b9e21413d6a72545880d2a3f341, which is the full signed tx of:

Code:
010000000217cbf067a9ad71b2f69ea66a1c94d04cee26f856b5b4bdccaeccb59761419668010000008a4730440220735364aea32db724e7f0179f48e4ad5a63a3b04f733e82ca5215097a91aa7123022015846041c9564ff96fb269cb5e9b2f24dac003299e5d16d34fb9c699d55825c7014104617f9e26b7f6f776e30cb4aa24ebef9e183caf6da25684862a32446589be20a53c2b37a7283430033bdfd2f31a96edaea88bf9ebf07498476cb34d16b47887edffffffff877a5dd62eab9f1fd28739a9ae7c68fcb0f075b2c2ede13cb3acff15d362e271010000008c493046022100d0af9e17b678ad7823ad331a04d5b50f2dc173715949718ef974314f9ddbf0fa02210098de23b9c6daad57e7c8a8748718c56ec8d20cd2686aa652c4fb85091a39c690014104617f9e26b7f6f776e30cb4aa24ebef9e183caf6da25684862a32446589be20a53c2b37a7283430033bdfd2f31a96edaea88bf9ebf07498476cb34d16b47887edffffffff01709cc901000000001976a914ea0fcd06c9c62e590a8975627d0165b514568a5a88ac00000000

After some research, I've been able to break down the entire tx:

Code:
01000000  -  byte_reverse(Version: 1, in hex, 4 bytes long)
02  -  Total number of inputs (starts at 1, not 0, so for this tx there are 2 total inputs not three)
17cbf067a9ad71b2f69ea66a1c94d04cee26f856b5b4bdccaeccb59761419668  -  byte_reverse(input_txid)
01000000  -  byte_reverse of vout num for prev_tx (starting at 0, so this is the second output from that tx)
8a  -  total byte length (in hex, 0x8a = 138) of following signature + pubkey, (plus prefix bytes to indicate length)
47  -  total byte length (0x47 = 71) of following signature
30  -  DER encoded signature
44  -  total byte length of following signature info
02  -  first value is an integer, represented in hex (DER format calls that 0x02 apparently)
20  -  byte length of first value (0x20 = 32 in decimal)
735364aea32db724e7f0179f48e4ad5a63a3b04f733e82ca5215097a91aa7123  -  r value (pub X coord of random nonce)
02  -  next number is also an int
20  -  next data is 32 bytes long
15846041c9564ff96fb269cb5e9b2f24dac003299e5d16d34fb9c699d55825c7  -  s value (signature for nonce,data,privkey tuple)
01  -  bitcoin signature type SIGHASH_ALL
       (tells miners how to verify signature.  some sig types sign only certain inputs or outputs, like in coinjoin tx's.  the standard SIGHASH_ALL signs the entire tx so no modifications can be made)
41  -  byte length of following public key (0x41=65)
04617f9e26b7f6f776e30cb4aa24ebef9e183caf6da25684862a32446589be20a53c2b37a7283430033bdfd2f31a96edaea88bf9ebf07498476cb34d16b47887ed  -  pubkey which is the key for the input address and which corresponds to the privkey used to make sig
ffffffff  -  sequence number, assigned just now in this tx, to this last input, for use with nlocktime in this tx
877a5dd62eab9f1fd28739a9ae7c68fcb0f075b2c2ede13cb3acff15d362e271  -  second input byte_reverse(tx_id)
01000000  -  second input byte_reversed vout number.  (again, starting at 0, so this is the second output)
8c  -  length of full signature and pubkey
49  -  length of following signature info
30  -  DER encoded signature
46  -  length of following signature info
02  -  first number is der int
21  -  length of first number data plus 00 prefix
00  -  I'm unclear about what this is or why it's here or if it's necessary
d0af9e17b678ad7823ad331a04d5b50f2dc173715949718ef974314f9ddbf0fa  -  r value
02  -  next number is int
21  -  length of next number and 00 prefix
00  -  again, no clue
98de23b9c6daad57e7c8a8748718c56ec8d20cd2686aa652c4fb85091a39c690  -  s value
01  -  SIGHASH_ALL
41  -  length of following pubkey
04617f9e26b7f6f776e30cb4aa24ebef9e183caf6da25684862a32446589be20a53c2b37a7283430033bdfd2f31a96edaea88bf9ebf07498476cb34d16b47887ed  -  pubkey for prevtx vout, which should be the same one used for the signature
ffffffff  -  sequence number assigned to input
01  -  total number of outputs, in hex, starting at 1 not 0.
709cc90100000000  -  byte_reverse of (number of satoshis in output represented in hex), zfilled to 8 bytes long
19  -  number of bytes for output script
76  -  OP_DUP, duplicated previous stack data (which will be the hash160 when this script is used to spend the money)
a9  -  OP_HASH160, the ripemd160(sha250(pubkey)) for the output key
14  -  length of the hash160 data
ea0fcd06c9c62e590a8975627d0165b514568a5a  -  hash160 of address's public key
88  -  OP_EQUALVERIFY, does OP_EQUAL which puts TRUE on the stack if sig is valid
       then does OP_VERIFY which stops the transaciton and marks it invalid if the top stack item is not TRUE
ac  -  OP_CHECKSIG, makes sure the data that has a valid sig is actually this tx's data.
00000000  -  nlocktime

And using the pic I linked to above, as well as this page and this page, I've attempted to create what the picture link calls "verifyThisStr", replacing the scriptsig with the previous tx scriptpubkey:

Code:
010000000217cbf067a9ad71b2f69ea66a1c94d04cee26f856b5b4bdccaeccb59761419668010000001976a9140a2217742759c9951371083564d94b8b0317528488acffffffff877a5dd62eab9f1fd28739a9ae7c68fcb0f075b2c2ede13cb3acff15d362e271010000001976a9140a2217742759c9951371083564d94b8b0317528488acffffffff01709cc901000000001976a914ea0fcd06c9c62e590a8975627d0165b514568a5a88ac0000000001000000

However, the double hash for that is 6379ec988e87a690521a2bafe96fd035fc28ad451f3d1b65bf80d25bdb322057, which does not pass signature verification.

I was hoping somebody could point out the error in my unsigned tx "verifyThisStr", so that I can manually verify the tx.

Thanks for the help everybody!!!

1714643169
Hero Member
*
Offline Offline

Posts: 1714643169

View Profile Personal Message (Offline)

Ignore
1714643169
Reply with quote  #2

1714643169
Report to moderator
1714643169
Hero Member
*
Offline Offline

Posts: 1714643169

View Profile Personal Message (Offline)

Ignore
1714643169
Reply with quote  #2

1714643169
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
hhanh00
Sr. Member
****
Offline Offline

Activity: 467
Merit: 266


View Profile
November 27, 2014, 02:27:39 AM
 #2

I just looked at your hex dump so I may be wrong but it seems that you have used both pub scripts.
When you have more than one input, you are supposed to use the previous pubscript as the redeemscript before signing (like you did), but only for the input that you are signing. The other redeemscripts must be set to empty, i.e. 00

luv2drnkbr (OP)
Hero Member
*****
Offline Offline

Activity: 793
Merit: 1016



View Profile
November 27, 2014, 06:56:26 AM
 #3

Excellent, that worked perfectly.  Thank you very much for the help!

Edit:  I posted an updated version of the complete breakdown of the tx on pastebin if anybody wants it

luv2drnkbr (OP)
Hero Member
*****
Offline Offline

Activity: 793
Merit: 1016



View Profile
November 27, 2014, 08:43:11 AM
 #4

Can I call on your expertise one more time?  I'm trying to verify a multisig input now.  Tx number 0700ef4799c28537e7ae494575a2fa41bb2354ce621245dee796cfd7cdb3ddef.  Here's the full signed tx:

Code:
0100000001d3988ed76ff725847e4fdfb2d51b58881a94d7b5319ac1a9951bf9532e98a85d00000000fdfe000048304502210080f029908a2d92186d6f174acc8a27e763c17bb4ad4a4d0f9e0e9040687a0aa6022024ad5d27a1a166a657c5df283e00cccfd17cfd8e0d841eb9698f56fcd5ae08e201483045022100a91a362a0471d40fa31b1dc0d2decde9a6f8bc6d952025523430c60de39855c8022023340bbd96c30391bd70cff12926c7f540d5dbb52adcc0c604b2df43bb686b7b014c6952210252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4210395ad4c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de21021f3affcf31dee6b2ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f386153aeffffffff01b8bb0608000000001976a9148442e8244ee26488bdef062b77a727053372a65488ac00000000

and here's my attempt at re-creating the verifyThisStr that each multisig key needs to sign:

Code:
0100000001d3988ed76ff725847e4fdfb2d51b58881a94d7b5319ac1a9951bf9532e98a85d0000000017a914a2d92e95e73732e01aea6a4d7c4e406813ea32be87ffffffff01b8bb0608000000001976a9148442e8244ee26488bdef062b77a727053372a65488ac0000000001000000

Could you possibly point out my error there?

Additionally, in the original tx, the var_int for the script size is 0xfdfe0000, which means the size is 0xfe, but by my count, the size looks like 0xfd.  Can you possibly point out to me why the var_int is one byte larger than I think it should be?

Thank you again for your help, it's really really appreciated.  There's not much good documentation about this part of bitcoin, and what little there is is very difficult for me to understand, so this is all very slow-going.

hhanh00
Sr. Member
****
Offline Offline

Activity: 467
Merit: 266


View Profile
November 27, 2014, 01:29:01 PM
 #5

It's a pay to script hash. They work differently than other transactions.

Here's a play by play example: https://gist.github.com/gavinandresen/3966071 and a link to the BIP https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki

Basically, the protocol has a special case for scripts of the form OP_HASH160 xxxx OP_EQUAL. Note that there is no CHECKSIG here because it's you who provides the pubscript and it has to hash to the given hash. It's hard to explain in a short post but the links should give you enough information. If not, feel free to ask.

Quote
Additionally, in the original tx, the var_int for the script size is 0xfdfe0000, which means the size is 0xfe, but by my count, the size looks like 0xfd.  Can you possibly point out to me why the var_int is one byte larger than I think it should be?
The size is indeed 0xfe. 0xFD is followed by 2 bytes for the length FE00. You probably thought that the 2nd 00 was part of the length but it's actually the first byte of the script.

luv2drnkbr (OP)
Hero Member
*****
Offline Offline

Activity: 793
Merit: 1016



View Profile
November 27, 2014, 03:38:28 PM
 #6

If that last 0x00 byte isn't part of the var_int length, what purpose does it serve?  I can't for the life of me identify its function.  And other tx's less than size 0xfd don't seem to have that 00 after the size.

I also can't validate the tx for gavin's example tx, where he spends the multisig funds.  Is there something wrong this this verifyThisStr that I'm using to attempt to validate against each of gavin's signatures?

Code:
0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c0000000017a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087ffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac0000000001000000

I believe I've made the input  OP_HASH160 xxxx OP_EQUAL like it should be.

What I'm trying to do is get the string that I can double hash and validate the signatures with, and for the life of me I can't do it.  Thanks to you, I've been able to do it on multiple different "regular address" transactions, but not with multisig address tx signatures.

Sorry to ask so many simple questions.  I've already seen and carefully read through those links you provided a few days ago, and they don't help with my main problem of transforming the tx into the data that is being signed so I can manually verify the signatures.

Gah, this is just super frustrating.  I feel like all of this shouldn't be so difficult, but apparently I'm still novice enough where I'm making simple mistakes due to not fully understanding every last piece.  I feel like I do actually understand the scripting process and how it all works, but then I keep having seemingly simple problems like creating "verifyThisStr's", and still can't find the answers after hours of pouring through the code of various implementations that know how to validate tx's.

Sigh, I guess it'll just take some time!

hhanh00
Sr. Member
****
Offline Offline

Activity: 467
Merit: 266


View Profile
November 27, 2014, 06:12:07 PM
 #7

If that last 0x00 byte isn't part of the var_int length, what purpose does it serve?  I can't for the life of me identify its function.  And other tx's less than size 0xfd don't seem to have that 00 after the size.
The 0x00 is the opcode for OP_0, it pushes an empty array on the stack.

Your raw tx is
Code:
0100000001d3988ed76ff725847e4fdfb2d51b58881a94d7b5319ac1a9951bf9532e98a85d00000000fdfe000048304502210080f029908a2d92186d6f174acc8a27e763c17bb4ad4a4d0f9e0e9040687a0aa6022024ad5d27a1a166a657c5df283e00cccfd17cfd8e0d841eb9698f56fcd5ae08e201483045022100a91a362a0471d40fa31b1dc0d2decde9a6f8bc6d952025523430c60de39855c8022023340bbd96c30391bd70cff12926c7f540d5dbb52adcc0c604b2df43bb686b7b014c6952210252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4210395ad4c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de21021f3affcf31dee6b2ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f386153aeffffffff01b8bb0608000000001976a9148442e8244ee26488bdef062b77a727053372a65488ac00000000

On https://blockchain.info/tx/0700ef4799c28537e7ae494575a2fa41bb2354ce621245dee796cfd7cdb3ddef?show_adv=true, the input script is
Code:
OP_FALSE 304502210080f029908a2d92186d6f174acc8a27e763c17bb4ad4a4d0f9e0e9040687a0aa6022024ad5d27a1a166a657c5df283e00cccfd17cfd8e0d841eb9698f56fcd5ae08e201 3045022100a91a362a0471d40fa31b1dc0d2decde9a6f8bc6d952025523430c60de39855c8022023340bbd96c30391bd70cff12926c7f540d5dbb52adcc0c604b2df43bb686b7b01 52210252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4210395ad4c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de21021f3affcf31dee6b2ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f386153ae

This asm part shows you that 4 values were pushed.
  • <nothing>
  • 304502210080f029908a2d92186d6f174acc8a27e763c17bb4ad4a4d0f9e0e9040687a0aa602202 4ad5d27a1a166a657c5df283e00cccfd17cfd8e0d841eb9698f56fcd5ae08e201
  • 3045022100a91a362a0471d40fa31b1dc0d2decde9a6f8bc6d952025523430c60de39855c802202 3340bbd96c30391bd70cff12926c7f540d5dbb52adcc0c604b2df43bb686b7b01
  • 52210252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4210395ad4 c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de21021f3affcf31dee6b2 ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f386153ae

The "" is a dummy value because there is a legacy off-by-1 bug in OP_CHECKMULTISIG that makes it use 1 more stack element than it should.
The other two beginning with 30 are the 2 sigs in DER format.
The last one is your redeem script. If you take it and run it through SHA-256 then RIPEMD-160, you'll get a2d92e95e73732e01aea6a4d7c4e406813ea32be which matches the expected hash160.
http://www.fileformat.info/tool/hash.htm. Also if you decode it with bitcoin core console

Code:
decodescript 52210252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4210395ad4c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de21021f3affcf31dee6b2ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f386153ae

{
"asm" : "2 0252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4 0395ad4c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de 021f3affcf31dee6b2ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f3861 3 OP_CHECKMULTISIG",
"reqSigs" : 2,
"type" : "multisig",
"addresses" : [
"1D4LM66YwaoqcfHF1366pqvxvxHxvq66EZ",
"12KVX5eJQZDgZcccWnJNcuHgxgSdd3s8yT",
"1K1VgVpscuYr2j1C8D3F7BrghSpitdg2t9"
],
"p2sh" : "3GY5ZgtAeJDkiMLDR2DwSXFexVWJPnfA6g"
}
It's a 2 of 3 multi sig.

It is also the pub script that you should use as the input when preparing the signature. Because at the time CHECKSIG/MULTISIG gets evaluated, the current script is that one. The OP_HASH160 xxx OP_EQUAL was evaluated before and is no longer relevant.

luv2drnkbr (OP)
Hero Member
*****
Offline Offline

Activity: 793
Merit: 1016



View Profile
November 28, 2014, 01:11:03 PM
 #8

Excellent!  I just tested this "verifyThisStr":

Code:
0100000001d3988ed76ff725847e4fdfb2d51b58881a94d7b5319ac1a9951bf9532e98a85d000000006952210252865fa8553e7314deaa058b45349969a53df2a4825a9e8ba314236fe6bfd6c4210395ad4c60c648dea133e3731f2a0583baf1da5f6c60b56cdbad3b3bf8d28fe7de21021f3affcf31dee6b2ed6cb375d382516fd1fcb78f96dbeb6ceacc9aa47c6f386153aeffffffff01b8bb0608000000001976a9148442e8244ee26488bdef062b77a727053372a65488ac0000000001000000

and both signatures validated against it.  Beautiful!

Thank you very much for all your help.  This has really been enlightening.

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!