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