2018-01-31 07:23:17 -07:00
|
|
|
package bchain
|
2017-08-28 09:50:57 -06:00
|
|
|
|
2018-03-26 07:17:44 -06:00
|
|
|
import (
|
2018-05-30 06:37:30 -06:00
|
|
|
"context"
|
2018-05-18 07:04:40 -06:00
|
|
|
"encoding/json"
|
2018-03-26 07:17:44 -06:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2018-07-24 07:58:37 -06:00
|
|
|
"math/big"
|
2018-03-26 07:17:44 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// errors with specific meaning returned by blockchain rpc
|
|
|
|
var (
|
|
|
|
// ErrBlockNotFound is returned when block is not found
|
|
|
|
// either unknown hash or too high height
|
|
|
|
// can be returned from GetBlockHash, GetBlockHeader, GetBlock
|
|
|
|
ErrBlockNotFound = errors.New("Block not found")
|
2018-03-28 05:23:43 -06:00
|
|
|
// ErrAddressMissing is returned if address is not specified
|
|
|
|
// for example To address in ethereum can be missing in case of contract transaction
|
|
|
|
ErrAddressMissing = errors.New("Address missing")
|
2018-04-20 15:53:17 -06:00
|
|
|
// ErrTxidMissing is returned if txid is not specified
|
|
|
|
// for example coinbase transactions in Bitcoin
|
|
|
|
ErrTxidMissing = errors.New("Txid missing")
|
2018-03-26 07:17:44 -06:00
|
|
|
)
|
2018-03-08 10:36:01 -07:00
|
|
|
|
2017-08-28 09:50:57 -06:00
|
|
|
type ScriptSig struct {
|
2018-03-02 08:07:45 -07:00
|
|
|
// Asm string `json:"asm"`
|
2017-08-28 09:50:57 -06:00
|
|
|
Hex string `json:"hex"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Vin struct {
|
|
|
|
Coinbase string `json:"coinbase"`
|
|
|
|
Txid string `json:"txid"`
|
|
|
|
Vout uint32 `json:"vout"`
|
|
|
|
ScriptSig ScriptSig `json:"scriptSig"`
|
|
|
|
Sequence uint32 `json:"sequence"`
|
2018-06-21 05:53:27 -06:00
|
|
|
Addresses []string `json:"addresses"`
|
2017-08-28 09:50:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type ScriptPubKey struct {
|
2018-03-22 07:07:14 -06:00
|
|
|
// Asm string `json:"asm"`
|
|
|
|
Hex string `json:"hex,omitempty"`
|
|
|
|
// Type string `json:"type"`
|
2018-06-21 05:53:27 -06:00
|
|
|
Addresses []string `json:"addresses"`
|
2017-08-28 09:50:57 -06:00
|
|
|
}
|
|
|
|
|
2018-04-18 17:49:56 -06:00
|
|
|
type Address interface {
|
|
|
|
String() string
|
2018-05-29 07:03:25 -06:00
|
|
|
AreEqual(addr string) bool
|
|
|
|
InSlice(addrs []string) bool
|
2018-04-18 17:49:56 -06:00
|
|
|
}
|
|
|
|
|
2017-08-28 09:50:57 -06:00
|
|
|
type Vout struct {
|
2018-07-24 07:58:37 -06:00
|
|
|
ValueSat big.Int
|
|
|
|
JsonValue json.Number `json:"value"`
|
2017-08-28 09:50:57 -06:00
|
|
|
N uint32 `json:"n"`
|
|
|
|
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
2018-04-18 17:49:56 -06:00
|
|
|
Address Address
|
2017-08-28 09:50:57 -06:00
|
|
|
}
|
|
|
|
|
2018-03-02 05:45:39 -07:00
|
|
|
// Tx is blockchain transaction
|
|
|
|
// unnecessary fields are commented out to avoid overhead
|
2017-08-28 09:50:57 -06:00
|
|
|
type Tx struct {
|
2018-06-26 05:02:53 -06:00
|
|
|
Hex string `json:"hex"`
|
|
|
|
Txid string `json:"txid"`
|
|
|
|
Version int32 `json:"version"`
|
2018-03-02 05:45:39 -07:00
|
|
|
LockTime uint32 `json:"locktime"`
|
|
|
|
Vin []Vin `json:"vin"`
|
|
|
|
Vout []Vout `json:"vout"`
|
|
|
|
// BlockHash string `json:"blockhash,omitempty"`
|
2017-08-28 09:50:57 -06:00
|
|
|
Confirmations uint32 `json:"confirmations,omitempty"`
|
|
|
|
Time int64 `json:"time,omitempty"`
|
|
|
|
Blocktime int64 `json:"blocktime,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Block struct {
|
2017-09-12 16:36:08 -06:00
|
|
|
BlockHeader
|
|
|
|
Txs []Tx `json:"tx"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type ThinBlock struct {
|
2017-09-11 04:19:41 -06:00
|
|
|
BlockHeader
|
|
|
|
Txids []string `json:"tx"`
|
2017-08-28 09:50:57 -06:00
|
|
|
}
|
2017-09-06 02:59:40 -06:00
|
|
|
|
|
|
|
type BlockHeader struct {
|
2017-09-11 04:19:41 -06:00
|
|
|
Hash string `json:"hash"`
|
2017-09-11 05:03:08 -06:00
|
|
|
Prev string `json:"previousblockhash"`
|
2017-09-11 04:19:41 -06:00
|
|
|
Next string `json:"nextblockhash"`
|
|
|
|
Height uint32 `json:"height"`
|
|
|
|
Confirmations int `json:"confirmations"`
|
2017-09-06 02:59:40 -06:00
|
|
|
}
|
2018-03-08 04:59:37 -07:00
|
|
|
|
2018-03-07 04:08:37 -07:00
|
|
|
type MempoolEntry struct {
|
2018-07-25 07:56:08 -06:00
|
|
|
Size uint32 `json:"size"`
|
|
|
|
FeeSat big.Int
|
|
|
|
Fee json.Number `json:"fee"`
|
|
|
|
ModifiedFeeSat big.Int
|
|
|
|
ModifiedFee json.Number `json:"modifiedfee"`
|
|
|
|
Time uint64 `json:"time"`
|
|
|
|
Height uint32 `json:"height"`
|
|
|
|
DescendantCount uint32 `json:"descendantcount"`
|
|
|
|
DescendantSize uint32 `json:"descendantsize"`
|
|
|
|
DescendantFees uint32 `json:"descendantfees"`
|
|
|
|
AncestorCount uint32 `json:"ancestorcount"`
|
|
|
|
AncestorSize uint32 `json:"ancestorsize"`
|
|
|
|
AncestorFees uint32 `json:"ancestorfees"`
|
|
|
|
Depends []string `json:"depends"`
|
2018-03-07 04:08:37 -07:00
|
|
|
}
|
|
|
|
|
2018-03-08 04:59:37 -07:00
|
|
|
type RPCError struct {
|
|
|
|
Code int `json:"code"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
}
|
|
|
|
|
2018-03-08 10:36:01 -07:00
|
|
|
func (e *RPCError) Error() string {
|
|
|
|
return fmt.Sprintf("%d: %s", e.Code, e.Message)
|
|
|
|
}
|
|
|
|
|
2018-04-08 03:24:29 -06:00
|
|
|
// BlockChain defines common interface to block chain daemon
|
2018-03-08 04:59:37 -07:00
|
|
|
type BlockChain interface {
|
2018-03-19 08:46:29 -06:00
|
|
|
// life-cycle methods
|
2018-03-21 08:33:48 -06:00
|
|
|
Initialize() error
|
2018-05-30 06:37:30 -06:00
|
|
|
Shutdown(ctx context.Context) error
|
2018-03-08 04:59:37 -07:00
|
|
|
// chain info
|
|
|
|
IsTestnet() bool
|
|
|
|
GetNetworkName() string
|
2018-04-27 02:53:33 -06:00
|
|
|
GetSubversion() string
|
2018-06-05 08:14:46 -06:00
|
|
|
GetCoinName() string
|
2018-03-08 04:59:37 -07:00
|
|
|
// requests
|
2018-05-17 04:30:45 -06:00
|
|
|
GetBlockChainInfo() (string, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
GetBestBlockHash() (string, error)
|
|
|
|
GetBestBlockHeight() (uint32, error)
|
|
|
|
GetBlockHash(height uint32) (string, error)
|
|
|
|
GetBlockHeader(hash string) (*BlockHeader, error)
|
2018-03-12 10:37:32 -06:00
|
|
|
GetBlock(hash string, height uint32) (*Block, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
GetMempool() ([]string, error)
|
|
|
|
GetTransaction(txid string) (*Tx, error)
|
2018-05-14 10:12:01 -06:00
|
|
|
GetTransactionForMempool(txid string) (*Tx, error)
|
2018-07-24 07:58:37 -06:00
|
|
|
EstimateSmartFee(blocks int, conservative bool) (big.Int, error)
|
|
|
|
EstimateFee(blocks int) (big.Int, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
SendRawTransaction(tx string) (string, error)
|
|
|
|
// mempool
|
2018-06-01 05:22:56 -06:00
|
|
|
ResyncMempool(onNewTxAddr func(txid string, addr string)) (int, error)
|
2018-03-20 08:58:35 -06:00
|
|
|
GetMempoolTransactions(address string) ([]string, error)
|
2018-03-07 04:08:37 -07:00
|
|
|
GetMempoolEntry(txid string) (*MempoolEntry, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
// parser
|
|
|
|
GetChainParser() BlockChainParser
|
|
|
|
}
|
|
|
|
|
2018-04-08 03:24:29 -06:00
|
|
|
// BlockChainParser defines common interface to parsing and conversions of block chain data
|
2018-03-08 04:59:37 -07:00
|
|
|
type BlockChainParser interface {
|
2018-07-24 07:58:37 -06:00
|
|
|
// chain configuration description
|
2018-03-23 04:03:41 -06:00
|
|
|
// UTXO chains need "inputs" column in db, that map transactions to transactions that spend them
|
|
|
|
// non UTXO chains have mapping of address to input and output transactions directly in "outputs" column in db
|
|
|
|
IsUTXOChain() bool
|
2018-04-20 05:56:55 -06:00
|
|
|
// KeepBlockAddresses returns number of blocks which are to be kept in blockaddresses column
|
|
|
|
// and used in case of fork
|
|
|
|
// if 0 the blockaddresses column is not used at all (usually non UTXO chains)
|
|
|
|
KeepBlockAddresses() int
|
2018-07-24 07:58:37 -06:00
|
|
|
// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
|
|
|
|
AmountToDecimalString(a *big.Int) string
|
|
|
|
// AmountToBigInt converts amount in json.Number (string) to big.Int
|
|
|
|
// it uses string operations to avoid problems with rounding
|
|
|
|
AmountToBigInt(n json.Number) (big.Int, error)
|
2018-03-23 04:03:41 -06:00
|
|
|
// address id conversions
|
2018-03-23 06:15:19 -06:00
|
|
|
GetAddrIDFromVout(output *Vout) ([]byte, error)
|
2018-03-23 04:03:41 -06:00
|
|
|
GetAddrIDFromAddress(address string) ([]byte, error)
|
|
|
|
// address to output script conversions
|
2018-03-08 04:59:37 -07:00
|
|
|
AddressToOutputScript(address string) ([]byte, error)
|
2018-06-18 05:00:54 -06:00
|
|
|
OutputScriptToAddresses(script []byte) ([]string, error)
|
2018-03-23 04:03:41 -06:00
|
|
|
// transactions
|
2018-04-08 03:24:29 -06:00
|
|
|
PackedTxidLen() int
|
|
|
|
PackTxid(txid string) ([]byte, error)
|
|
|
|
UnpackTxid(buf []byte) (string, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
ParseTx(b []byte) (*Tx, error)
|
2018-05-18 07:04:40 -06:00
|
|
|
ParseTxFromJson(json.RawMessage) (*Tx, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error)
|
|
|
|
UnpackTx(buf []byte) (*Tx, uint32, error)
|
2018-03-23 04:03:41 -06:00
|
|
|
// blocks
|
2018-04-08 03:24:29 -06:00
|
|
|
PackBlockHash(hash string) ([]byte, error)
|
|
|
|
UnpackBlockHash(buf []byte) (string, error)
|
2018-03-23 04:03:41 -06:00
|
|
|
ParseBlock(b []byte) (*Block, error)
|
2018-03-08 04:59:37 -07:00
|
|
|
}
|