subsidy.go raw
1 package blockchain
2
3 import (
4 "github.com/p9c/p9/pkg/btcaddr"
5 "github.com/p9c/p9/pkg/chaincfg"
6 "github.com/p9c/p9/pkg/chainhash"
7 "github.com/p9c/p9/pkg/hardfork"
8 "github.com/p9c/p9/pkg/txscript"
9 "github.com/p9c/p9/pkg/util"
10 "github.com/p9c/p9/pkg/wire"
11 )
12
13 // CreateHardForkSubsidyTx creates the transaction that must be on the hard fork activation block in place of a standard
14 // coinbase transaction.
15 //
16 // The main difference is the value set on this coinbase and that it pays out to multiple addresses, several being to
17 // the developers and to a 3 of 4 multisig to the development team for marketing and ongoing development costs multisig
18 // tx: NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG
19 func CreateHardForkSubsidyTx(
20 params *chaincfg.Params,
21 coinbaseScript []byte,
22 nextBlockHeight int32,
23 addr btcaddr.Address,
24 version int32,
25 ) (*util.Tx, error) {
26 payees := hardfork.Payees
27 if params.Net == wire.TestNet3 {
28 payees = hardfork.TestnetPayees
29 }
30 tx := wire.NewMsgTx(wire.TxVersion)
31 tx.AddTxIn(
32 &wire.TxIn{
33 // Coinbase transactions have no inputs, so previous outpoint is zero hash and max index.
34 PreviousOutPoint: *wire.NewOutPoint(
35 &chainhash.Hash{},
36 wire.MaxPrevOutIndex,
37 ),
38 SignatureScript: coinbaseScript,
39 Sequence: wire.MaxTxInSequenceNum,
40 },
41 )
42 for i := range payees {
43 script, _ := txscript.PayToAddrScript(payees[i].Address)
44 tx.AddTxOut(
45 &wire.TxOut{
46 Value: int64(payees[i].Amount),
47 PkScript: script,
48 },
49 )
50 }
51 // Add Core multisig payment
52 builder := txscript.NewScriptBuilder()
53 keylist := hardfork.CorePubkeyBytes
54 if params.Net == wire.TestNet3 {
55 keylist = hardfork.TestnetCorePubkeyBytes
56 }
57 builder.AddOp(txscript.OP_3).
58 AddData(keylist[0]).
59 AddData(keylist[1]).
60 AddData(keylist[2]).
61 AddData(keylist[3]).
62 AddOp(txscript.OP_4).
63 AddOp(txscript.OP_CHECKMULTISIG)
64 script, _ := builder.Script()
65 amt := hardfork.CoreAmount
66 if params.Net == wire.TestNet3 {
67 amt = hardfork.TestnetCoreAmount
68 }
69 tx.AddTxOut(
70 &wire.TxOut{
71 Value: int64(amt),
72 PkScript: script,
73 },
74 )
75 // add miner's reward based on last non-hf reward
76 script, _ = txscript.PayToAddrScript(addr)
77 tx.AddTxOut(
78 &wire.TxOut{
79 Value: CalcBlockSubsidy(nextBlockHeight+1, params, version),
80 PkScript: script,
81 },
82 )
83 return util.NewTx(tx), nil
84 }
85