Bitcoin Forum
May 23, 2019, 10:36:40 AM *
News: Latest Bitcoin Core release: 0.18.0 [Torrent] (New!)
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: spend P2SH output  (Read 111 times)
darosior
Full Member
***
Offline Offline

Activity: 170
Merit: 177



View Profile WWW
January 06, 2019, 05:20:56 PM
Last edit: January 06, 2019, 06:20:25 PM by darosior
Merited by DarkStar_ (4), ETFbitcoin (1), bones261 (1), LoyceV (1)
 #1

Hi,

I am playing around with raw transactions and have succesfully created a P2SH output with the locking script set to
Code:
OP_2 OP_EQUAL
following the bip16 standard. Thus my script_pubkey looks like :
Code:
OP_HASH160 <ripemd160(sha256(OP_2 OP_EQUAL))> OP_EQUAL
OP_HASH160 5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
a9145c9081ddd7c74d71e183b104abcc3f74be54c9c787

When trying to spend it I naively created a transaction which spends it with the script_sig :
Code:
OP_2 OP_2 OP_EQUAL
As the example  (for a classic P2PK the P2SH way) in the bip is :
Code:
scriptSig: [signature] {[pubkey] OP_CHECKSIG}
which I interpreted as :
Code:
scriptSig: [unlocking scrip] {locking script}

But I ended up with an error (64: scriptsig-not-pushonly) because there is OP_EQUAL, but the script will be evaluated as :
Code:
OP_2 OP_2 OP_EQUAL OP_HASH160 5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
So here is my question : how to make the hash match without putting the script in the script_sig ? Moreover HASH160 will only hash the top item on the stack..

Github profile ~ Crypto Lyon (french community)  ~ GPG key fingerprint : E13F C145 CD3F 430 ~ LN public key : 03678b4f041fbfbeebcafc076469df75decf81da20a53bd490172e83ce532df1fa
Tutorials/posts : Address from private keyBitcoin smart contracts ~ Setup a Bitcoin node ~ Raw P2PKH transaction in Python ~ P2SH ~ 51% attack
PLAY OVER 3000 GAMES
LIGHTNING FAST WITHDRAWALS
PLAY NOW
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
Coding Enthusiast
Hero Member
*****
Offline Offline

Activity: 625
Merit: 851


Novice C♯ Coder


View Profile WWW
January 06, 2019, 06:27:54 PM
Last edit: January 06, 2019, 06:44:51 PM by Coding Enthusiast
Merited by DarkStar_ (4), bones261 (3), ETFbitcoin (1), LoyceV (1), darosior (1)
 #2

I am not very good at scripts but I'll try.

ripemd160(sha256(OP_2 OP_EQUAL)
You can not hash an operation, you has the values. OP_2 is also an operation but it happens to be adding a predefined value (2) to the stack. Your OP_Equal on the other hand is just an operation, so your hash looks like something like this:
Hash(5 +)
So your interpreter is surprised to see a + operation (or in your case an equality check op) where it is expecting a value.

16: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)"
Here is the step by step of the script:
1. Stack is empty.
OP_2 OP_2 OP_EQUAL OP_HASH160 5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
2. Push value 2 on the stack: Stack is { 2 }
OP_2 OP_EQUAL OP_HASH160 5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
3. Push value 2 on the stack: Stack is { 2, 2 }
OP_EQUAL OP_HASH160 5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
4.
4.1. Pop 2 items from stack: Stack is { }, you have two values in memory
4.2. Check their equality...
4.3. Push (Boolean) result on the stack: Stack is { 1 }
OP_HASH160 5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
5.
5.1. Pop 1 item from stack, stack is empty and there is value 1 in memory
5.2. Perform hash160 hash on 1
5.3. Push the result of hash back on stack { .... }
5c9081ddd7c74d71e183b104abcc3f74be54c9c7 OP_EQUAL
6. (Assuming there is a push op behind this, the value will be pushed onto the stack)
OP_EQUAL
7. The same as 4 but the result is false because you were supposed to have Hash160(2) but you have Hash160(1)

Edit: I've made a tiny mistake which I fixed. The script fails not because of final step or the equality check before that, it fails because in your script sig you have operations other than push operations.

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

darosior
Full Member
***
Offline Offline

Activity: 170
Merit: 177



View Profile WWW
January 06, 2019, 06:42:11 PM
 #3

Thank you for response, CodingEnthusiast

I have found the solution : I should push the OPs from which are composed the locking script. So just adding 0x02 before my 2 OPs made my tx be valid :
Code:
script_sig : OP_2 0x02 OP_2 OP_EQUAL
I think that being pushed, the OP_EQUAL is interpreted as data and not executed.

Github profile ~ Crypto Lyon (french community)  ~ GPG key fingerprint : E13F C145 CD3F 430 ~ LN public key : 03678b4f041fbfbeebcafc076469df75decf81da20a53bd490172e83ce532df1fa
Tutorials/posts : Address from private keyBitcoin smart contracts ~ Setup a Bitcoin node ~ Raw P2PKH transaction in Python ~ P2SH ~ 51% attack
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 1778
Merit: 2379


bc1qshxkrpe4arppq89fpzm6c0tpdvx5cfkve2c8kl


View Profile WWW
January 06, 2019, 09:38:38 PM
Merited by darosior (2), ETFbitcoin (1), bones261 (1)
 #4

Thank you for response, CodingEnthusiast

I have found the solution : I should push the OPs from which are composed the locking script. So just adding 0x02 before my 2 OPs made my tx be valid :
Code:
script_sig : OP_2 0x02 OP_2 OP_EQUAL
I think that being pushed, the OP_EQUAL is interpreted as data and not executed.
Right, you need to push the redeemScript.

How P2SH works is that the redeemScript is pushed to the stack. This stack is then duplicated. On one stack, the top stack element (the redeemScript) is popped and its hash160 is pushed to the stack. That is then compared to the hash in the scriptPubKey. If that succeeds, the second stack is used which has the top stack element as the redeemScript. On this stack, the redeemScript is popped off and executed as a script. So for all of this to work, the redeemScript needs to be pushed as a singular stack element in the scriptSig.

Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!