4 "github.com/bytom/blockchain/query"
5 "github.com/bytom/consensus/difficulty"
6 chainjson "github.com/bytom/encoding/json"
7 "github.com/bytom/protocol/bc"
8 "github.com/bytom/protocol/bc/types"
11 // return best block hash
12 func (a *API) getBestBlockHash() Response {
13 blockHash := map[string]string{"block_hash": a.chain.BestBlockHash().String()}
14 return NewSuccessResponse(blockHash)
17 // return current block count
18 func (a *API) getBlockCount() Response {
19 blockHeight := map[string]uint64{"block_count": a.chain.BestBlockHeight()}
20 return NewSuccessResponse(blockHeight)
23 // BlockTx is the tx struct for getBlock func
25 ID bc.Hash `json:"id"`
26 Version uint64 `json:"version"`
27 Size uint64 `json:"size"`
28 TimeRange uint64 `json:"time_range"`
29 Inputs []*query.AnnotatedInput `json:"inputs"`
30 Outputs []*query.AnnotatedOutput `json:"outputs"`
31 StatusFail bool `json:"status_fail"`
34 // BlockReq is used to handle getBlock req
35 type BlockReq struct {
36 BlockHeight uint64 `json:"block_height"`
37 BlockHash chainjson.HexBytes `json:"block_hash"`
40 // GetBlockResp is the resp for getBlock api
41 type GetBlockResp struct {
42 Hash *bc.Hash `json:"hash"`
43 Size uint64 `json:"size"`
44 Version uint64 `json:"version"`
45 Height uint64 `json:"height"`
46 PreviousBlockHash *bc.Hash `json:"previous_block_hash"`
47 Timestamp uint64 `json:"timestamp"`
48 Nonce uint64 `json:"nonce"`
49 Bits uint64 `json:"bits"`
50 Difficulty string `json:"difficulty"`
51 TransactionsMerkleRoot *bc.Hash `json:"transaction_merkle_root"`
52 TransactionStatusHash *bc.Hash `json:"transaction_status_hash"`
53 Transactions []*BlockTx `json:"transactions"`
56 // return block by hash
57 func (a *API) getBlock(ins BlockReq) Response {
59 block := &types.Block{}
60 if len(ins.BlockHash) == 32 {
62 copy(b32[:], ins.BlockHash)
63 hash := bc.NewHash(b32)
64 block, err = a.chain.GetBlockByHash(&hash)
66 block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
69 return NewErrorResponse(err)
72 blockHash := block.Hash()
73 txStatus, err := a.chain.GetTransactionStatus(&blockHash)
74 rawBlock, err := block.MarshalText()
76 return NewErrorResponse(err)
79 resp := &GetBlockResp{
81 Size: uint64(len(rawBlock)),
82 Version: block.Version,
84 PreviousBlockHash: &block.PreviousBlockHash,
85 Timestamp: block.Timestamp,
88 Difficulty: difficulty.CompactToBig(block.Bits).String(),
89 TransactionsMerkleRoot: &block.TransactionsMerkleRoot,
90 TransactionStatusHash: &block.TransactionStatusHash,
91 Transactions: []*BlockTx{},
94 for i, orig := range block.Transactions {
97 Version: orig.Version,
98 Size: orig.SerializedSize,
99 TimeRange: orig.TimeRange,
100 Inputs: []*query.AnnotatedInput{},
101 Outputs: []*query.AnnotatedOutput{},
103 tx.StatusFail, err = txStatus.GetStatus(i)
105 NewSuccessResponse(resp)
108 for i := range orig.Inputs {
109 tx.Inputs = append(tx.Inputs, a.wallet.BuildAnnotatedInput(orig, uint32(i)))
111 for i := range orig.Outputs {
112 tx.Outputs = append(tx.Outputs, a.wallet.BuildAnnotatedOutput(orig, i))
114 resp.Transactions = append(resp.Transactions, tx)
116 return NewSuccessResponse(resp)
119 // GetBlockHeaderResp is resp struct for getBlockHeader API
120 type GetBlockHeaderResp struct {
121 BlockHeader *types.BlockHeader `json:"block_header"`
122 Reward uint64 `json:"reward"`
125 func (a *API) getBlockHeader(ins BlockReq) Response {
127 block := &types.Block{}
128 if len(ins.BlockHash) == 32 {
130 copy(b32[:], ins.BlockHash)
131 hash := bc.NewHash(b32)
132 block, err = a.chain.GetBlockByHash(&hash)
134 block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
137 return NewErrorResponse(err)
140 resp := &GetBlockHeaderResp{
141 BlockHeader: &block.BlockHeader,
142 Reward: block.Transactions[0].Outputs[0].Amount,
144 return NewSuccessResponse(resp)