Bit-Wasp / bitcoin-php

Bitcoin implementation in PHP
The Unlicense
1.05k stars 419 forks source link

creating multisig transaction with invalid data #762

Closed ghost closed 5 years ago

ghost commented 5 years ago

For some demonstration purpose I want to create a multisig transaction using "fake" inputs (meaning they are not valid ones).

Using:

this example

is working fine, but there are two "problems" I would like to ask:

  1. When I'm decoding the generated "unsigned" fake transaction:

010000000141414141414141414141414141414141414141414141414141414141414141410000000000ffffffff019596a209000000001976a914e911698e978f3be278905860ec7827e2abef6ef788ac00000000

using coinb.in it doesn't display this as a multisig transaction. Any idea why this occurs / how to make sure it's displayed as a multisig transaction but keep the fake transaction data?

When I use for example this transaction (which is generated by fake transaction data too), it is displayed as multisig transaction:

0100000001a024ced83d73ae6b3a040d380eeldc6fb9699305c675b97dea26e8ce454a52890000000047522102047fb81b818e7062f67becf3061Cfd79eab5f0efed9f4643a3589a6765bedbff21027cb1fa9a3ec3eaa6d17b6a0b50c4263e6971f1c5cb3eee40b2ab559d6d819d4d52aeffffffff0110270000000000001976a9148c634dff20a82adca308e57910601a1a9ce0f91888ac00000000

  1. Is there some way to get a private key from the ones in the example above I can use to sign the transaction using coinb.in? I wasn't able to find a method inside the PrivateKeyFactory class to "convert" the private key to something "more usable" for humans.

All the best;

afk11 commented 5 years ago

1 When I'm decoding the generated "unsigned" fake transaction ... using coinb.in it doesn't display this as a multisig transaction.

  {
            "txid": "4141414141414141414141414141414141414141414141414141414141414141",
            "vout": 0,
            "scriptSig": {
                "asm": "",
                "hex": ""
            },
            "sequence": 4294967295
        }

For some strange reason, the larger transaction fails to decode using bitcoin-tx -- possibly there's a character missing somewhere. However, I see the second version includes the redeemScript, which is probably enough for coinbin to classify the output as a P2SH 2-of-3 multisig.

47522102047fb81b818e7062f67becf3061Cfd79eab5f0efed9f4643a3589a6765bedbff21027cb1fa9a3ec3eaa6d17b6a0b50c4263e6971f1c5cb3eee40b2ab559d6d819d4d52ae

  1. Is there some way to get a private key from the ones in the example above I can use to sign the transaction using coinb.in? I wasn't able to find a method inside the PrivateKeyFactory class to "convert" the private key to something "more usable" for humans.

You can call toWif on $pk1 and $pk2. Check the documentation for that function if you're dealing with multiple networks throughout your code.

ghost commented 5 years ago

Thanks for the reply.

Is there someway to include the redeemScript into the transaction I built using bit-wasp lib too?

afk11 commented 5 years ago

Yea - pretty sure this function call also takes a method for what the scriptSig should be. You need to do something like ScriptFactory::create()->data($rsBuffer)->getScript() which produces a scriptSig with a single data push containing the redeemScript.

https://github.com/Bit-Wasp/bitcoin-php/blob/master/examples/offlinetx.p2sh.hex.php#L41

ghost commented 5 years ago

I don't get it, could you show me this inside the code above? Unsure what to call exactly, the linked codeline is already the example I used in my script to generate the TX.

afk11 commented 5 years ago

https://github.com/Bit-Wasp/bitcoin-php/blob/master/src/Transaction/Factory/TxBuilder.php#L224

The method has optional arguments at the end, you can pass $script in there.

I'm looking at the second transaction again though, and from what I can tell, it isn't preparing it with ScriptFactory::create()->data($rsBuffer)->getScript(), but instead, the second tx could be prepared with new Script($rsBuffer) instead.

Unless the input script part isn't incorrect somehow (it doesn't decode), it's a strange way to embed the redeem script.. coinbin must have some quirk that just makes it work, but it mightn't be the most portable.