Merge branch 'master' of github.com:trezor/blockbook

pull/136/head
Martin Boehm 2019-03-13 14:14:25 +01:00
commit 46e49daa9c
10 changed files with 1056 additions and 0 deletions

View File

@ -21,6 +21,7 @@ import (
"blockbook/bchain/coins/myriad"
"blockbook/bchain/coins/namecoin"
"blockbook/bchain/coins/pivx"
"blockbook/bchain/coins/qtum"
"blockbook/bchain/coins/vertcoin"
"blockbook/bchain/coins/xzc"
"blockbook/bchain/coins/zec"
@ -76,6 +77,8 @@ func init() {
BlockChainFactories["Fujicoin"] = fujicoin.NewFujicoinRPC
BlockChainFactories["Flo"] = flo.NewFloRPC
BlockChainFactories["Bellcoin"] = bellcoin.NewBellcoinRPC
BlockChainFactories["Qtum"] = qtum.NewQtumRPC
BlockChainFactories["Qtum Testnet"] = qtum.NewQtumRPC
}
// GetCoinNameFromConfig gets coin name and coin shortcut from config file

View File

@ -0,0 +1,149 @@
package qtum
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"blockbook/bchain/coins/utils"
"bytes"
"encoding/json"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"io"
)
const (
MainnetMagic wire.BitcoinNet = 0xf1cfa6d3
TestnetMagic wire.BitcoinNet = 0x0d221506
)
var (
MainNetParams chaincfg.Params
TestNetParams chaincfg.Params
)
func init() {
MainNetParams = chaincfg.MainNetParams
MainNetParams.Net = MainnetMagic
MainNetParams.PubKeyHashAddrID = []byte{58}
MainNetParams.ScriptHashAddrID = []byte{50}
MainNetParams.Bech32HRPSegwit = "qc"
TestNetParams = chaincfg.TestNet3Params
TestNetParams.Net = TestnetMagic
TestNetParams.PubKeyHashAddrID = []byte{120}
TestNetParams.ScriptHashAddrID = []byte{110}
TestNetParams.Bech32HRPSegwit = "tq"
}
// QtumParser handle
type QtumParser struct {
*btc.BitcoinParser
}
// NewQtumParser returns new DashParser instance
func NewQtumParser(params *chaincfg.Params, c *btc.Configuration) *QtumParser {
return &QtumParser{
BitcoinParser: btc.NewBitcoinParser(params, c),
}
}
// GetChainParams contains network parameters for the main Qtum network,
// the regression test Qtum network, the test Qtum network and
// the simulation test Qtum network, in this order
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
if err == nil {
err = chaincfg.Register(&TestNetParams)
}
if err != nil {
panic(err)
}
}
switch chain {
case "test":
return &TestNetParams
default:
return &MainNetParams
}
}
func parseBlockHeader(r io.Reader) (*wire.BlockHeader, error) {
h := &wire.BlockHeader{}
err := h.Deserialize(r)
// hash_state_root 32
// hash_utxo_root 32
// hash_prevout_stake 32
// hash_prevout_n 4
buf := make([]byte, 100)
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, err
}
sigLength, err := wire.ReadVarInt(r, 0)
if err != nil {
return nil, err
}
sigBuf := make([]byte, sigLength)
_, err = io.ReadFull(r, sigBuf)
if err != nil {
return nil, err
}
return h, err
}
func (p *QtumParser) ParseBlock(b []byte) (*bchain.Block, error) {
r := bytes.NewReader(b)
w := wire.MsgBlock{}
h, err := parseBlockHeader(r)
if err != nil {
return nil, err
}
err = utils.DecodeTransactions(r, 0, wire.WitnessEncoding, &w)
if err != nil {
return nil, err
}
txs := make([]bchain.Tx, len(w.Transactions))
for ti, t := range w.Transactions {
txs[ti] = p.TxFromMsgTx(t, false)
}
return &bchain.Block{
BlockHeader: bchain.BlockHeader{
Size: len(b),
Time: h.Timestamp.Unix(),
},
Txs: txs,
}, nil
}
// ParseTxFromJson parses JSON message containing transaction and returns Tx struct
func (p *QtumParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) {
var tx bchain.Tx
err := json.Unmarshal(msg, &tx)
if err != nil {
return nil, err
}
for i := range tx.Vout {
vout := &tx.Vout[i]
// convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal
vout.ValueSat, err = p.AmountToBigInt(vout.JsonValue)
if err != nil {
return nil, err
}
vout.JsonValue = ""
if vout.ScriptPubKey.Addresses == nil {
vout.ScriptPubKey.Addresses = []string{}
}
}
return &tx, nil
}

