You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.2 KiB
82 lines
3.2 KiB
6 years ago
|
package hmyapi
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"github.com/ethereum/go-ethereum/common"
|
||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||
|
"github.com/ethereum/go-ethereum/rpc"
|
||
|
"github.com/harmony-one/harmony/core"
|
||
|
)
|
||
|
|
||
|
// PublicBlockChainAPI provides an API to access the Harmony blockchain.
|
||
|
// It offers only methods that operate on public data that is freely available to anyone.
|
||
|
type PublicBlockChainAPI struct {
|
||
|
b *core.HmyAPIBackend
|
||
|
}
|
||
|
|
||
|
// NewPublicBlockChainAPI creates a new Harmony blockchain API.
|
||
|
func NewPublicBlockChainAPI(b *core.HmyAPIBackend) *PublicBlockChainAPI {
|
||
|
return &PublicBlockChainAPI{b}
|
||
|
}
|
||
|
|
||
|
// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
|
||
|
// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
|
||
|
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
||
|
block, err := s.b.BlockByNumber(ctx, blockNr)
|
||
|
if block != nil {
|
||
|
response, err := RPCMarshalBlock(block, false, false)
|
||
|
if err == nil && blockNr == rpc.PendingBlockNumber {
|
||
|
// Pending blocks need to nil out a few fields
|
||
|
for _, field := range []string{"hash", "nonce", "miner"} {
|
||
|
response[field] = nil
|
||
|
}
|
||
|
}
|
||
|
return response, err
|
||
|
}
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
|
||
|
// detail, otherwise only the transaction hash is returned.
|
||
|
func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) {
|
||
|
block, err := s.b.GetBlock(ctx, blockHash)
|
||
|
if block != nil {
|
||
|
return RPCMarshalBlock(block, false, false)
|
||
|
}
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// GetCode returns the code stored at the given address in the state for the given block number.
|
||
|
func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
||
|
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||
|
if state == nil || err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
code := state.GetCode(address)
|
||
|
return code, state.Error()
|
||
|
}
|
||
|
|
||
|
// GetStorageAt returns the storage from the state at the given address, key and
|
||
|
// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block
|
||
|
// numbers are also allowed.
|
||
|
func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
||
|
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||
|
if state == nil || err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
res := state.GetState(address, common.HexToHash(key))
|
||
|
return res[:], state.Error()
|
||
|
}
|
||
|
|
||
|
// GetBalance returns the amount of wei for the given address in the state of the
|
||
|
// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta
|
||
|
// block numbers are also allowed.
|
||
|
func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Big, error) {
|
||
|
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||
|
if state == nil || err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return (*hexutil.Big)(state.GetBalance(address)), state.Error()
|
||
|
}
|