# spillman ```go= package tx import ( "bytes" "encoding/hex" "fmt" "github.com/bergusman/bitcoin-go/chain" "github.com/bergusman/bitcoin-go/crypto" "github.com/bergusman/bitcoin-go/primitives" "github.com/bergusman/bitcoin-go/script" "github.com/bergusman/bitcoin-go/sign" "github.com/bergusman/bitcoin-go/wallet" ) /* Alice: Alpha Bob: Beta */ func Spillman() { //spillman_prepare() spillman_funding() //spillman_pay() } func spillman_prepare() { alphaPrivateKey, _ := wallet.PrivateKeyFromHex(ALPHA_PRIVATE_KEY) alphaPublicKey := wallet.CompressPublicKey(wallet.PublicKeyFromPrivateKey(alphaPrivateKey)) alphaAddress := wallet.PublicKeyToAddress(alphaPublicKey, chain.RegTestBase58Prefixes) fmt.Println("ALPHA ADDRESS:", alphaAddress) fmt.Println("sendtoaddress", alphaAddress, "10.001") fmt.Println() } func spillman_funding() { alphaPrivateKey, _ := wallet.PrivateKeyFromHex(ALPHA_PRIVATE_KEY) alphaPublicKey := wallet.CompressPublicKey(wallet.PublicKeyFromPrivateKey(alphaPrivateKey)) betaPrivateKey, _ := wallet.PrivateKeyFromHex(BETA_PRIVATE_KEY) betaPublicKey := wallet.CompressPublicKey(wallet.PublicKeyFromPrivateKey(betaPrivateKey)) prepareTxRaw, _ := hex.DecodeString("0200000001f500941954d16f7f8b0cef74f3dcc0a9f7a7dcf156a26c84f88b58637283022d0000000048473044022037036f997c5bd419b0e1119d4b3aa1100a1db20b514c3da08569123d8f58efe6022013d3e8754292ef58b76d1c3ec5dcf0103755b111ca63ea1ef8460a7bf4c6757001feffffff02a0509c3b000000001976a9142007a791f3c0c9eb4d6bfec931b3442339bbc2f288ac749269ee000000001976a914d35af54a6f1ee49498c265e17938e001030de34988ac65000000") prepareTx := primitives.NewTransaction(bytes.NewBuffer(prepareTxRaw)) fmt.Println("PREPARE TX:") fmt.Println(&prepareTx) redeemScript := script.CreateMultisigRedeemScript(2, []wallet.CompressedPublicKey{ alphaPublicKey, betaPublicKey, }) redeemScriptHash := crypto.Hash160(redeemScript) fmt.Println("REDEEM SCRIPT ASM:", script.ScriptToString(redeemScript)) fmt.Println("REDEEM SCRIPT HEX:", hex.EncodeToString(redeemScript)) fmt.Println("REDEEM SCRIPT HASH:", hex.EncodeToString(redeemScriptHash[:])) fmt.Println("REDEEM SCRIPT ADDRESS:", wallet.ScriptToAddress(redeemScript, chain.RegTestBase58Prefixes)) fmt.Println() var fundingTX primitives.Transaction fundingTX.Version = 2 fundingTX.LockTime = 0 fundingTX.Inputs = make([]primitives.Input, 1) fundingTX.Outputs = make([]primitives.Output, 1) fundingTX.Outputs[0].Value = 1000000000 fundingTX.Outputs[0].ScriptPubKey = script.P2SHScriptPubKey(redeemScriptHash) fundingTX.Inputs[0].Outpoint.Hash = prepareTx.TxId() fundingTX.Inputs[0].Outpoint.Index = 0 fundingTX.Inputs[0].Sequence = 0xffffffff fundingSig, _ := sign.SignTx(fundingTX, 0, prepareTx.Outputs[fundingTX.Inputs[0].Outpoint.Index].ScriptPubKey, sign.SIGHASH_ALL, alphaPrivateKey) fundingTX.Inputs[0].ScriptSig = script.P2PHKScriptSig(fundingSig, alphaPublicKey) fmt.Println("FUNDING TX") fmt.Println(&fundingTX) fmt.Println(hex.EncodeToString(fundingTX.Bytes())) fmt.Println() fTxRaw, _ := hex.DecodeString("020000000158caf34c8742ccd5fd9679bbb95bf1db768e5c4f75e1850418e78a303a5a446d000000006a47304402200941602c955229e6c96fb2092ce33a56d33c69a8591a7d874c4c12a5a9c1edf60220292180e62285305c7e5b02634f22f02d46e07b8f0f7bc31a2016f8f8970623be01210229a0cd0024360e55d2c7e82ef87045b45766938510309f493b8597d661329befffffffff0100ca9a3b0000000017a914a5253c26e379aa7f4b38b0117b0abafa2e499e388700000000") fTx := primitives.NewTransaction(bytes.NewBuffer(fTxRaw)) // Refunding var refundingTx primitives.Transaction refundingTx.Version = 2 refundingTx.LockTime = 200 refundingTx.Inputs = make([]primitives.Input, 1) refundingTx.Outputs = make([]primitives.Output, 1) refundingTx.Outputs[0].Value = 999000000 refundingTx.Outputs[0].ScriptPubKey = script.P2PHKScriptPupKey(crypto.Hash160(alphaPublicKey[:])) refundingTx.Inputs[0].Outpoint.Hash = fTx.TxId() refundingTx.Inputs[0].Outpoint.Index = 0 refundingTx.Inputs[0].Sequence = 0xfffffffe alphaSig, _ := sign.SignTx(refundingTx, 0, redeemScript, sign.SIGHASH_ALL, alphaPrivateKey) betaSig, _ := sign.SignTx(refundingTx, 0, redeemScript, sign.SIGHASH_ALL, betaPrivateKey) buf := new(bytes.Buffer) buf.WriteByte(script.OP_0) buf.WriteByte(byte(len(alphaSig))) buf.Write(alphaSig) buf.WriteByte(byte(len(betaSig))) buf.Write(betaSig) buf.WriteByte(byte(len(redeemScript))) buf.Write(redeemScript) refundingTx.Inputs[0].ScriptSig = buf.Bytes() fmt.Println("REFUNDING TX") fmt.Println(&refundingTx) fmt.Println(hex.EncodeToString(refundingTx.Bytes())) // non-final (code 64) (code -26) } func spillman_pay() { alphaPrivateKey, _ := wallet.PrivateKeyFromHex(ALPHA_PRIVATE_KEY) alphaPublicKey := wallet.CompressPublicKey(wallet.PublicKeyFromPrivateKey(alphaPrivateKey)) betaPrivateKey, _ := wallet.PrivateKeyFromHex(BETA_PRIVATE_KEY) betaPublicKey := wallet.CompressPublicKey(wallet.PublicKeyFromPrivateKey(betaPrivateKey)) redeemScript := script.CreateMultisigRedeemScript(2, []wallet.CompressedPublicKey{ alphaPublicKey, betaPublicKey, }) redeemScriptHash := crypto.Hash160(redeemScript) fmt.Println("REDEEM SCRIPT ASM:", script.ScriptToString(redeemScript)) fmt.Println("REDEEM SCRIPT HEX:", hex.EncodeToString(redeemScript)) fmt.Println("REDEEM SCRIPT HASH:", hex.EncodeToString(redeemScriptHash[:])) fmt.Println("REDEEM SCRIPT ADDRESS:", wallet.ScriptToAddress(redeemScript, chain.RegTestBase58Prefixes)) fmt.Println() // Funding fTxRaw, _ := hex.DecodeString("020000000158caf34c8742ccd5fd9679bbb95bf1db768e5c4f75e1850418e78a303a5a446d000000006a47304402200941602c955229e6c96fb2092ce33a56d33c69a8591a7d874c4c12a5a9c1edf60220292180e62285305c7e5b02634f22f02d46e07b8f0f7bc31a2016f8f8970623be01210229a0cd0024360e55d2c7e82ef87045b45766938510309f493b8597d661329befffffffff0100ca9a3b0000000017a914a5253c26e379aa7f4b38b0117b0abafa2e499e388700000000") fTx := primitives.NewTransaction(bytes.NewBuffer(fTxRaw)) // Pay var payTx primitives.Transaction payTx.Version = 2 payTx.LockTime = 0 payTx.Inputs = make([]primitives.Input, 1) payTx.Outputs = make([]primitives.Output, 2) pay := int64(100000000) change := fTx.Outputs[0].Value - pay - 1000000 payTx.Outputs[0].Value = pay payTx.Outputs[0].ScriptPubKey = script.P2PHKScriptPupKey(crypto.Hash160(betaPublicKey[:])) payTx.Outputs[1].Value = change payTx.Outputs[1].ScriptPubKey = script.P2PHKScriptPupKey(crypto.Hash160(alphaPublicKey[:])) payTx.Inputs[0].Outpoint.Hash = fTx.TxId() payTx.Inputs[0].Outpoint.Index = 0 payTx.Inputs[0].Sequence = 0xffffffff alphaSig, _ := sign.SignTx(payTx, 0, redeemScript, sign.SIGHASH_ALL, alphaPrivateKey) betaSig, _ := sign.SignTx(payTx, 0, redeemScript, sign.SIGHASH_ALL, betaPrivateKey) buf := new(bytes.Buffer) buf.WriteByte(script.OP_0) buf.WriteByte(byte(len(alphaSig))) buf.Write(alphaSig) buf.WriteByte(byte(len(betaSig))) buf.Write(betaSig) buf.WriteByte(byte(len(redeemScript))) buf.Write(redeemScript) payTx.Inputs[0].ScriptSig = buf.Bytes() fmt.Println("PAY TX") fmt.Println(&payTx) fmt.Println(hex.EncodeToString(payTx.Bytes())) } ```