View File

@ -0,0 +1,304 @@
// +build unittest
package qtum
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/hex"
"math/big"
"os"
"reflect"
"testing"
"github.com/martinboehm/btcutil/chaincfg"
)
func TestMain(m *testing.M) {
c := m.Run()
chaincfg.ResetParams()
os.Exit(c)
}
func Test_GetAddrDescFromAddress_Mainnet(t *testing.T) {
type args struct {
address string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "P2PKH1",
args: args{address: "QiZfqrMLAtfzLCjXTHyLSiNDV6xydoocme"},
want: "76a914f0e2aff6730b53b9986a5db8ca17c59426134a0988ac",
wantErr: false,
},
{
name: "P2PKH2",
args: args{address: "Qcy8wvP1StA3cB9JcPdivXvqUqwai6t1tC"},
want: "76a914b3822026c7f758b43a0882d7f2cbfa954702e45688ac",
wantErr: false,
},
{
name: "P2SH1",
args: args{address: "MHx35M7aq4FcudwVSYziTkpbm9Hz8wJL7y"},
want: "a9146e3c881d51d62a668362a5bba28be438f9c548e287",
wantErr: false,
},
{
name: "P2SH2",
args: args{address: "MSNLeFGHY8iY2Kio57PnKuwWdCQinjuPDC"},
want: "a914ca962f788569443b33ec673208ccdcfaac6873b487",
wantErr: false,
},
{
name: "witness_v0_keyhash",
args: args{address: "qc1q3msdh3npg5ufvwm2sxltxcet6hll9tjzu8ym0d"},
want: "00148ee0dbc6614538963b6a81beb3632bd5fff2ae42",
wantErr: false,
},
{
name: "witness_v0_scripthashx",
args: args{address: "qc1q0uvgqxwqt0u4esawwcff7652jreqye30kmp4sj5dtydee50pze0s0ljwxp"},
want: "00207f188019c05bf95cc3ae76129f6a8a90f202662fb6c3584a8d591b9cd1e1165f",
wantErr: false,
},
}
parser := NewQtumParser(GetChainParams("main"), &btc.Configuration{})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parser.GetAddrDescFromAddress(tt.args.address)
if (err != nil) != tt.wantErr {
t.Errorf("GetAddrDescFromAddress() error = %v, wantErr %v", err, tt.wantErr)
return
}
h := hex.EncodeToString(got)
if !reflect.DeepEqual(h, tt.want) {
t.Errorf("GetAddrDescFromAddress() = %v, want %v", h, tt.want)
}
})
}
}
func Test_GetAddressesFromAddrDesc(t *testing.T) {
type args struct {
script string
}
tests := []struct {
name string
args args
want []string
want2 bool
wantErr bool
}{
{
name: "P2PKH",
args: args{script: "76a914f0e2aff6730b53b9986a5db8ca17c59426134a0988ac"},
want: []string{"QiZfqrMLAtfzLCjXTHyLSiNDV6xydoocme"},
want2: true,
wantErr: false,
},
{
name: "P2SH",
args: args{script: "a9146e3c881d51d62a668362a5bba28be438f9c548e287"},
want: []string{"MHx35M7aq4FcudwVSYziTkpbm9Hz8wJL7y"},
want2: true,
wantErr: false,
},
{
name: "P2WPKH",
args: args{script: "00148ee0dbc6614538963b6a81beb3632bd5fff2ae42"},
want: []string{"qc1q3msdh3npg5ufvwm2sxltxcet6hll9tjzu8ym0d"},
want2: true,
wantErr: false,
},
{
name: "P2WSH",
args: args{script: "00207f188019c05bf95cc3ae76129f6a8a90f202662fb6c3584a8d591b9cd1e1165f"},
want: []string{"qc1q0uvgqxwqt0u4esawwcff7652jreqye30kmp4sj5dtydee50pze0s0ljwxp"},
want2: true,
wantErr: false,
},
{
name: "OP_RETURN ascii",
args: args{script: "6a0461686f6a"},
want: []string{"OP_RETURN (ahoj)"},
want2: false,
wantErr: false,
},
{
name: "OP_RETURN hex",
args: args{script: "6a072020f1686f6a20"},
want: []string{"OP_RETURN 2020f1686f6a20"},
want2: false,
wantErr: false,
},
}
parser := NewQtumParser(GetChainParams("main"), &btc.Configuration{})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, _ := hex.DecodeString(tt.args.script)
got, got2, err := parser.GetAddressesFromAddrDesc(b)
if (err != nil) != tt.wantErr {
t.Errorf("outputScriptToAddresses() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(got2, tt.want2) {
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, tt.want2)
}
})
}
}
var (
testTx1 bchain.Tx
testTxPacked1 = "00050fc08bc88ede00010000000336e691ab7f236d7c772b18e967c324b92ad1ba79e4641fd868f737d08f11857a000000006b483045022100bdef630a30ea681be3d2a66bbbc994100509effe9b85b384a0f8d75685eca97802206b7a5e58115deffe3f8f35d4c22dc52eb2cc1632ef18a48498731c09255c2fa9812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3fffffffffa3ba1bd605b4db3594a8f5fd3cdec34d3044e3e26dee66908235e8643e9f50f010000006b483045022100f1889232cae3860876025317002bbc9a7e68b172c0595df5db8a1e59a12254150220557bebe548bae1b8fe3474375caca12cab1789e8d6e2c9bd6ab1b4a2c3e3691a812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3ffffffff06fb670847bea092c352198f327e39fac3f568d57a100cb4a7db991485dda546170000006b483045022100a2fba32aebca4eaa261f9ebd2b956ac22d9c29e7f65868acd60165077dcfbc85022011864df322178f515260c9f4c098112bfbc23bf257f38005b80a34271d08149b812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3ffffffff020088526a740000001976a914b61ba6aa3cc8be40e7553c8728ab3a303cbd4f2188acec1e0923000000001976a9148e896f90d402cdb5517f7d1f32a3d9d400e4bbcb88ac00000000"
)
func init() {
testTx1 = bchain.Tx{
Hex: "010000000336e691ab7f236d7c772b18e967c324b92ad1ba79e4641fd868f737d08f11857a000000006b483045022100bdef630a30ea681be3d2a66bbbc994100509effe9b85b384a0f8d75685eca97802206b7a5e58115deffe3f8f35d4c22dc52eb2cc1632ef18a48498731c09255c2fa9812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3fffffffffa3ba1bd605b4db3594a8f5fd3cdec34d3044e3e26dee66908235e8643e9f50f010000006b483045022100f1889232cae3860876025317002bbc9a7e68b172c0595df5db8a1e59a12254150220557bebe548bae1b8fe3474375caca12cab1789e8d6e2c9bd6ab1b4a2c3e3691a812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3ffffffff06fb670847bea092c352198f327e39fac3f568d57a100cb4a7db991485dda546170000006b483045022100a2fba32aebca4eaa261f9ebd2b956ac22d9c29e7f65868acd60165077dcfbc85022011864df322178f515260c9f4c098112bfbc23bf257f38005b80a34271d08149b812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3ffffffff020088526a740000001976a914b61ba6aa3cc8be40e7553c8728ab3a303cbd4f2188acec1e0923000000001976a9148e896f90d402cdb5517f7d1f32a3d9d400e4bbcb88ac00000000",
Blocktime: 1552013184,
Txid: "40cc76f3d9747472c49a7c162628d5794e1fb3e5c28e5787b3c6c1178c794e8c",
LockTime: 0,
Version: 1,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
Hex: "483045022100bdef630a30ea681be3d2a66bbbc994100509effe9b85b384a0f8d75685eca97802206b7a5e58115deffe3f8f35d4c22dc52eb2cc1632ef18a48498731c09255c2fa9812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3",
},
Txid: "7a85118fd037f768d81f64e479bad12ab924c367e9182b777c6d237fab91e636",
Vout: 0,
Sequence: 4294967295,
},
{
ScriptSig: bchain.ScriptSig{
Hex: "483045022100f1889232cae3860876025317002bbc9a7e68b172c0595df5db8a1e59a12254150220557bebe548bae1b8fe3474375caca12cab1789e8d6e2c9bd6ab1b4a2c3e3691a812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3",
},
Txid: "0ff5e943865e230869e6de263e4e04d334eccdd35f8f4a59b34d5b60bda13bfa",
Vout: 1,
Sequence: 4294967295,
},
{
ScriptSig: bchain.ScriptSig{
Hex: "483045022100a2fba32aebca4eaa261f9ebd2b956ac22d9c29e7f65868acd60165077dcfbc85022011864df322178f515260c9f4c098112bfbc23bf257f38005b80a34271d08149b812102cc0f9a0906c0e8dffb3262778be1b3bc75e2d636fa01a7c2c129b1f3f30f21d3",
},
Txid: "46a5dd851499dba7b40c107ad568f5c3fa397e328f1952c392a0be470867fb06",
Vout: 23,
Sequence: 4294967295,
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(500000000000),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914b61ba6aa3cc8be40e7553c8728ab3a303cbd4f2188ac",
Addresses: []string{
"QdCtDST9o3JzQN1tchkpakAgGT4oSRhJec",
},
},
},
{
ValueSat: *big.NewInt(587800300),
N: 1,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a9148e896f90d402cdb5517f7d1f32a3d9d400e4bbcb88ac",
Addresses: []string{
"QZbehkDJekWHZeyKGwXDWqxy8m7RGWPeGn",
},
},
},
},
}
}
func Test_PackTx(t *testing.T) {
type args struct {
tx bchain.Tx
height uint32
blockTime int64
parser *QtumParser
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "Qtum-1",
args: args{
tx: testTx1,
height: 331712,
blockTime: 1552013184,
parser: NewQtumParser(GetChainParams("main"), &btc.Configuration{}),
},
want: testTxPacked1,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.args.parser.PackTx(&tt.args.tx, tt.args.height, tt.args.blockTime)
if (err != nil) != tt.wantErr {
t.Errorf("packTx() error = %v, wantErr %v", err, tt.wantErr)
return
}
h := hex.EncodeToString(got)
if !reflect.DeepEqual(h, tt.want) {
t.Errorf("packTx() = %v, want %v", h, tt.want)
}
})
}
}
func Test_UnpackTx(t *testing.T) {
type args struct {
packedTx string
parser *QtumParser
}
tests := []struct {
name string
args args
want *bchain.Tx
want1 uint32
wantErr bool
}{
{
name: "Qtum-1",
args: args{
packedTx: testTxPacked1,
parser: NewQtumParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx1,
want1: 331712,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, _ := hex.DecodeString(tt.args.packedTx)
got, got1, err := tt.args.parser.UnpackTx(b)
if (err != nil) != tt.wantErr {
t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("unpackTx() got = %v, want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1)
}
})
}
}

View File

@ -0,0 +1,61 @@
package qtum
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/json"
"github.com/golang/glog"
)
// QtumRPC is an interface to JSON-RPC bitcoind service.
type QtumRPC struct {
*btc.BitcoinRPC
}
// NewQtumRPC returns new QtumRPC instance.
func NewQtumRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
b, err := btc.NewBitcoinRPC(config, pushHandler)
if err != nil {
return nil, err
}
s := &QtumRPC{
b.(*btc.BitcoinRPC),
}
s.RPCMarshaler = btc.JSONMarshalerV1{}
s.ChainConfig.SupportsEstimateSmartFee = true
return s, nil
}
// Initialize initializes QtumRPC instance.
func (b *QtumRPC) Initialize() error {
chainName, err := b.GetChainInfoAndInitializeMempool(b)
if err != nil {
return err
}
params := GetChainParams(chainName)
// always create parser
b.Parser = NewQtumParser(params, b.ChainConfig)
// parameters for getInfo request
if params.Net == MainnetMagic {
b.Testnet = false
b.Network = "livenet"
} else {
b.Testnet = true
b.Network = "testnet"
}
glog.Info("rpc: block chain ", params.Name)
return nil
}
// GetTransactionForMempool returns a transaction by the transaction ID
// It could be optimized for mempool, i.e. without block time and confirmations
func (b *QtumRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
return b.GetTransaction(txid)
}

