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 }