Last active
September 20, 2018 19:49
-
-
Save davecgh/6ec528c23d1c1e9eb737 to your computer and use it in GitHub Desktop.
P2SH Multisig Manual
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/hex" | |
"fmt" | |
"github.com/btcsuite/btcutil" | |
. "github.com/btcsuite/btcd/txscript" | |
) | |
func main() { | |
// Using pubkeys and signatures from redeeming tx d646f82bd5fbdb94a36872ce460f97662b80c3050ad3209bef9d1e398ea277ab:0 | |
// which references tx e2124d25a7f6fe0d5dd5dd78ba7d98f60f8c47be9c91699e649e04118d531f52:0 | |
pubKey1Hex := "04cb9c3c222c5f7a7d3b9bd152f363a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e29105f24de20ff463c1c91fcf3bf662cdde4783d4799f787cb7c08869b" | |
pubKey2Hex := "04ccc588420deeebea22a7e900cc8b68620d2212c374604e3487ca08f1ff3ae12bdc639514d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e71e610b036aa2" | |
pubKey3Hex := "04ab47ad1939edcb3db65f7fedea62bbf781c5410d3f22a7a3a56ffefb2238af8627363bdf2ed97c1f89784a1aecdb43384f11d2acc64443c7fc299cef0400421a" | |
pubKey1, _ := hex.DecodeString(pubKey1Hex) | |
pubKey2, _ := hex.DecodeString(pubKey2Hex) | |
pubKey3, _ := hex.DecodeString(pubKey3Hex) | |
sig1Hex := "3045022100dedc2621f9ab11cd008efa4a6734f64336cc5217368cc5a7bb3c74d025812267022059a300963f634adad7c4b01bcb3834ed697df17b0b81c708f92142b81f7ae12a01" | |
sig2Hex := "3045022063a7dec8db21f38d73a922b9dd40a5107d59edb912339828ffce2c28a006f9b6022100a57a49beee175c913a5504c7d411d67736435b5cf21993ebc74e350576a98b1b01" | |
sig1, _ := hex.DecodeString(sig1Hex) | |
sig2, _ := hex.DecodeString(sig2Hex) | |
// 1) Generate the serialized pay script in the mutlsig-form of | |
// {[numsigs] [...pubkeys...] [numpubkeys] OP_CHECKMULTISIG} | |
payScript, _ := NewScriptBuilder().AddInt64(2).AddData(pubKey1).AddData(pubKey2).AddData(pubKey3).AddInt64(3).AddOp(OP_CHECKMULTISIG).Script() | |
payScriptDisasm, _ := DisasmString(payScript) | |
fmt.Printf("payScript hex: %x\npayScript asm: %s\n", payScript, payScriptDisasm) | |
// 2) Calculate the hash160 to obtain the script hash | |
payScriptHash := btcutil.Hash160(payScript) | |
fmt.Printf("payScript hash: %x\n", payScriptHash) | |
// 3) Create the spending transaction's output script | |
outScript, _ := NewScriptBuilder().AddOp(OP_HASH160).AddData(payScriptHash).AddOp(OP_EQUAL).Script() | |
outScriptDisasm, _ := DisasmString(outScript) | |
fmt.Printf("outScript hex: %x\noutScript asm: %s\n", outScript, outScriptDisasm) | |
// 4) Create the redeeming transaction's input script | |
inScript, _ := NewScriptBuilder().AddOp(OP_0).AddData(sig1).AddData(sig2).AddData(payScript).Script() | |
inScriptDisasm, _ := DisasmString(inScript) | |
fmt.Printf("inScript hex: %x\ninScript asm: %s\n", inScript, inScriptDisasm) | |
} | |
Output: | |
payScript hex: 524104cb9c3c222c5f7a7d3b9bd152f363a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e29105f24de20ff463c1c91fcf3bf662cdde4783d4799f787cb7c08869b4104ccc588420deeebea22a7e900cc8b68620d2212c374604e3487ca08f1ff3ae12bdc639514d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e71e610b036aa24104ab47ad1939edcb3db65f7fedea62bbf781c5410d3f22a7a3a56ffefb2238af8627363bdf2ed97c1f89784a1aecdb43384f11d2acc64443c7fc299cef0400421a53ae | |
payScript asm: 2 04cb9c3c222c5f7a7d3b9bd152f363a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e29105f24de20ff463c1c91fcf3bf662cdde4783d4799f787cb7c08869b 04ccc588420deeebea22a7e900cc8b68620d2212c374604e3487ca08f1ff3ae12bdc639514d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e71e610b036aa2 04ab47ad1939edcb3db65f7fedea62bbf781c5410d3f22a7a3a56ffefb2238af8627363bdf2ed97c1f89784a1aecdb43384f11d2acc64443c7fc299cef0400421a 3 OP_CHECKMULTISIG | |
payScript hash: 1b800cec1fe92222f36a502c139bed47c5959715 | |
outScript hex: a9141b800cec1fe92222f36a502c139bed47c595971587 | |
outScript asm: OP_HASH160 1b800cec1fe92222f36a502c139bed47c5959715 OP_EQUAL | |
inScript hex: 00483045022100dedc2621f9ab11cd008efa4a6734f64336cc5217368cc5a7bb3c74d025812267022059a300963f634adad7c4b01bcb3834ed697df17b0b81c708f92142b81f7ae12a01483045022063a7dec8db21f38d73a922b9dd40a5107d59edb912339828ffce2c28a006f9b6022100a57a49beee175c913a5504c7d411d67736435b5cf21993ebc74e350576a98b1b014cc9524104cb9c3c222c5f7a7d3b9bd152f363a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e29105f24de20ff463c1c91fcf3bf662cdde4783d4799f787cb7c08869b4104ccc588420deeebea22a7e900cc8b68620d2212c374604e3487ca08f1ff3ae12bdc639514d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e71e610b036aa24104ab47ad1939edcb3db65f7fedea62bbf781c5410d3f22a7a3a56ffefb2238af8627363bdf2ed97c1f89784a1aecdb43384f11d2acc64443c7fc299cef0400421a53ae | |
inScript asm: 0 3045022100dedc2621f9ab11cd008efa4a6734f64336cc5217368cc5a7bb3c74d025812267022059a300963f634adad7c4b01bcb3834ed697df17b0b81c708f92142b81f7ae12a01 3045022063a7dec8db21f38d73a922b9dd40a5107d59edb912339828ffce2c28a006f9b6022100a57a49beee175c913a5504c7d411d67736435b5cf21993ebc74e350576a98b1b01 524104cb9c3c222c5f7a7d3b9bd152f363a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e29105f24de20ff463c1c91fcf3bf662cdde4783d4799f787cb7c08869b4104ccc588420deeebea22a7e900cc8b68620d2212c374604e3487ca08f1ff3ae12bdc639514d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e71e610b036aa24104ab47ad1939edcb3db65f7fedea62bbf781c5410d3f22a7a3a56ffefb2238af8627363bdf2ed97c1f89784a1aecdb43384f11d2acc64443c7fc299cef0400421a53ae |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment