github.com/bchainhub/blockbook@v0.3.2/bchain/types.go (about)

     1  package bchain
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"math/big"
    10  )
    11  
    12  // ChainType is type of the blockchain
    13  type ChainType int
    14  
    15  const (
    16  	// ChainBitcoinType is blockchain derived from bitcoin
    17  	ChainBitcoinType = ChainType(iota)
    18  	// ChainEthereumType is blockchain derived from ethereum
    19  	ChainEthereumType
    20  )
    21  
    22  // errors with specific meaning returned by blockchain rpc
    23  var (
    24  	// ErrBlockNotFound is returned when block is not found
    25  	// either unknown hash or too high height
    26  	// can be returned from GetBlockHash, GetBlockHeader, GetBlock
    27  	ErrBlockNotFound = errors.New("Block not found")
    28  	// ErrAddressMissing is returned if address is not specified
    29  	// for example To address in ethereum can be missing in case of contract transaction
    30  	ErrAddressMissing = errors.New("Address missing")
    31  	// ErrTxidMissing is returned if txid is not specified
    32  	// for example coinbase transactions in Bitcoin
    33  	ErrTxidMissing = errors.New("Txid missing")
    34  	// ErrTxNotFound is returned if transaction was not found
    35  	ErrTxNotFound = errors.New("Tx not found")
    36  )
    37  
    38  // Outpoint is txid together with output (or input) index
    39  type Outpoint struct {
    40  	Txid string
    41  	Vout int32
    42  }
    43  
    44  // ScriptSig contains data about input script
    45  type ScriptSig struct {
    46  	// Asm string `json:"asm"`
    47  	Hex string `json:"hex"`
    48  }
    49  
    50  // Vin contains data about tx output
    51  type Vin struct {
    52  	Coinbase  string    `json:"coinbase"`
    53  	Txid      string    `json:"txid"`
    54  	Vout      uint32    `json:"vout"`
    55  	ScriptSig ScriptSig `json:"scriptSig"`
    56  	Sequence  uint32    `json:"sequence"`
    57  	Addresses []string  `json:"addresses"`
    58  }
    59  
    60  // ScriptPubKey contains data about output script
    61  type ScriptPubKey struct {
    62  	// Asm       string   `json:"asm"`
    63  	Hex string `json:"hex,omitempty"`
    64  	// Type      string   `json:"type"`
    65  	Addresses []string `json:"addresses"`
    66  }
    67  
    68  // Vout contains data about tx output
    69  type Vout struct {
    70  	ValueSat     big.Int
    71  	JsonValue    json.Number  `json:"value"`
    72  	N            uint32       `json:"n"`
    73  	ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
    74  }
    75  
    76  // Tx is blockchain transaction
    77  // unnecessary fields are commented out to avoid overhead
    78  type Tx struct {
    79  	Hex         string `json:"hex"`
    80  	Txid        string `json:"txid"`
    81  	Version     int32  `json:"version"`
    82  	LockTime    uint32 `json:"locktime"`
    83  	Vin         []Vin  `json:"vin"`
    84  	Vout        []Vout `json:"vout"`
    85  	BlockHeight uint32 `json:"blockHeight,omitempty"`
    86  	// BlockHash     string `json:"blockhash,omitempty"`
    87  	Confirmations    uint32      `json:"confirmations,omitempty"`
    88  	Time             int64       `json:"time,omitempty"`
    89  	Blocktime        int64       `json:"blocktime,omitempty"`
    90  	CoinSpecificData interface{} `json:"-"`
    91  }
    92  
    93  // Block is block header and list of transactions
    94  type Block struct {
    95  	BlockHeader
    96  	Txs []Tx `json:"tx"`
    97  }
    98  
    99  // BlockHeader contains limited data (as needed for indexing) from backend block header
   100  type BlockHeader struct {
   101  	Hash          string `json:"hash"`
   102  	Prev          string `json:"previousblockhash"`
   103  	Next          string `json:"nextblockhash"`
   104  	Height        uint32 `json:"height"`
   105  	Confirmations int    `json:"confirmations"`
   106  	Size          int    `json:"size"`
   107  	Time          int64  `json:"time,omitempty"`
   108  }
   109  
   110  // BlockInfo contains extended block header data and a list of block txids
   111  type BlockInfo struct {
   112  	BlockHeader
   113  	Version    json.Number `json:"version"`
   114  	MerkleRoot string      `json:"merkleroot"`
   115  	Nonce      json.Number `json:"nonce"`
   116  	Bits       string      `json:"bits"`
   117  	Difficulty json.Number `json:"difficulty"`
   118  	Txids      []string    `json:"tx,omitempty"`
   119  }
   120  
   121  // MempoolEntry is used to get data about mempool entry
   122  type MempoolEntry struct {
   123  	Size            uint32 `json:"size"`
   124  	FeeSat          big.Int
   125  	Fee             json.Number `json:"fee"`
   126  	ModifiedFeeSat  big.Int
   127  	ModifiedFee     json.Number `json:"modifiedfee"`
   128  	Time            uint64      `json:"time"`
   129  	Height          uint32      `json:"height"`
   130  	DescendantCount uint32      `json:"descendantcount"`
   131  	DescendantSize  uint32      `json:"descendantsize"`
   132  	DescendantFees  uint32      `json:"descendantfees"`
   133  	AncestorCount   uint32      `json:"ancestorcount"`
   134  	AncestorSize    uint32      `json:"ancestorsize"`
   135  	AncestorFees    uint32      `json:"ancestorfees"`
   136  	Depends         []string    `json:"depends"`
   137  }
   138  
   139  // ChainInfo is used to get information about blockchain
   140  type ChainInfo struct {
   141  	Chain           string  `json:"chain"`
   142  	Blocks          int     `json:"blocks"`
   143  	Headers         int     `json:"headers"`
   144  	Bestblockhash   string  `json:"bestblockhash"`
   145  	Difficulty      string  `json:"difficulty"`
   146  	SizeOnDisk      int64   `json:"size_on_disk"`
   147  	Version         string  `json:"version"`
   148  	Subversion      string  `json:"subversion"`
   149  	ProtocolVersion string  `json:"protocolversion"`
   150  	Timeoffset      float64 `json:"timeoffset"`
   151  	Warnings        string  `json:"warnings"`
   152  }
   153  
   154  // RPCError defines rpc error returned by backend
   155  type RPCError struct {
   156  	Code    int    `json:"code"`
   157  	Message string `json:"message"`
   158  }
   159  
   160  func (e *RPCError) Error() string {
   161  	return fmt.Sprintf("%d: %s", e.Code, e.Message)
   162  }
   163  
   164  // AddressDescriptor is an opaque type obtained by parser.GetAddrDesc* methods
   165  type AddressDescriptor []byte
   166  
   167  func (ad AddressDescriptor) String() string {
   168  	return "ad:" + hex.EncodeToString(ad)
   169  }
   170  
   171  // AddressDescriptorFromString converts string created by AddressDescriptor.String to AddressDescriptor
   172  func AddressDescriptorFromString(s string) (AddressDescriptor, error) {
   173  	if len(s) > 3 && s[0:3] == "ad:" {
   174  		return hex.DecodeString(s[3:])
   175  	}
   176  	return nil, errors.New("Not AddressDescriptor")
   177  }
   178  
   179  // EthereumType specific
   180  
   181  // Erc20Contract contains info about ERC20 contract
   182  type Erc20Contract struct {
   183  	Contract string `json:"contract"`
   184  	Name     string `json:"name"`
   185  	Symbol   string `json:"symbol"`
   186  	Decimals int    `json:"decimals"`
   187  }
   188  
   189  // Erc20Transfer contains a single ERC20 token transfer
   190  type Erc20Transfer struct {
   191  	Contract string
   192  	From     string
   193  	To       string
   194  	Tokens   big.Int
   195  }
   196  
   197  // MempoolTxidEntry contains mempool txid with first seen time
   198  type MempoolTxidEntry struct {
   199  	Txid string
   200  	Time uint32
   201  }
   202  
   203  // MempoolTxidEntries is array of MempoolTxidEntry
   204  type MempoolTxidEntries []MempoolTxidEntry
   205  
   206  // OnNewBlockFunc is used to send notification about a new block
   207  type OnNewBlockFunc func(hash string, height uint32)
   208  
   209  // OnNewTxAddrFunc is used to send notification about a new transaction/address
   210  type OnNewTxAddrFunc func(tx *Tx, desc AddressDescriptor)
   211  
   212  // AddrDescForOutpointFunc defines function that returns address descriptorfor given outpoint or nil if outpoint not found
   213  type AddrDescForOutpointFunc func(outpoint Outpoint) AddressDescriptor
   214  
   215  // BlockChain defines common interface to block chain daemon
   216  type BlockChain interface {
   217  	// life-cycle methods
   218  	// initialize the block chain connector
   219  	Initialize() error
   220  	// create mempool but do not initialize it
   221  	CreateMempool(BlockChain) (Mempool, error)
   222  	// initialize mempool, create ZeroMQ (or other) subscription
   223  	InitializeMempool(AddrDescForOutpointFunc, OnNewTxAddrFunc) error
   224  	// shutdown mempool, ZeroMQ and block chain connections
   225  	Shutdown(ctx context.Context) error
   226  	// chain info
   227  	IsTestnet() bool
   228  	GetNetworkName() string
   229  	GetSubversion() string
   230  	GetCoinName() string
   231  	GetChainInfo() (*ChainInfo, error)
   232  	// requests
   233  	GetBestBlockHash() (string, error)
   234  	GetBestBlockHeight() (uint32, error)
   235  	GetBlockHash(height uint32) (string, error)
   236  	GetBlockHeader(hash string) (*BlockHeader, error)
   237  	GetBlock(hash string, height uint32) (*Block, error)
   238  	GetBlockInfo(hash string) (*BlockInfo, error)
   239  	GetMempoolTransactions() ([]string, error)
   240  	GetTransaction(txid string) (*Tx, error)
   241  	GetTransactionForMempool(txid string) (*Tx, error)
   242  	GetTransactionSpecific(tx *Tx) (json.RawMessage, error)
   243  	EstimateSmartFee(blocks int, conservative bool) (big.Int, error)
   244  	EstimateFee(blocks int) (big.Int, error)
   245  	SendRawTransaction(tx string) (string, error)
   246  	GetMempoolEntry(txid string) (*MempoolEntry, error)
   247  	// parser
   248  	GetChainParser() BlockChainParser
   249  	// EthereumType specific
   250  	EthereumTypeGetBalance(addrDesc AddressDescriptor) (*big.Int, error)
   251  	EthereumTypeGetNonce(addrDesc AddressDescriptor) (uint64, error)
   252  	EthereumTypeEstimateGas(params map[string]interface{}) (uint64, error)
   253  	EthereumTypeGetErc20ContractInfo(contractDesc AddressDescriptor) (*Erc20Contract, error)
   254  	EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error)
   255  }
   256  
   257  // BlockChainParser defines common interface to parsing and conversions of block chain data
   258  type BlockChainParser interface {
   259  	// type of the blockchain
   260  	GetChainType() ChainType
   261  	// KeepBlockAddresses returns number of blocks which are to be kept in blockTxs column
   262  	// to be used for rollbacks
   263  	KeepBlockAddresses() int
   264  	// AmountDecimals returns number of decimal places in coin amounts
   265  	AmountDecimals() int
   266  	// MinimumCoinbaseConfirmations returns minimum number of confirmations a coinbase transaction must have before it can be spent
   267  	MinimumCoinbaseConfirmations() int
   268  	// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
   269  	AmountToDecimalString(a *big.Int) string
   270  	// AmountToBigInt converts amount in json.Number (string) to big.Int
   271  	// it uses string operations to avoid problems with rounding
   272  	AmountToBigInt(n json.Number) (big.Int, error)
   273  	// address descriptor conversions
   274  	GetAddrDescFromVout(output *Vout) (AddressDescriptor, error)
   275  	GetAddrDescFromAddress(address string) (AddressDescriptor, error)
   276  	GetAddressesFromAddrDesc(addrDesc AddressDescriptor) ([]string, bool, error)
   277  	GetScriptFromAddrDesc(addrDesc AddressDescriptor) ([]byte, error)
   278  	IsAddrDescIndexable(addrDesc AddressDescriptor) bool
   279  	// transactions
   280  	PackedTxidLen() int
   281  	PackTxid(txid string) ([]byte, error)
   282  	UnpackTxid(buf []byte) (string, error)
   283  	ParseTx(b []byte) (*Tx, error)
   284  	ParseTxFromJson(json.RawMessage) (*Tx, error)
   285  	PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error)
   286  	UnpackTx(buf []byte) (*Tx, uint32, error)
   287  	GetAddrDescForUnknownInput(tx *Tx, input int) AddressDescriptor
   288  	// blocks
   289  	PackBlockHash(hash string) ([]byte, error)
   290  	UnpackBlockHash(buf []byte) (string, error)
   291  	ParseBlock(b []byte) (*Block, error)
   292  	// xpub
   293  	DerivationBasePath(xpub string) (string, error)
   294  	DeriveAddressDescriptors(xpub string, change uint32, indexes []uint32) ([]AddressDescriptor, error)
   295  	DeriveAddressDescriptorsFromTo(xpub string, change uint32, fromIndex uint32, toIndex uint32) ([]AddressDescriptor, error)
   296  	// EthereumType specific
   297  	EthereumTypeGetErc20FromTx(tx *Tx) ([]Erc20Transfer, error)
   298  }
   299  
   300  // Mempool defines common interface to mempool
   301  type Mempool interface {
   302  	Resync() (int, error)
   303  	GetTransactions(address string) ([]Outpoint, error)
   304  	GetAddrDescTransactions(addrDesc AddressDescriptor) ([]Outpoint, error)
   305  	GetAllEntries() MempoolTxidEntries
   306  	GetTransactionTime(txid string) uint32
   307  }