github.com/cryptohub-digital/blockbook@v0.3.5-0.20240403155730-99ab40b9104c/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 "github.com/cryptohub-digital/blockbook/common" 12 ) 13 14 // ChainType is type of the blockchain 15 type ChainType int 16 17 const ( 18 // ChainBitcoinType is blockchain derived from bitcoin 19 ChainBitcoinType = ChainType(iota) 20 // ChainEthereumType is blockchain derived from ethereum 21 ChainEthereumType 22 // ChainCoreCoinType is blockchain derived from coreblockchain 23 ChainCoreCoinType 24 ) 25 26 // errors with specific meaning returned by blockchain rpc 27 var ( 28 // ErrBlockNotFound is returned when block is not found 29 // either unknown hash or too high height 30 // can be returned from GetBlockHash, GetBlockHeader, GetBlock 31 ErrBlockNotFound = errors.New("Block not found") 32 // ErrAddressMissing is returned if address is not specified 33 // for example To address in ethereum can be missing in case of contract transaction 34 ErrAddressMissing = errors.New("Address missing") 35 // ErrTxidMissing is returned if txid is not specified 36 // for example coinbase transactions in Bitcoin 37 ErrTxidMissing = errors.New("Txid missing") 38 // ErrTxNotFound is returned if transaction was not found 39 ErrTxNotFound = errors.New("Tx not found") 40 ) 41 42 // Outpoint is txid together with output (or input) index 43 type Outpoint struct { 44 Txid string 45 Vout int32 46 } 47 48 // ScriptSig contains data about input script 49 type ScriptSig struct { 50 // Asm string `json:"asm"` 51 Hex string `json:"hex"` 52 } 53 54 // Vin contains data about tx input 55 type Vin struct { 56 Coinbase string `json:"coinbase"` 57 Txid string `json:"txid"` 58 Vout uint32 `json:"vout"` 59 ScriptSig ScriptSig `json:"scriptSig"` 60 Sequence uint32 `json:"sequence"` 61 Addresses []string `json:"addresses"` 62 } 63 64 // ScriptPubKey contains data about output script 65 type ScriptPubKey struct { 66 // Asm string `json:"asm"` 67 Hex string `json:"hex,omitempty"` 68 // Type string `json:"type"` 69 Addresses []string `json:"addresses"` 70 } 71 72 // Vout contains data about tx output 73 type Vout struct { 74 ValueSat big.Int 75 JsonValue common.JSONNumber `json:"value"` 76 N uint32 `json:"n"` 77 ScriptPubKey ScriptPubKey `json:"scriptPubKey"` 78 } 79 80 // Tx is blockchain transaction 81 // unnecessary fields are commented out to avoid overhead 82 type Tx struct { 83 Hex string `json:"hex"` 84 Txid string `json:"txid"` 85 Version int32 `json:"version"` 86 LockTime uint32 `json:"locktime"` 87 VSize int64 `json:"vsize,omitempty"` 88 Vin []Vin `json:"vin"` 89 Vout []Vout `json:"vout"` 90 BlockHeight uint32 `json:"blockHeight,omitempty"` 91 // BlockHash string `json:"blockhash,omitempty"` 92 Confirmations uint32 `json:"confirmations,omitempty"` 93 Time int64 `json:"time,omitempty"` 94 Blocktime int64 `json:"blocktime,omitempty"` 95 CoinSpecificData interface{} `json:"-"` 96 } 97 98 // MempoolVin contains data about tx input 99 type MempoolVin struct { 100 Vin 101 AddrDesc AddressDescriptor `json:"-"` 102 ValueSat big.Int 103 } 104 105 // MempoolTx is blockchain transaction in mempool 106 // optimized for onNewTx notification 107 type MempoolTx struct { 108 Hex string `json:"hex"` 109 Txid string `json:"txid"` 110 Version int32 `json:"version"` 111 LockTime uint32 `json:"locktime"` 112 VSize int64 `json:"vsize,omitempty"` 113 Vin []MempoolVin `json:"vin"` 114 Vout []Vout `json:"vout"` 115 Blocktime int64 `json:"blocktime,omitempty"` 116 TokenTransfers TokenTransfers `json:"-"` 117 CoinSpecificData interface{} `json:"-"` 118 } 119 120 // TokenType - type of token 121 type TokenType int 122 123 // TokenType enumeration 124 const ( 125 FungibleToken = TokenType(iota) // ERC20/BEP20/CBC20 126 NonFungibleToken // ERC721/BEP721/CBC721 127 MultiToken // ERC1155/BEP1155 128 ) 129 130 // TokenTypeName specifies type of token 131 type TokenTypeName string 132 133 // Token types 134 const ( 135 UnknownTokenType TokenTypeName = "" 136 137 // XPUBAddressTokenType is address derived from xpub 138 XPUBAddressTokenType TokenTypeName = "XPUBAddress" 139 ) 140 141 // TokenTransfers is array of TokenTransfer 142 type TokenTransfers []*TokenTransfer 143 144 func (a TokenTransfers) Len() int { return len(a) } 145 func (a TokenTransfers) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 146 func (a TokenTransfers) Less(i, j int) bool { 147 return a[i].Type < a[j].Type 148 } 149 150 // Block is block header and list of transactions 151 type Block struct { 152 BlockHeader 153 Txs []Tx `json:"tx"` 154 CoinSpecificData interface{} `json:"-"` 155 } 156 157 // BlockHeader contains limited data (as needed for indexing) from backend block header 158 type BlockHeader struct { 159 Hash string `json:"hash"` 160 Prev string `json:"previousblockhash"` 161 Next string `json:"nextblockhash"` 162 Height uint32 `json:"height"` 163 Confirmations int `json:"confirmations"` 164 Size int `json:"size"` 165 Time int64 `json:"time,omitempty"` 166 } 167 168 // BlockInfo contains extended block header data and a list of block txids 169 type BlockInfo struct { 170 BlockHeader 171 Version common.JSONNumber `json:"version"` 172 MerkleRoot string `json:"merkleroot"` 173 Nonce common.JSONNumber `json:"nonce"` 174 Bits string `json:"bits"` 175 Difficulty common.JSONNumber `json:"difficulty"` 176 Txids []string `json:"tx,omitempty"` 177 } 178 179 // MempoolEntry is used to get data about mempool entry 180 type MempoolEntry struct { 181 Size uint32 `json:"size"` 182 FeeSat big.Int 183 Fee common.JSONNumber `json:"fee"` 184 ModifiedFeeSat big.Int 185 ModifiedFee common.JSONNumber `json:"modifiedfee"` 186 Time uint64 `json:"time"` 187 Height uint32 `json:"height"` 188 DescendantCount uint32 `json:"descendantcount"` 189 DescendantSize uint32 `json:"descendantsize"` 190 DescendantFees uint32 `json:"descendantfees"` 191 AncestorCount uint32 `json:"ancestorcount"` 192 AncestorSize uint32 `json:"ancestorsize"` 193 AncestorFees uint32 `json:"ancestorfees"` 194 Depends []string `json:"depends"` 195 } 196 197 // ChainInfo is used to get information about blockchain 198 type ChainInfo struct { 199 Chain string `json:"chain"` 200 Blocks int `json:"blocks"` 201 Headers int `json:"headers"` 202 Bestblockhash string `json:"bestblockhash"` 203 Difficulty string `json:"difficulty"` 204 SizeOnDisk int64 `json:"size_on_disk"` 205 Version string `json:"version"` 206 Subversion string `json:"subversion"` 207 ProtocolVersion string `json:"protocolversion"` 208 Timeoffset float64 `json:"timeoffset"` 209 Warnings string `json:"warnings"` 210 ConsensusVersion string `json:"consensus_version,omitempty"` 211 Consensus interface{} `json:"consensus,omitempty"` 212 } 213 214 // RPCError defines rpc error returned by backend 215 type RPCError struct { 216 Code int `json:"code"` 217 Message string `json:"message"` 218 } 219 220 func (e *RPCError) Error() string { 221 return fmt.Sprintf("%d: %s", e.Code, e.Message) 222 } 223 224 // AddressDescriptor is an opaque type obtained by parser.GetAddrDesc* methods 225 type AddressDescriptor []byte 226 227 func (ad AddressDescriptor) String() string { 228 return "ad:" + hex.EncodeToString(ad) 229 } 230 231 // AddressDescriptorFromString converts string created by AddressDescriptor.String to AddressDescriptor 232 func AddressDescriptorFromString(s string) (AddressDescriptor, error) { 233 if len(s) > 3 && s[0:3] == "ad:" { 234 return hex.DecodeString(s[3:]) 235 } 236 return nil, errors.New("invalid address descriptor") 237 } 238 239 type VerifiedAddress struct { 240 Address string `json:"address"` 241 Name string `json:"name"` 242 Icon string `json:"icon"` 243 URL string `json:"url"` 244 URLTitle string `json:"urlTitle"` 245 Aliases []string `json:"aliases"` 246 } 247 248 // MempoolTxidEntry contains mempool txid with first seen time 249 type MempoolTxidEntry struct { 250 Txid string 251 Time uint32 252 } 253 254 // ScriptType - type of output script parsed from xpub (descriptor) 255 type ScriptType int 256 257 // ScriptType enumeration 258 const ( 259 P2PK = ScriptType(iota) 260 P2PKH 261 P2SHWPKH 262 P2WPKH 263 P2TR 264 ) 265 266 // XpubDescriptor contains parsed data from xpub descriptor 267 type XpubDescriptor struct { 268 XpubDescriptor string // The whole descriptor 269 Xpub string // Xpub part of the descriptor 270 Type ScriptType 271 Bip string 272 ChangeIndexes []uint32 273 ExtKey interface{} // extended key parsed from xpub, usually of type *hdkeychain.ExtendedKey 274 } 275 276 // MempoolTxidEntries is array of MempoolTxidEntry 277 type MempoolTxidEntries []MempoolTxidEntry 278 279 // MempoolTxidFilterEntries is a map of txids to mempool golomb filters 280 type MempoolTxidFilterEntries struct { 281 Entries map[string]string `json:"entries,omitempty"` 282 } 283 284 // OnNewBlockFunc is used to send notification about a new block 285 type OnNewBlockFunc func(hash string, height uint32) 286 287 // OnNewTxAddrFunc is used to send notification about a new transaction/address 288 type OnNewTxAddrFunc func(tx *Tx, desc AddressDescriptor) 289 290 // OnNewTxFunc is used to send notification about a new transaction/address 291 type OnNewTxFunc func(tx *MempoolTx) 292 293 // AddrDescForOutpointFunc returns address descriptor and value for given outpoint or nil if outpoint not found 294 type AddrDescForOutpointFunc func(outpoint Outpoint) (AddressDescriptor, *big.Int) 295 296 // BlockChain defines common interface to block chain daemon 297 type BlockChain interface { 298 // life-cycle methods 299 // initialize the block chain connector 300 Initialize() error 301 // create mempool but do not initialize it 302 CreateMempool(BlockChain) (Mempool, error) 303 // initialize mempool, create ZeroMQ (or other) subscription 304 InitializeMempool(AddrDescForOutpointFunc, OnNewTxAddrFunc, OnNewTxFunc) error 305 // shutdown mempool, ZeroMQ and block chain connections 306 Shutdown(ctx context.Context) error 307 // chain info 308 IsTestnet() bool 309 GetNetworkName() string 310 GetSubversion() string 311 GetCoinName() string 312 GetChainInfo() (*ChainInfo, error) 313 // requests 314 GetBestBlockHash() (string, error) 315 GetBestBlockHeight() (uint32, error) 316 GetBlockHash(height uint32) (string, error) 317 GetBlockHeader(hash string) (*BlockHeader, error) 318 GetBlock(hash string, height uint32) (*Block, error) 319 GetBlockInfo(hash string) (*BlockInfo, error) 320 GetBlockRaw(hash string) (string, error) 321 GetMempoolTransactions() ([]string, error) 322 GetTransaction(txid string) (*Tx, error) 323 GetTransactionForMempool(txid string) (*Tx, error) 324 GetTransactionSpecific(tx *Tx) (json.RawMessage, error) 325 EstimateSmartFee(blocks int, conservative bool) (big.Int, error) 326 EstimateFee(blocks int) (big.Int, error) 327 SendRawTransaction(tx string) (string, error) 328 GetMempoolEntry(txid string) (*MempoolEntry, error) 329 GetContractInfo(contractDesc AddressDescriptor) (*ContractInfo, error) 330 // parser 331 GetChainParser() BlockChainParser 332 // EthereumType specific 333 EthereumTypeGetBalance(addrDesc AddressDescriptor) (*big.Int, error) 334 EthereumTypeGetNonce(addrDesc AddressDescriptor) (uint64, error) 335 EthereumTypeEstimateGas(params map[string]interface{}) (uint64, error) 336 EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error) 337 GetTokenURI(contractDesc AddressDescriptor, tokenID *big.Int) (string, error) 338 // CoreCoinType specific 339 CoreCoinTypeGetBalance(addrDesc AddressDescriptor) (*big.Int, error) 340 CoreCoinTypeGetNonce(addrDesc AddressDescriptor) (uint64, error) 341 CoreCoinTypeEstimateEnergy(params map[string]interface{}) (uint64, error) 342 CoreCoinTypeGetCbc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error) 343 344 AddVerifiedSCData(contract *ContractInfo) *ContractInfo 345 AddVerifiedAddressData(address AddressDescriptor) *VerifiedAddress 346 FindVerifiedByName(query string) *AddressDescriptor 347 } 348 349 // BlockChainParser defines common interface to parsing and conversions of block chain data 350 type BlockChainParser interface { 351 // type of the blockchain 352 GetChainType() ChainType 353 // KeepBlockAddresses returns number of blocks which are to be kept in blockTxs column 354 // to be used for rollbacks 355 KeepBlockAddresses() int 356 // AmountDecimals returns number of decimal places in coin amounts 357 AmountDecimals() int 358 // UseAddressAliases returns true if address aliases are enabled 359 UseAddressAliases() bool 360 // MinimumCoinbaseConfirmations returns minimum number of confirmations a coinbase transaction must have before it can be spent 361 MinimumCoinbaseConfirmations() int 362 // SupportsVSize returns true if vsize of a transaction should be computed and returned by API 363 SupportsVSize() bool 364 // AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place 365 AmountToDecimalString(a *big.Int) string 366 // AmountToBigInt converts amount in common.JSONNumber (string) to big.Int 367 // it uses string operations to avoid problems with rounding 368 AmountToBigInt(n common.JSONNumber) (big.Int, error) 369 // address descriptor conversions 370 GetAddrDescFromVout(output *Vout) (AddressDescriptor, error) 371 GetAddrDescFromAddress(address string) (AddressDescriptor, error) 372 GetAddressesFromAddrDesc(addrDesc AddressDescriptor) ([]string, bool, error) 373 GetScriptFromAddrDesc(addrDesc AddressDescriptor) ([]byte, error) 374 IsAddrDescIndexable(addrDesc AddressDescriptor) bool 375 // transactions 376 PackedTxidLen() int 377 PackTxid(txid string) ([]byte, error) 378 UnpackTxid(buf []byte) (string, error) 379 ParseTx(b []byte) (*Tx, error) 380 ParseTxFromJson(json.RawMessage) (*Tx, error) 381 PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error) 382 UnpackTx(buf []byte) (*Tx, uint32, error) 383 GetAddrDescForUnknownInput(tx *Tx, input int) AddressDescriptor 384 // blocks 385 PackBlockHash(hash string) ([]byte, error) 386 UnpackBlockHash(buf []byte) (string, error) 387 ParseBlock(b []byte) (*Block, error) 388 // xpub 389 ParseXpub(xpub string) (*XpubDescriptor, error) 390 DerivationBasePath(descriptor *XpubDescriptor) (string, error) 391 DeriveAddressDescriptors(descriptor *XpubDescriptor, change uint32, indexes []uint32) ([]AddressDescriptor, error) 392 DeriveAddressDescriptorsFromTo(descriptor *XpubDescriptor, change uint32, fromIndex uint32, toIndex uint32) ([]AddressDescriptor, error) 393 // EthereumType specific 394 EthereumTypeGetTokenTransfersFromTx(tx *Tx) (TokenTransfers, error) 395 // CoreCoinType specific 396 CoreCoinTypeGetTokenTransfersFromTx(tx *Tx) (TokenTransfers, error) 397 // AddressAlias 398 FormatAddressAlias(address string, name string) string 399 } 400 401 // Mempool defines common interface to mempool 402 type Mempool interface { 403 Resync() (int, error) 404 GetTransactions(address string) ([]Outpoint, error) 405 GetAddrDescTransactions(addrDesc AddressDescriptor) ([]Outpoint, error) 406 GetAllEntries() MempoolTxidEntries 407 GetTransactionTime(txid string) uint32 408 GetTxidFilterEntries(filterScripts string, fromTimestamp uint32) (MempoolTxidFilterEntries, error) 409 }