View File

@ -0,0 +1,70 @@
{
"coin": {
"name": "Qtum",
"shortcut": "QTUM",
"label": "Qtum",
"alias": "qtum"
},
"ports": {
"backend_rpc": 8088,
"backend_message_queue": 38388,
"blockbook_internal": 9088,
"blockbook_public": 9188
},
"ipc": {
"rpc_url_template": "http://127.0.0.1:{{.Ports.BackendRPC}}",
"rpc_user": "rpc",
"rpc_pass": "rpc",
"rpc_timeout": 25,
"message_queue_binding_template": "tcp://127.0.0.1:{{.Ports.BackendMessageQueue}}"
},
"backend": {
"package_name": "backend-qtum",
"package_revision": "satoshilabs-1",
"system_user": "qtum",
"version": "0.17.2",
"binary_url": "https://github.com/qtumproject/qtum/releases/download/mainnet-ignition-v0.17.2/qtum-0.17.2-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "f51926bf704c541e3ead5e5a14da6a4807cb7b761c23830aa37f044824e4fb33",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/qtum-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/qtumd -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/*.log",
"postinst_script_template": "",
"service_type": "forking",
"service_additional_params_template": "",
"protect_memory": true,
"mainnet": true,
"server_config_file": "bitcoin_like.conf",
"client_config_file": "bitcoin_like_client.conf",
"additional_params": {
"deprecatedrpc": "estimatefee",
"logevents": "1"
}
},
"blockbook": {
"package_name": "blockbook-qtum",
"system_user": "blockbook-qtum",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300,
"xpub_magic": 76067358,
"xpub_magic_segwit_p2sh": 77429938,
"xpub_magic_segwit_native": 78792518,
"slip44": 2301,
"additional_params": {}
}
},
"meta": {
"package_maintainer": "CodeFace",
"package_maintainer_email": "codeface@qtum.info"
}
}

