Title: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 16, 2015, 05:25:34 AM Let's take http://test.webbtc.com/tx/76cf175637ee40281b9893e691113a9b5c835d8eb44875954a68b9d582b14a9e (http://test.webbtc.com/tx/76cf175637ee40281b9893e691113a9b5c835d8eb44875954a68b9d582b14a9e) as an example (Testnet, TxID: 76cf175637ee40281b9893e691113a9b5c835d8eb44875954a68b9d582b14a9e (http://test.webbtc.com/tx/76cf175637ee40281b9893e691113a9b5c835d8eb44875954a68b9d582b14a9e.json))
(I found this through the Unknown P2SH Scripts page of webbtc.com) Code: 2 How would I use Pycoin to play around with non-standard scripts like this? Alternatively, pybitcointools. Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 17, 2015, 06:17:43 PM How would I use Pycoin to play around with non-standard scripts like this? Alternatively, pybitcointools. Writing a Script "compiler" in python should be very straight forward. PyBitcoinTools will parse out the scripts with deserialize, then you take the Script 'asm' and write a decompiler.If you then put the 'asm' data back in the dict and serialize with pybitcointools you should be good to go. I'll give it a shot next week. Title: Re: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 18, 2015, 06:41:04 AM How would I use Pycoin to play around with non-standard scripts like this? Alternatively, pybitcointools. Writing a Script "compiler" in python should be very straight forward. PyBitcoinTools will parse out the scripts with deserialize, then you take the Script 'asm' and write a decompiler.If you then put the 'asm' data back in the dict and serialize with pybitcointools you should be good to go. Thanks for the reply! I'm really familiar with pybitcointools, so I can certainly see how your suggestion works. However, the issue is when using serialize_script; namely, if you've got objects (like a pubkey), the serialize_script method doesn't add push codes for the size of the object. Ie: Code: my_script = serialize_script([OP_foo, OP_bar, "20byte_pubkey_hash", OP_spam]) myscript will return 11 22 01234567890123456789 33 instead of 11 22 14 01234567890123456789 33 Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 18, 2015, 06:53:46 AM I'm really familiar with pybitcointools, so I can certainly see how your suggestion works. However, the issue is when using serialize_script; namely, if you've got objects (like a pubkey), the serialize_script method doesn't add push codes for the size of the object. LOL...Ie: Code: my_script = serialize_script([OP_foo, OP_bar, "20byte_pubkey_hash", OP_spam]) myscript will return 11 22 01234567890123456789 33 instead of 11 22 14 01234567890123456789 33 I'm terribly unfamiliar with PyBitcoinTools, as my 'Wow there is a PyBitcoinTools module" post from today will likely attest. I never realized there was a serialize_script method. I was simply thinking of the serialize(tx_dict). I was thinking you would right your own (or overwrite) the serialize_script method. I mean there are less than 100 op codes right? Title: Re: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 18, 2015, 08:49:12 AM I never realized there was a serialize_script method. I was simply thinking of the serialize(tx_dict). I was thinking you would right your own (or overwrite) the serialize_script method. I mean there are less than 100 op codes right?[/size] Yeah, that's certainly do-able. I'll fork the pybitcointools library and see how I go with it. I've been looking at Peter Todd's python-bitcoinlib (https://github.com/petertodd/python-bitcoinlib/) and Richard Kiss' Pycoin (https://github.com/richardkiss/pycoin), mainly because the classes are much more powerful for playing around with scripting, SIGHASH, etc. That being said, the OOP for python-bitcoinlib tries to emulate the Core software naming conventions, and it's really complicated. If anyone else can provide a single example of a non-standard script Tx using Pycoin/python-bitcoinlib, I'd really appreciate it. d4n13: Thanks for the input, I'll look at trying this with pybitcointools Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 19, 2015, 06:28:34 AM Yep... there is a bug in there somewhere...
Try the following Code: from bitcoin import * Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 20, 2015, 07:13:30 AM I was simply thinking of the serialize(tx_dict). I was thinking you would right your own (or overwrite) the serialize_script method. I mean there are less than 100 op codes right? It worked.... https://i.imgur.com/hW6pjGW.png Transaction 5e4cf125218fcab2746303485ce3a2a74dc12271f678e851fc95fd97cd0153e4 (http://test.webbtc.com/tx/5e4cf125218fcab2746303485ce3a2a74dc12271f678e851fc95fd97cd0153e4) puts "Hello World" on the blockchain Transaction 602c4d614351ee615ee1dc280c16a4cf962ccc928a8c3a0dca6f9ccd46104976 (http://test.webbtc.com/script/602c4d614351ee615ee1dc280c16a4cf962ccc928a8c3a0dca6f9ccd46104976:0) spends "Hello World" on the blockchain. Interestingly... the script debugger says OP_SIGCHECK failed... but it didn't. Also, the funky output script does an interesting job of making the coins quasi-anonomized. Title: Re: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 20, 2015, 09:09:31 AM Yep... there is a bug in there somewhere... Try the following Code: from bitcoin import * Yeh, I often run scripts on iOS Pythonista, and there's a lot of recursion errors that come up since by default the recursion depth is 256; so setting sys.setrecursiondepth(512) often works in that environment. The pybitcointools bug is strange because the code serializes multisig scripts, but there's a bug with the CHECKMULTISIG; so instead of serializing the 'ae', it just appends 'ae' to the end of the returned string. I am looking at using this code: Code: def mk_script(*args): How would I go about tweaking this code to avoid the manual addition of push20? ie. I want to use Code: mk_script(['76', 'a9', 'dd6cce9f255a8cc17bda8ba0373df8e861cb866e', '88', 'ac']) Code: mk_script(['76', 'a9', '14', 'dd6cce9f255a8cc17bda8ba0373df8e861cb866e', '88', 'ac']) I'd prefer to avoid using the push bytes Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 20, 2015, 09:39:45 AM How would I go about tweaking this code to avoid the manual addition of push20? Yeah, the bit about push20 is clean... no bug. The fact that you have a list item of 40 hex digits is proof that deserialize consumed a push20. If it consumed a push10 you would have a list item of 20 hex digits instead..ie. I want to use Code: mk_script(['76', 'a9', 'dd6cce9f255a8cc17bda8ba0373df8e861cb866e', '88', 'ac']) Code: mk_script(['76', 'a9', '14', 'dd6cce9f255a8cc17bda8ba0373df8e861cb866e', '88', 'ac']) I'd prefer to avoid using the push bytes get it? Title: Re: Using Pycoin to spend non-standard scripts Post by: edmundedgar on July 20, 2015, 12:41:57 PM I don't know if this is related but something seems to have changed in the way pybitcointool serializes scripts since I was working with this around:
https://github.com/vbuterin/pybitcointools/commit/87aaf6dc3f38d853dd8cb324a4eaf72ae309d322 ...which I think is still the version you get if you do pip install pybitcointool (This is before the name changed to "bitcoin".) I haven't had a chance to get to the bottom of this and it may be that the old version is broken and the new one is right, but you might like to try comparing what you get with the old version. Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 20, 2015, 11:26:09 PM Yep... there is a bug in there somewhere... Try the following Code: from bitcoin import * Submitted issue #104 (https://github.com/vbuterin/pybitcointools/issues/104) Title: Re: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 21, 2015, 03:06:08 AM Yep... there is a bug in there somewhere... Try the following Code: from bitcoin import * Submitted issue #104 (https://github.com/vbuterin/pybitcointools/issues/104) I fixed it (https://github.com/vbuterin/pybitcointools/pull/103) Title: Re: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 21, 2015, 03:15:40 AM Maybe we can work on this Tx: http://test.webbtc.com/tx/2e7f518ce5ab61c1c959d25e396bc9d3d684d22ea86dc477b1a90329c6ca354f (http://test.webbtc.com/tx/2e7f518ce5ab61c1c959d25e396bc9d3d684d22ea86dc477b1a90329c6ca354f)
I've set up the script like this: Code: OP_IF So its a master key, which is sha256("master"*42) How would I use pybitcointools to spend this script? Nb script: Code: myscript = "63210330ed33784ee1891122bc608b89da2da45194efaca68564051e5a7be9bee7f63fad670380bf07b1756841042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9ac" Title: Re: Using Pycoin to spend non-standard scripts Post by: d4n13 on July 21, 2015, 04:07:50 AM Maybe we can work on this Tx: http://test.webbtc.com/tx/2e7f518ce5ab61c1c959d25e396bc9d3d684d22ea86dc477b1a90329c6ca354f (http://test.webbtc.com/tx/2e7f518ce5ab61c1c959d25e396bc9d3d684d22ea86dc477b1a90329c6ca354f) I've set up the script like this: Code: OP_IF So its a master key, which is sha256("master"*42) How would I use pybitcointools to spend this script? Nb script: Code: myscript = "63210330ed33784ee1891122bc608b89da2da45194efaca68564051e5a7be9bee7f63fad670380bf07b1756841042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9ac" I was working on a cleaner implementation... but got pulled away tonight... Basically you have to override Code: sign(tx,i,priv,hashcode) Code: signing_tx = signature_form(tx, i, '<utxo_scriptPubKey>', hashcode) Then you need to sign the transaction with pubkey 042d...d17c, and copy the sig into "sig1", then sign the transaction with pubkey 0330...f63f, and copy the sig into "sig2". Finally your non-standard scriptSig is: Code: <sig1> Let me clean it up and I'll write a pybitcointools implementation to spend the coin. Title: Re: Using Pycoin to spend non-standard scripts Post by: HeadsOrTails on July 21, 2015, 04:15:28 AM Basically you have to override Code: sign(tx,i,priv,hashcode) Code: signing_tx = signature_form(tx, i, '<utxo_scriptPubKey>', hashcode) Then you need to sign the transaction with pubkey 042d...d17c, and copy the sig into "sig1", then sign the transaction with pubkey 0330...f63f, and copy the sig into "sig2". Finally your non-standard scriptSig is: Code: <sig1> Let me clean it up and I'll write a pybitcointools implementation to spend the coin. Ah ha! OK, that makes perfect sense. I'll try it out. There's a fork of pybitcointools which is updated more often here (https://github.com/simcity4242/pybitcointools). One of the issues I've encountered with pybitcointools is the DER encoding; the fork checks for DER encoding, whereas the original pybitcointools isn't even BER in some instances (eg if the r or s value has the leading bit set and is less than 2**255, the encoding doesn't prepend nullbytes) |