func NewBlockFromBlockAndBytes(msgBlock *wire.MsgBlock, serializedBlock []byte) *Block {
	return &Block{
		msgBlock:        msgBlock,
		serializedBlock: serializedBlock,
	}
}
NewBlockFromBlockAndBytes returns a new instance of a bitcoin block given
an underlying wire.MsgBlock and the serialized bytes for it.  See Block.
package provautil
import (
	"bytes"
	"fmt"
	"io"
	"github.com/bitgo/prova/chaincfg/chainhash"
	"github.com/bitgo/prova/wire"
)
type OutOfRangeError string
const BlockHeightUnknown = int32(-1)
func (e OutOfRangeError) Error() string {
	return string(e)
}
type Block struct {
	msgBlock        *wire.MsgBlock   
	serializedBlock []byte           
	blockHash       *chainhash.Hash  
	transactions    []*Tx            
	txnsGenerated   bool             
}
func (b *Block) blockHeight() uint32 {
	return b.msgBlock.Header.Height
}
func (b *Block) MsgBlock() *wire.MsgBlock {
	return b.msgBlock
}
func (b *Block) Bytes() ([]byte, error) {
	if len(b.serializedBlock) != 0 {
		return b.serializedBlock, nil
	}
	var w bytes.Buffer
	err := b.msgBlock.Serialize(&w)
	if err != nil {
		return nil, err
	}
	serializedBlock := w.Bytes()
	b.serializedBlock = serializedBlock
	return serializedBlock, nil
}
func (b *Block) Hash() *chainhash.Hash {
	if b.blockHash != nil {
		return b.blockHash
	}
	hash := b.msgBlock.BlockHash()
	b.blockHash = &hash
	return &hash
}
func (b *Block) Tx(txNum int) (*Tx, error) {
	numTx := uint64(len(b.msgBlock.Transactions))
	if txNum < 0 || uint64(txNum) > numTx {
		str := fmt.Sprintf("transaction index %d is out of range - max %d",
			txNum, numTx-1)
		return nil, OutOfRangeError(str)
	}
	if len(b.transactions) == 0 {
		b.transactions = make([]*Tx, numTx)
	}
	if b.transactions[txNum] != nil {
		return b.transactions[txNum], nil
	}
	newTx := NewTx(b.msgBlock.Transactions[txNum])
	newTx.SetIndex(txNum)
	b.transactions[txNum] = newTx
	return newTx, nil
}
func (b *Block) Transactions() []*Tx {
	if b.txnsGenerated {
		return b.transactions
	}
	if len(b.transactions) == 0 {
		b.transactions = make([]*Tx, len(b.msgBlock.Transactions))
	}
	for i, tx := range b.transactions {
		if tx == nil {
			newTx := NewTx(b.msgBlock.Transactions[i])
			newTx.SetIndex(i)
			b.transactions[i] = newTx
		}
	}
	b.txnsGenerated = true
	return b.transactions
}
func (b *Block) TxHashWithSig(txNum int) (*chainhash.Hash, error) {
	tx, err := b.Tx(txNum)
	if err != nil {
		return nil, err
	}
	return tx.HashWithSig(), nil
}
func (b *Block) TxHash(txNum int) (*chainhash.Hash, error) {
	tx, err := b.Tx(txNum)
	if err != nil {
		return nil, err
	}
	return tx.Hash(), nil
}
func (b *Block) TxLoc() ([]wire.TxLoc, error) {
	rawMsg, err := b.Bytes()
	if err != nil {
		return nil, err
	}
	rbuf := bytes.NewBuffer(rawMsg)
	var mblock wire.MsgBlock
	txLocs, err := mblock.DeserializeTxLoc(rbuf)
	if err != nil {
		return nil, err
	}
	return txLocs, err
}
func (b *Block) Height() uint32 {
	return b.blockHeight()
}
func (b *Block) SetHeight(height uint32) {
	b.msgBlock.Header.Height = height
}
func NewBlock(msgBlock *wire.MsgBlock) *Block {
	return &Block{
		msgBlock: msgBlock,
	}
}
func NewBlockFromBytes(serializedBlock []byte) (*Block, error) {
	br := bytes.NewReader(serializedBlock)
	b, err := NewBlockFromReader(br)
	if err != nil {
		return nil, err
	}
	b.serializedBlock = serializedBlock
	return b, nil
}
func NewBlockFromReader(r io.Reader) (*Block, error) {
	var msgBlock wire.MsgBlock
	err := msgBlock.Deserialize(r)
	if err != nil {
		return nil, err
	}
	b := Block{
		msgBlock: &msgBlock,
	}
	return &b, nil
}