View File

@ -0,0 +1,70 @@
{
"coin": {
"name": "Qtum Testnet",
"shortcut": "TQTUM",
"label": "Qtum Testnet",
"alias": "qtum_testnet"
},
"ports": {
"backend_rpc": 18088,
"backend_message_queue": 48388,
"blockbook_internal": 19088,
"blockbook_public": 19188
},
"ipc": {
"rpc_url_template": "http://127.0.0.1:{{.Ports.BackendRPC}}",
"rpc_user": "rpc",
"rpc_pass": "rpc",
"rpc_timeout": 25,
"message_queue_binding_template": "tcp://127.0.0.1:{{.Ports.BackendMessageQueue}}"
},
"backend": {
"package_name": "backend-qtum-testnet",
"package_revision": "satoshilabs-1",
"system_user": "qtum",
"version": "0.17.2",
"binary_url": "https://github.com/qtumproject/qtum/releases/download/mainnet-ignition-v0.17.2/qtum-0.17.2-x86_64-linux-gnu.tar.gz",
"verification_type": "sha256",
"verification_source": "f51926bf704c541e3ead5e5a14da6a4807cb7b761c23830aa37f044824e4fb33",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [
"bin/qtum-qt"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/qtumd -datadir={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend -conf={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/{{.Coin.Alias}}.conf -pid=/run/{{.Coin.Alias}}/{{.Coin.Alias}}.pid",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/testnet3/*.log",
"postinst_script_template": "",
"service_type": "forking",
"service_additional_params_template": "",
"protect_memory": true,
"mainnet": false,
"server_config_file": "bitcoin_like.conf",
"client_config_file": "bitcoin_like_client.conf",
"additional_params": {
"deprecatedrpc": "estimatefee",
"logevents": "1"
}
},
"blockbook": {
"package_name": "blockbook-qtum-testnet",
"system_user": "blockbook-qtum",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300,
"xpub_magic": 70617039,
"xpub_magic_segwit_p2sh": 71979618,
"xpub_magic_segwit_native": 73342198,
"slip44": 1,
"additional_params": {}
}
},
"meta": {
"package_maintainer": "CodeFace",
"package_maintainer_email": "codeface@qtum.info"
}
}

View File

@ -26,6 +26,7 @@
| Koto | 9051 | 9151 | 8051 | 38351 |
| Bellcoin | 9052 | 9152 | 8052 | 38352 |
| Flo | 9066 | 9166 | 8066 | 38366 |
| Qtum | 9088 | 9188 | 8088 | 38388 |
| Bitcoin Testnet | 19030 | 19130 | 18030 | 48330 |
| Bitcoin Cash Testnet | 19031 | 19131 | 18031 | 48331 |
| Zcash Testnet | 19032 | 19132 | 18032 | 48332 |
@ -38,5 +39,6 @@
| PIVX Testnet | 19049 | 19149 | 18049 | 48349 |
| Koto Testnet | 19051 | 19151 | 18051 | 48351 |
| Flo Testnet | 19066 | 19166 | 18066 | 48366 |
| Qtum Testnet | 19088 | 19188 | 18088 | 48388 |
> NOTE: This document is generated from coin definitions in `configs/coins`.

170
tests/rpc/testdata/qtum.json vendored 100644
View File

@ -0,0 +1,170 @@
{
"blockHeight": 333514,
"blockHash": "249208b04314e1541c15d7676f09d2a47f8ea7be69b0271678304c5312d44873",
"blockTime": 1552272592,
"blockTxs": [
"1dbdf1b25e3e85fc62158112468e65dba5d63b3824878650809a9718e71174eb",
"a391909c9521ee8e4489705366bf0bcddf84d8a34726ddfd503854ae4cdb4654"
],
"txDetails": {
"1dbdf1b25e3e85fc62158112468e65dba5d63b3824878650809a9718e71174eb": {
"hex": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0503ca160500ffffffff020000000000000000000000000000000000266a24aa21a9ed598bdca4eab6001d5753ba33e9a50b1986649f4b477948b5f761decd6b742b4e0120000000000000000000000000000000000000000000000000000000000000000000000000",
"txid": "1dbdf1b25e3e85fc62158112468e65dba5d63b3824878650809a9718e71174eb",
"blocktime": 1552272592,
"time": 1552272592,
"locktime": 0,
"version": 2,
"vin": [
{
"coinbase": "03ca160500",
"sequence": 4294967295
}
],
"vout": [
{
"value": 0,
"n": 0,
"scriptPubKey": {
"hex": "",
"type": "nonstandard"
}
},
{
"value": 0,
"n": 1,
"scriptPubKey": {
"hex": "6a24aa21a9ed598bdca4eab6001d5753ba33e9a50b1986649f4b477948b5f761decd6b742b4e"
}
}
]
},
"a391909c9521ee8e4489705366bf0bcddf84d8a34726ddfd503854ae4cdb4654": {
"hex": "0200000001bb1bddb412ba1deda03d139889fc892e395d9ae20e5f956d8acb23ae64dc530401000000484730440220243bfff81362d09ee38fda1ac381905fef9af24cf3240a15c14985978c4cccee02204220fa5157693bfa01dd8a3b94ac23b35ba5bad20ff0f8f34c2a248ffacc4f8201ffffffff0b000000000000000000802c8c630400000023210254aaf2f2a7e1de6ff886fdd25ed92d472ecbf6aba7959fcc84079faef9fd0ee0ac005a6202000000001976a914a9f8f3b055324f6b2d6bcac328ec2d7e3cd22d8b88ac005a6202000000001976a914e05a3073deebefc491f782c8af8ad2899a6bf36388ac005a6202000000001976a914dbb6c84e8c0ea78482cc1db809d37572a8bf748e88ac005a6202000000001976a91423158af7bb43843d05bab9210917b9063413a3ae88ac005a6202000000001976a91490d7395c53fb6047a2ff7c7e2b42527ebc81832288ac005a6202000000001976a9140fb6d44794ae58756164b3377c3512286511840488ac005a6202000000001976a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac005a6202000000001976a914f94467916b9e0d985f90722e0d6f5b65846dfb5e88ac005a6202000000001976a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac00000000",
"txid": "a391909c9521ee8e4489705366bf0bcddf84d8a34726ddfd503854ae4cdb4654",
"blocktime": 1552272592,
"time": 1552272592,
"locktime": 0,
"version": 2,
"vin": [
{
"txid": "0453dc64ae23cb8a6d955f0ee29a5d392e89fc8998133da0ed1dba12b4dd1bbb",
"vout": 1,
"scriptSig": {
"hex": "4730440220243bfff81362d09ee38fda1ac381905fef9af24cf3240a15c14985978c4cccee02204220fa5157693bfa01dd8a3b94ac23b35ba5bad20ff0f8f34c2a248ffacc4f8201"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.00000000,
"n": 0,
"scriptPubKey": {
"hex": "",
"type": "nonstandard"
}
},
{
"value": 188.50000000,
"n": 1,
"scriptPubKey": {
"hex": "210254aaf2f2a7e1de6ff886fdd25ed92d472ecbf6aba7959fcc84079faef9fd0ee0ac",
"addresses": [
"Qd3xCT4kKgTDw85vqgr1jXyHq3GqZvurpa"
]
}
},
{
"value": 0.40000000,
"n": 2,
"scriptPubKey": {
"hex": "76a914a9f8f3b055324f6b2d6bcac328ec2d7e3cd22d8b88ac",
"addresses": [
"Qc6iYCZWn4BauKXGYirRG8pMtgdHMk2dzn"
]
}
},
{
"value": 0.40000000,
"n": 3,
"scriptPubKey": {
"hex": "76a914e05a3073deebefc491f782c8af8ad2899a6bf36388ac",
"addresses": [
"Qh4FWjExZZj4v81xeLPG6oLB2tTnLt8BMQ"
]
}
},
{
"value": 0.40000000,
"n": 4,
"scriptPubKey": {
"hex": "76a914dbb6c84e8c0ea78482cc1db809d37572a8bf748e88ac",
"addresses": [
"Qgdj4FrXXxLVkxPDYtFNNGZNd9TJrNjtpM"
]
}
},
{
"value": 0.40000000,
"n": 5,
"scriptPubKey": {
"hex": "76a91423158af7bb43843d05bab9210917b9063413a3ae88ac",
"addresses": [
"QPoVZqSCxtWkHgNt8jkipv6KNJUMmE7gRT"
]
}
},
{
"value": 0.40000000,
"n": 6,
"scriptPubKey": {
"hex": "76a91490d7395c53fb6047a2ff7c7e2b42527ebc81832288ac",
"addresses": [
"QZoqExD34XsaPyx61AmTRTLfSzwYK6pXXY"
]
}
},
{
"value": 0.40000000,
"n": 7,
"scriptPubKey": {
"hex": "76a9140fb6d44794ae58756164b3377c3512286511840488ac",
"addresses": [
"QN35GNbDzzMAHLWBvej9vGucFLpZMoVz6N"
]
}
},
{
"value": 0.40000000,
"n": 8,
"scriptPubKey": {
"hex": "76a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac",
"addresses": [
"QUFwvRXTnjnWmGVYxaXZoEAmMkKtkth8ND"
]
}
},
{
"value": 0.40000000,
"n": 9,
"scriptPubKey": {
"hex": "76a914f94467916b9e0d985f90722e0d6f5b65846dfb5e88ac",
"addresses": [
"QjKzJtymBHQfuc7zGU6LSE1eHfJr2dFXpE"
]
}
},
{
"value": 0.40000000,
"n": 10,
"scriptPubKey": {
"hex": "76a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac",
"addresses": [
"QUFwvRXTnjnWmGVYxaXZoEAmMkKtkth8ND"
]
}
}
]
}
}
}

222
tests/sync/testdata/qtum.json vendored 100644
View File

@ -0,0 +1,222 @@
{
"connectBlocks": {
"syncRanges": [
{
"lower": 333494,
"upper": 333514
}
],
"blocks": {
"333514": {
"height": 333514,
"hash": "249208b04314e1541c15d7676f09d2a47f8ea7be69b0271678304c5312d44873",
"noTxs": 2,
"txDetails": [
{
"hex": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0503ca160500ffffffff020000000000000000000000000000000000266a24aa21a9ed598bdca4eab6001d5753ba33e9a50b1986649f4b477948b5f761decd6b742b4e0120000000000000000000000000000000000000000000000000000000000000000000000000",
"txid": "1dbdf1b25e3e85fc62158112468e65dba5d63b3824878650809a9718e71174eb",
"blocktime": 1552272592,
"time": 1552272592,
"locktime": 0,
"version": 2,
"vin": [
{
"coinbase": "03ca160500",
"sequence": 4294967295
}
],
"vout": [
{
"value": 0,
"n": 0,
"scriptPubKey": {
"hex": "",
"type": "nonstandard"
}
},
{
"value": 0,
"n": 1,
"scriptPubKey": {
"hex": "6a24aa21a9ed598bdca4eab6001d5753ba33e9a50b1986649f4b477948b5f761decd6b742b4e"
}
}
]
},
{
"hex": "0200000001bb1bddb412ba1deda03d139889fc892e395d9ae20e5f956d8acb23ae64dc530401000000484730440220243bfff81362d09ee38fda1ac381905fef9af24cf3240a15c14985978c4cccee02204220fa5157693bfa01dd8a3b94ac23b35ba5bad20ff0f8f34c2a248ffacc4f8201ffffffff0b000000000000000000802c8c630400000023210254aaf2f2a7e1de6ff886fdd25ed92d472ecbf6aba7959fcc84079faef9fd0ee0ac005a6202000000001976a914a9f8f3b055324f6b2d6bcac328ec2d7e3cd22d8b88ac005a6202000000001976a914e05a3073deebefc491f782c8af8ad2899a6bf36388ac005a6202000000001976a914dbb6c84e8c0ea78482cc1db809d37572a8bf748e88ac005a6202000000001976a91423158af7bb43843d05bab9210917b9063413a3ae88ac005a6202000000001976a91490d7395c53fb6047a2ff7c7e2b42527ebc81832288ac005a6202000000001976a9140fb6d44794ae58756164b3377c3512286511840488ac005a6202000000001976a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac005a6202000000001976a914f94467916b9e0d985f90722e0d6f5b65846dfb5e88ac005a6202000000001976a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac00000000",
"txid": "a391909c9521ee8e4489705366bf0bcddf84d8a34726ddfd503854ae4cdb4654",
"blocktime": 1552272592,
"time": 1552272592,
"locktime": 0,
"version": 2,
"vin": [
{
"txid": "0453dc64ae23cb8a6d955f0ee29a5d392e89fc8998133da0ed1dba12b4dd1bbb",
"vout": 1,
"scriptSig": {
"hex": "4730440220243bfff81362d09ee38fda1ac381905fef9af24cf3240a15c14985978c4cccee02204220fa5157693bfa01dd8a3b94ac23b35ba5bad20ff0f8f34c2a248ffacc4f8201"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.00000000,
"n": 0,
"scriptPubKey": {
"hex": "",
"type": "nonstandard"
}
},
{
"value": 188.50000000,
"n": 1,
"scriptPubKey": {
"hex": "210254aaf2f2a7e1de6ff886fdd25ed92d472ecbf6aba7959fcc84079faef9fd0ee0ac",
"addresses": [
"Qd3xCT4kKgTDw85vqgr1jXyHq3GqZvurpa"
]
}
},
{
"value": 0.40000000,
"n": 2,
"scriptPubKey": {
"hex": "76a914a9f8f3b055324f6b2d6bcac328ec2d7e3cd22d8b88ac",
"addresses": [
"Qc6iYCZWn4BauKXGYirRG8pMtgdHMk2dzn"
]
}
},
{
"value": 0.40000000,
"n": 3,
"scriptPubKey": {
"hex": "76a914e05a3073deebefc491f782c8af8ad2899a6bf36388ac",
"addresses": [
"Qh4FWjExZZj4v81xeLPG6oLB2tTnLt8BMQ"
]
}
},
{
"value": 0.40000000,
"n": 4,
"scriptPubKey": {
"hex": "76a914dbb6c84e8c0ea78482cc1db809d37572a8bf748e88ac",
"addresses": [
"Qgdj4FrXXxLVkxPDYtFNNGZNd9TJrNjtpM"
]
}
},
{
"value": 0.40000000,
"n": 5,
"scriptPubKey": {
"hex": "76a91423158af7bb43843d05bab9210917b9063413a3ae88ac",
"addresses": [
"QPoVZqSCxtWkHgNt8jkipv6KNJUMmE7gRT"
]
}
},
{
"value": 0.40000000,
"n": 6,
"scriptPubKey": {
"hex": "76a91490d7395c53fb6047a2ff7c7e2b42527ebc81832288ac",
"addresses": [
"QZoqExD34XsaPyx61AmTRTLfSzwYK6pXXY"
]
}
},
{
"value": 0.40000000,
"n": 7,
"scriptPubKey": {
"hex": "76a9140fb6d44794ae58756164b3377c3512286511840488ac",
"addresses": [
"QN35GNbDzzMAHLWBvej9vGucFLpZMoVz6N"
]
}
},
{
"value": 0.40000000,
"n": 8,
"scriptPubKey": {
"hex": "76a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac",
"addresses": [
"QUFwvRXTnjnWmGVYxaXZoEAmMkKtkth8ND"
]
}
},
{
"value": 0.40000000,
"n": 9,
"scriptPubKey": {
"hex": "76a914f94467916b9e0d985f90722e0d6f5b65846dfb5e88ac",
"addresses": [
"QjKzJtymBHQfuc7zGU6LSE1eHfJr2dFXpE"
]
}
},
{
"value": 0.40000000,
"n": 10,
"scriptPubKey": {
"hex": "76a91453f6dc6a60a98921a3d72aea5dba2aefb6d7bd3888ac",
"addresses": [
"QUFwvRXTnjnWmGVYxaXZoEAmMkKtkth8ND"
]
}
}
]
}
]
}
}
},
"handleFork": {
"syncRanges": [
{
"lower": 333494,
"upper": 333514
}
],
"fakeBlocks": {
"333511": {
"height": 333511,
"hash": "fb0e87a1ccadd775e7e7d31497ef30d8cf2ccc2bcbc57396a364c948b6c34016"
},
"333512": {
"height": 333512,
"hash": "b5e1eb1e02a8f31390152534c4e05a3976ee6ba14689cfc0ba9a866de460b887"
},
"333513": {
"height": 333513,
"hash": "1a2b9b3c74865c23612bd4dcb97b84213a4fc549cb5e8585a0117d53e9464e00"
},
"333514": {
"height": 333514,
"hash": "5603634c6dd553695f46b4f30010b3181087215c7ed291992d1c2864d70f46fe"
}
},
"realBlocks": {
"333511": {
"height": 333511,
"hash": "120d0f656b367137ea0ca88f928753d8fd2d0964cddb5474a4769a93a385f1b8"
},
"333512": {
"height": 333512,
"hash": "cade18715c6ebb00ad530659cf1b2f3f1aacd5d87d5dc60bbfad61e886516dc2"
},
"333513": {
"height": 333513,
"hash": "0c1648c30144646876ea4909ed9bacd6642904cb5bdd84e7180304f7b7ffae65"
},
"333514": {
"height": 333514,
"hash": "249208b04314e1541c15d7676f09d2a47f8ea7be69b0271678304c5312d44873"
}
}
}
}

View File

@ -120,5 +120,10 @@
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],
"sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"]
},
"qtum": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],
"sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"]
}
}