---
# System prepended metadata

title: spillman

---

# 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()))
}
```