6 "github.com/vapor/consensus"
7 "github.com/vapor/crypto"
8 "github.com/vapor/crypto/ed25519/chainkd"
9 "github.com/vapor/errors"
10 "github.com/vapor/protocol"
11 "github.com/vapor/protocol/bc"
12 "github.com/vapor/protocol/bc/types"
13 "github.com/vapor/protocol/validation"
14 "github.com/vapor/protocol/vm"
15 "github.com/vapor/protocol/vm/vmutil"
18 // NewBlock create block according to the current status of chain
19 func NewBlock(chain *protocol.Chain, txs []*types.Tx, controlProgram []byte) (*types.Block, error) {
22 txEntries := []*bc.Tx{nil}
23 txStatus := bc.NewTransactionStatus()
24 if err := txStatus.SetStatus(0, false); err != nil {
28 preBlockHeader := chain.BestBlockHeader()
31 BlockHeader: types.BlockHeader{
33 Height: preBlockHeader.Height + 1,
34 PreviousBlockHash: preBlockHeader.Hash(),
35 Timestamp: preBlockHeader.Timestamp + 1,
36 BlockCommitment: types.BlockCommitment{},
38 Transactions: []*types.Tx{nil},
41 bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: preBlockHeader.Height + 1}}
42 for _, tx := range txs {
44 gasStatus, err := validation.ValidateTx(tx.Tx, bcBlock)
46 if !gasStatus.GasValid {
52 txStatus.SetStatus(len(b.Transactions), gasOnlyTx)
53 b.Transactions = append(b.Transactions, tx)
54 txEntries = append(txEntries, tx.Tx)
55 gasUsed += uint64(gasStatus.GasUsed)
59 coinbaseTx, err := CreateCoinbaseTx(controlProgram, preBlockHeader.Height+1, txsFee)
64 b.Transactions[0] = coinbaseTx
65 txEntries[0] = coinbaseTx.Tx
66 b.TransactionsMerkleRoot, err = types.TxMerkleRoot(txEntries)
71 b.TransactionStatusHash, err = types.TxStatusMerkleRoot(txStatus.VerifyStatus)
72 proof, err := generateProof(*b)
80 func generateProof(block types.Block) (types.Proof, error) {
82 if consensus.ActiveNetParams.Signer == "" {
83 return types.Proof{}, errors.New("Signer is empty")
85 xPrv.UnmarshalText([]byte(consensus.ActiveNetParams.Signer))
86 sign := xPrv.Sign(block.BlockCommitment.TransactionsMerkleRoot.Bytes())
87 pubHash := crypto.Ripemd160(xPrv.XPub().PublicKey())
88 control, err := vmutil.P2WPKHProgram([]byte(pubHash))
90 return types.Proof{}, err
92 return types.Proof{Sign: sign, ControlProgram: control}, nil
95 // ReplaceCoinbase replace the coinbase tx of block with coinbaseTx
96 func ReplaceCoinbase(block *types.Block, coinbaseTx *types.Tx) (err error) {
97 block.Transactions[0] = coinbaseTx
98 txEntires := []*bc.Tx{coinbaseTx.Tx}
99 for i := 1; i < len(block.Transactions); i++ {
100 txEntires = append(txEntires, block.Transactions[i].Tx)
103 block.TransactionsMerkleRoot, err = types.TxMerkleRoot(txEntires)
107 // AppendBlocks append empty blocks to chain, mainly used to mature the coinbase tx
108 func AppendBlocks(chain *protocol.Chain, num uint64) error {
109 for i := uint64(0); i < num; i++ {
110 block, err := NewBlock(chain, nil, []byte{byte(vm.OP_TRUE)})
114 if err := SolveAndUpdate(chain, block); err != nil {
121 func setAuthoritys(chain *protocol.Chain) {
122 authoritys := make(map[string]string)
123 xpubStr := "96bc2ad4b1c2db399990c811c4367688cbb7867612bb9d04e4dc7848e425c6395264d3b177a96646bc0ce517ae7fd63504c183ab6d330dea184331a4cf5912d5"
124 var xpub chainkd.XPub
125 xpub.UnmarshalText([]byte(xpubStr))
127 pubHash := crypto.Ripemd160(xpub.PublicKey())
128 control, _ := vmutil.P2WPKHProgram([]byte(pubHash))
129 key := hex.EncodeToString(control)
130 authoritys[key] = xpub.String()
132 chain.SetAuthoritys(authoritys)
135 // SolveAndUpdate solve difficulty and update chain status
136 func SolveAndUpdate(chain *protocol.Chain, block *types.Block) error {
137 _, err := chain.ProcessBlock(block)