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