Add Bitcore (BTX)

pull/349/head
Dali 2020-01-10 15:13:06 +01:00 committed by Martin
parent 29af6eb34d
commit e4231a2eaa
9 changed files with 717 additions and 0 deletions

View File

@ -0,0 +1,83 @@
package bitcore
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
)
const (
MainnetMagic wire.BitcoinNet = 0xf9beb4d9
TestnetMagic wire.BitcoinNet = 0xfdd2c8f1
RegtestMagic wire.BitcoinNet = 0xfabfb5da
)
var (
MainNetParams chaincfg.Params
TestNetParams chaincfg.Params
)
func init() {
MainNetParams = chaincfg.MainNetParams
MainNetParams.Net = MainnetMagic
MainNetParams.PubKeyHashAddrID = []byte{3}
MainNetParams.ScriptHashAddrID = []byte{125}
MainNetParams.Bech32HRPSegwit = "btx"
TestNetParams = chaincfg.TestNet3Params
TestNetParams.Net = TestnetMagic
TestNetParams.PubKeyHashAddrID = []byte{111}
TestNetParams.ScriptHashAddrID = []byte{196}
TestNetParams.Bech32HRPSegwit = "tbtx"
err := chaincfg.Register(&MainNetParams)
if err != nil {
panic(err)
}
}
// BitcoreParser handle
type BitcoreParser struct {
*btc.BitcoinParser
baseparser *bchain.BaseParser
}
// NewBitcoreParser returns new BitcoreParser instance
func NewBitcoreParser(params *chaincfg.Params, c *btc.Configuration) *BitcoreParser {
return &BitcoreParser{
BitcoinParser: btc.NewBitcoinParser(params, c),
baseparser: &bchain.BaseParser{},
}
}
// GetChainParams contains network parameters for the main Bitcore network,
// and the test Bitcore network
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
}
}
// PackTx packs transaction to byte array using protobuf
func (p *BitcoreParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
return p.baseparser.PackTx(tx, height, blockTime)
}
// UnpackTx unpacks transaction from protobuf byte array
func (p *BitcoreParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
return p.baseparser.UnpackTx(buf)
}

View File

@ -0,0 +1,210 @@
// +build unittest
package bitcore
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: "pubkeyhash1",
args: args{address: "2HbJfcGD6NTm318VeBjfd2hLf44hHkzHVV"},
want: "76a9143236327ebad3be5e336777bb3562439720f38dc488ac",
wantErr: false,
},
{
name: "pubkeyhash2",
args: args{address: "2XFmLkpyBzJncnnkALQ3qnMqSqUdqcBdc4"},
want: "76a914c815e7f760bbd5f109d58e848cf78ba808d972e088ac",
wantErr: false,
},
{
name: "scripthash1",
args: args{address: "scUVfntFvnyTHRCvBwUNyKGVFLiBb2iHVK"},
want: "a914c7ec567ef583a96a74c02980cc42f728cc987c3287",
wantErr: false,
},
{
name: "scripthash2",
args: args{address: "sVeAXe1CMWVAuq5174hG49QRfkBp4GFvAu"},
want: "a9147cf7a3a6b1305871ff5f0f064aaa634880ff67ab87",
wantErr: false,
},
{
name: "witness_v0_keyhash",
args: args{address: "btx1qnfkmarp8pe8q05690zd48qma3gmp0pp66gqsv3"},
want: "00149a6dbe8c270e4e07d345789b53837d8a3617843a",
wantErr: false,
},
}
parser := NewBitcoreParser(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)
}
})
}
}
var (
testTx1 bchain.Tx
testTxPacked1 = "0a20fcd4f2e45787a33571bc9b2ce939d6e8e51fa053296de9240f05455702bd954012e2010200000001f69bd1fd76e52a426f21332e3b7cfbc3350eacbd21c6e0c11a7ae11919803ef0010000006b483045022100d1fa62b9d7860a03e1dcd4734fe42457cb508ebb49e896d7a77748d997d09fba022005f1657b39451afe97076d8667fe5f6f18ca76391521ab84d09d5b82137d933b0121035aaf032f13761f27465467dc73f1998a80dd4d85a6353d2832a7244d7b591d3effffffff02a87322b3010000001976a914d0c320db3fbd0abe2b6fe31a3bca4fed8ce8669588ac94b94f37000000001976a9145584ee07090af59938e991c9d8e9e945c99a449f88ac0000000018858a8ce205200028f9f3133299010a001220f03e801919e17a1ac1e0c621bdac0e35c3fb7c3b2e33216f422ae576fdd19bf61801226b483045022100d1fa62b9d7860a03e1dcd4734fe42457cb508ebb49e896d7a77748d997d09fba022005f1657b39451afe97076d8667fe5f6f18ca76391521ab84d09d5b82137d933b0121035aaf032f13761f27465467dc73f1998a80dd4d85a6353d2832a7244d7b591d3e28ffffffff0f3a480a0501b32273a810001a1976a914d0c320db3fbd0abe2b6fe31a3bca4fed8ce8669588ac22223259336546797741414673617039757139726942474143684e326858356a6e7268753a470a04374fb99410011a1976a9145584ee07090af59938e991c9d8e9e945c99a449f88ac2222324c6f7a646b704450723562356b6a66445042315a76454c597735734475684139594002"
)
func init() {
testTx1 = bchain.Tx{
Hex: "0200000001f69bd1fd76e52a426f21332e3b7cfbc3350eacbd21c6e0c11a7ae11919803ef0010000006b483045022100d1fa62b9d7860a03e1dcd4734fe42457cb508ebb49e896d7a77748d997d09fba022005f1657b39451afe97076d8667fe5f6f18ca76391521ab84d09d5b82137d933b0121035aaf032f13761f27465467dc73f1998a80dd4d85a6353d2832a7244d7b591d3effffffff02a87322b3010000001976a914d0c320db3fbd0abe2b6fe31a3bca4fed8ce8669588ac94b94f37000000001976a9145584ee07090af59938e991c9d8e9e945c99a449f88ac00000000",
Blocktime: 1547896069,
Time: 1547896069,
Txid: "fcd4f2e45787a33571bc9b2ce939d6e8e51fa053296de9240f05455702bd9540",
LockTime: 0,
Version: 2,
Vin: []bchain.Vin{
{
ScriptSig: bchain.ScriptSig{
Hex: "483045022100d1fa62b9d7860a03e1dcd4734fe42457cb508ebb49e896d7a77748d997d09fba022005f1657b39451afe97076d8667fe5f6f18ca76391521ab84d09d5b82137d933b0121035aaf032f13761f27465467dc73f1998a80dd4d85a6353d2832a7244d7b591d3e",
},
Txid: "f03e801919e17a1ac1e0c621bdac0e35c3fb7c3b2e33216f422ae576fdd19bf6",
Vout: 1,
Sequence: 4294967295,
},
},
Vout: []bchain.Vout{
{
ValueSat: *big.NewInt(7300346792),
N: 0,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a914d0c320db3fbd0abe2b6fe31a3bca4fed8ce8669588ac",
Addresses: []string{
"2Y3eFywAAFsap9uq9riBGAChN2hX5jnrhu",
},
},
},
{
ValueSat: *big.NewInt(927971732),
N: 1,
ScriptPubKey: bchain.ScriptPubKey{
Hex: "76a9145584ee07090af59938e991c9d8e9e945c99a449f88ac",
Addresses: []string{
"2LozdkpDPr5b5kjfDPB1ZvELYw5sDuhA9Y",
},
},
},
},
}
}
func Test_PackTx(t *testing.T) {
type args struct {
tx bchain.Tx
height uint32
blockTime int64
parser *BitcoreParser
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "bitcore-1",
args: args{
tx: testTx1,
height: 326137,
blockTime: 1547896069,
parser: NewBitcoreParser(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 *BitcoreParser
}
tests := []struct {
name string
args args
want *bchain.Tx
want1 uint32
wantErr bool
}{
{
name: "bitcore-1",
args: args{
packedTx: testTxPacked1,
parser: NewBitcoreParser(GetChainParams("main"), &btc.Configuration{}),
},
want: &testTx1,
want1: 326137,
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,134 @@
package bitcore
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"encoding/json"
"github.com/juju/errors"
"github.com/golang/glog"
)
// BitcoreRPC is an interface to JSON-RPC bitcoind service.
type BitcoreRPC struct {
*btc.BitcoinRPC
}
// NewBitcoreRPC returns new BitcoreRPC instance.
func NewBitcoreRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
b, err := btc.NewBitcoinRPC(config, pushHandler)
if err != nil {
return nil, err
}
s := &BitcoreRPC{
b.(*btc.BitcoinRPC),
}
s.RPCMarshaler = btc.JSONMarshalerV2{}
s.ChainConfig.SupportsEstimateFee = false
return s, nil
}
// Initialize initializes BitcoreRPC instance.
func (b *BitcoreRPC) Initialize() error {
ci, err := b.GetChainInfo()
if err != nil {
return err
}
chainName := ci.Chain
glog.Info("Chain name ", chainName)
params := GetChainParams(chainName)
// always create parser
b.Parser = NewBitcoreParser(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
}
// GetBlock returns block with given hash.
func (f *BitcoreRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
var err error
if hash == "" {
hash, err = f.GetBlockHash(height)
if err != nil {
return nil, err
}
}
if !f.ParseBlocks {
return f.GetBlockFull(hash)
}
// optimization
if height > 0 {
return f.GetBlockWithoutHeader(hash, height)
}
header, err := f.GetBlockHeader(hash)
if err != nil {
return nil, err
}
data, err := f.GetBlockRaw(hash)
if err != nil {
return nil, err
}
block, err := f.Parser.ParseBlock(data)
if err != nil {
return nil, errors.Annotatef(err, "hash %v", hash)
}
block.BlockHeader = *header
return block, nil
}
// GetBlockFull returns block with given hash
func (f *BitcoreRPC) GetBlockFull(hash string) (*bchain.Block, error) {
glog.V(1).Info("rpc: getblock (verbosity=2) ", hash)
res := btc.ResGetBlockFull{}
req := btc.CmdGetBlock{Method: "getblock"}
req.Params.BlockHash = hash
req.Params.Verbosity = 2
err := f.Call(&req, &res)
if err != nil {
return nil, errors.Annotatef(err, "hash %v", hash)
}
if res.Error != nil {
if btc.IsErrBlockNotFound(res.Error) {
return nil, bchain.ErrBlockNotFound
}
return nil, errors.Annotatef(res.Error, "hash %v", hash)
}
for i := range res.Result.Txs {
tx := &res.Result.Txs[i]
for j := range tx.Vout {
vout := &tx.Vout[j]
// convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal
vout.ValueSat, err = f.Parser.AmountToBigInt(vout.JsonValue)
if err != nil {
return nil, err
}
vout.JsonValue = ""
}
}
return &res.Result, nil
}
// GetTransactionForMempool returns a transaction by the transaction ID.
// It could be optimized for mempool, i.e. without block time and confirmations
func (f *BitcoreRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
return f.GetTransaction(txid)
}

View File

@ -4,6 +4,7 @@ import (
"blockbook/bchain"
"blockbook/bchain/coins/bch"
"blockbook/bchain/coins/bellcoin"
"blockbook/bchain/coins/bitcore"
"blockbook/bchain/coins/btc"
"blockbook/bchain/coins/btg"
"blockbook/bchain/coins/cpuchain"
@ -105,6 +106,7 @@ func init() {
BlockChainFactories["CPUchain"] = cpuchain.NewCPUchainRPC
BlockChainFactories["Unobtanium"] = unobtanium.NewUnobtaniumRPC
BlockChainFactories["DeepOnion"] = deeponion.NewDeepOnionRPC
BlockChainFactories["Bitcore"] = bitcore.NewBitcoreRPC
}
// GetCoinNameFromConfig gets coin name and coin shortcut from config file

View File

@ -0,0 +1,71 @@
{
"coin": {
"name": "Bitcore",
"shortcut": "BTX",
"label": "Bitcore",
"alias": "bitcore"
},
"ports": {
"backend_rpc": 8054,
"backend_message_queue": 38354,
"blockbook_internal": 9054,
"blockbook_public": 9154
},
"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-bitcore",
"package_revision": "satoshilabs-1",
"system_user": "bitcore",
"version": "0.15.2.1",
"binary_url": "https://github.com/dalijolijo/BitCore/releases/download/0.15.2.1/bitcore-0.15.2.1-x86_64-linux-gnu_no-wallet.tar.gz",
"verification_type": "sha256",
"verification_source": "4e47b33d5fa7d67151c9860f4cd19c99a55d42b27c170bd2391988c67aa24fc8",
"extract_command": "tar -C backend -xf",
"exclude_files": [
"bin/bitcore-qt",
"bin/test_bitcore-qt",
"bin/bench_bitcore",
"bin/test_bitcore"
],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/bin/bitcored -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": {
"whitelist": "127.0.0.1"
}
},
"blockbook": {
"package_name": "blockbook-bitcore",
"system_user": "blockbook-bitcore",
"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,
"additional_params": {
"fiat_rates": "coingecko",
"fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"bitcore\", \"periodSeconds\": 60}"
}
}
},
"meta": {
"package_maintainer": "LIMXTEC",
"package_maintainer_email": "info@bitcore.cc"
}
}

View File

@ -26,6 +26,7 @@
| Koto | 9051 | 9151 | 8051 | 38351 |
| Bellcoin | 9052 | 9152 | 8052 | 38352 |
| NULS | 9053 | 9153 | 8053 | 38353 |
| Bitcore | 9054 | 9154 | 8054 | 38354 |
| Viacoin | 9055 | 9155 | 8055 | 38355 |
| VIPSTARCOIN | 9056 | 9156 | 8056 | 38356 |
| MonetaryUnit | 9057 | 9157 | 8057 | 38357 |

46
tests/rpc/testdata/bitcore.json vendored 100644
View File

@ -0,0 +1,46 @@
{
"blockHeight": 326137,
"blockHash": "e55c2494163b9c0fa52fdc94deaf69edb9c391c0de8831b036c84a5576e9bb4d",
"blockTime": 1547896069,
"blockTxs": [
"a64bb0b727a8c726773f4d90c8844e4d67723002a02d0640dec9d6df81b1b8c0",
"77d9f84476e40fa48b2206e734f718d35dfd86911b945944ee05160699739c8b",
"fcd4f2e45787a33571bc9b2ce939d6e8e51fa053296de9240f05455702bd9540"
],
"txDetails": {
"fcd4f2e45787a33571bc9b2ce939d6e8e51fa053296de9240f05455702bd9540": {
"hex": "0200000001f69bd1fd76e52a426f21332e3b7cfbc3350eacbd21c6e0c11a7ae11919803ef0010000006b483045022100d1fa62b9d7860a03e1dcd4734fe42457cb508ebb49e896d7a77748d997d09fba022005f1657b39451afe97076d8667fe5f6f18ca76391521ab84d09d5b82137d933b0121035aaf032f13761f27465467dc73f1998a80dd4d85a6353d2832a7244d7b591d3effffffff02a87322b3010000001976a914d0c320db3fbd0abe2b6fe31a3bca4fed8ce8669588ac94b94f37000000001976a9145584ee07090af59938e991c9d8e9e945c99a449f88ac00000000",
"txid": "fcd4f2e45787a33571bc9b2ce939d6e8e51fa053296de9240f05455702bd9540",
"blocktime": 1547896069,
"time": 1547896069,
"locktime": 0,
"version": 2,
"vin": [
{
"txid": "f03e801919e17a1ac1e0c621bdac0e35c3fb7c3b2e33216f422ae576fdd19bf6",
"vout": 1,
"scriptSig": {
"hex": "483045022100d1fa62b9d7860a03e1dcd4734fe42457cb508ebb49e896d7a77748d997d09fba022005f1657b39451afe97076d8667fe5f6f18ca76391521ab84d09d5b82137d933b0121035aaf032f13761f27465467dc73f1998a80dd4d85a6353d2832a7244d7b591d3e"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 73.00346792,
"n": 0,
"scriptPubKey": {
"hex": "76a914d0c320db3fbd0abe2b6fe31a3bca4fed8ce8669588ac"
}
},
{
"value": 9.27971732,
"n": 1,
"scriptPubKey": {
"hex": "76a9145584ee07090af59938e991c9d8e9e945c99a449f88ac"
}
}
]
}
}
}

165
tests/sync/testdata/bitcore.json vendored 100644
View File

@ -0,0 +1,165 @@
{
"connectBlocks": {
"syncRanges": [
{"lower": 322212, "upper": 322232}
],
"blocks": {
"322230": {
"height": 322230,
"hash": "7c5a032930a9e0250cc976a70cbc633b440e569f45b53c77b2c1ad3438430add",
"noTxs": 3,
"txDetails": [
{
"txid": "54d2eacdd9aa1f91e9829dbbbfa1a9a9cb3dda75d5f7e134accccdf1c5b4b53c",
"version": 2,
"vin": [
{
"txid": "36ca6b110a6e96c302e5d93d5ba7547e902a42d614e3e365cc0049dcb6f2cd06",
"vout": 1,
"scriptSig": {
"hex": "483045022100dbfc804b9fddb122b0b85e126786ce4be8bdec7cc74ae5c559ff47005947af5b02201d06c5bb13127170ee4002f28048f216c7b07359eec87c7c5d893ee709c2aff60121026c05efaacc255d07782f83d1b7ce948ecbf406adf0ff95454daa21a7ed2eaa62"
},
"sequence": 4294967294
}
],
"vout": [
{
"value": 549.9939726,
"n": 0,
"scriptPubKey": {
"hex": "76a9143bb26a2427f9790ff0e7afdecd3460cf59aa81d688ac"
}
},
{
"value": 50.00000000,
"n": 1,
"scriptPubKey": {
"hex": "76a914bb36447fe1acc280e0304d00cf25772413b9954d88ac"
}
}
],
"hex": "020000000106cdf2b6dc4900cc65e3e314d6422a907e54a75b3dd9e502c3966e0a116bca36010000006b483045022100dbfc804b9fddb122b0b85e126786ce4be8bdec7cc74ae5c559ff47005947af5b02201d06c5bb13127170ee4002f28048f216c7b07359eec87c7c5d893ee709c2aff60121026c05efaacc255d07782f83d1b7ce948ecbf406adf0ff95454daa21a7ed2eaa62feffffff028c3338ce0c0000001976a9143bb26a2427f9790ff0e7afdecd3460cf59aa81d688ac00f2052a010000001976a914bb36447fe1acc280e0304d00cf25772413b9954d88acb5ea0400",
"time": 1547300769,
"blocktime": 1547300769
},
{
"txid": "2506225de845f0a4078987c1aab115b6f08eaa6d08f76be0aa61ce9a3a86eabc",
"version": 2,
"vin": [
{
"txid": "fbb10919a1cca68bafe4a2a9a09cd23e00231d84d0e6c010f31c962250921751",
"vout": 1,
"scriptSig": {
"hex": "4830450221009afeedd0eed56bd6bd2c1e361b811ce094659ca178a401af3e0aeae23748a66802206f29e6f7961f0e13bb5626d7c2393ead75642091187aa5c454427a7f4b2d9d1d012103bf507caf97b107e35ba894bd51fe677a5f4dd7a9523d54d58d622604e7a0099c"
},
"sequence": 4294967294
}
],
"vout": [
{
"value": 299.99729859,
"n": 0,
"scriptPubKey": {
"hex": "76a914cbd6c5e94d9ce8520ba81f32c74e02fc0b36c98588ac"
}
},
{
"value": 50.00000000,
"n": 1,
"scriptPubKey": {
"hex": "76a914bb36447fe1acc280e0304d00cf25772413b9954d88ac"
}
}
],
"hex": "02000000015117925022961cf310c0e6d0841d23003ed29ca0a9a2e4af8ba6cca11909b1fb010000006b4830450221009afeedd0eed56bd6bd2c1e361b811ce094659ca178a401af3e0aeae23748a66802206f29e6f7961f0e13bb5626d7c2393ead75642091187aa5c454427a7f4b2d9d1d012103bf507caf97b107e35ba894bd51fe677a5f4dd7a9523d54d58d622604e7a0099cfeffffff02c38c1ffc060000001976a914cbd6c5e94d9ce8520ba81f32c74e02fc0b36c98588ac00f2052a010000001976a914bb36447fe1acc280e0304d00cf25772413b9954d88acb5ea0400",
"blockhash": "7c5a032930a9e0250cc976a70cbc633b440e569f45b53c77b2c1ad3438430add",
"confirmations": 4126,
"time": 1547300769,
"blocktime": 1547300769
}
]
},
"322214": {
"height": 322214,
"hash": "4ef7b0e81593fe596d2007755b7b9536a650367cd2faac20c109fe59692435e7",
"noTxs": 4,
"txDetails": [
{
"txid": "7dc1059cb5824758a256c0e637e7282a97557b77d1d19c0862e3c909d48a3235",
"version": 2,
"vin": [
{
"txid": "a6793b708e5b8fb0d4ac641e20f5f6ede4528c70946a64121459aad446d7c5c3",
"vout": 0,
"scriptSig": {
"hex": "47304402206951c77f111798349509b29ac05f0b4b12e31b08a5af63dbee53736ddbe4144a02205c8049556deadd2452e0cd0ac418402a641b9b94bae2a4d41e04ac755c658afd012102d9b6098eacbb5a58f984c76d75c99b6bfc0fae73590f946a6a4c2634acf8cc8e"
},
"sequence": 4294967294
},
{
"txid": "5a1bdefc5a4f9b7074ae46893a2d8e908ecad01986519ffe7b8c97de489f33d9",
"vout": 1,
"scriptSig": {
"hex": "4730440220705673f1cbf506177ae65dafe87083df2aefc8f3652bfe367031252d41897a810220554082d80ed46c1f831cb33c50aaf9390b0c83f4a02955b3048958cb2a9f36cd012102532ad08c8e2084f3a4811fac622dff01dded81ee3ef200d3e7efbccce1f52d60"
},
"sequence": 4294967294
}
],
"vout": [
{
"value": 3.12682838,
"n": 0,
"scriptPubKey": {
"hex": "76a914ff65ae5ed06457a560130eb33befb79b7240807888ac"
}
},
{
"value": 0.01459703,
"n": 1,
"scriptPubKey": {
"hex": "76a914cff0d08dd8853b20d0ecefa3a48452157a54e1ac88ac"
}
}
],
"hex": "0200000002c3c5d746d4aa591412646a94708c52e4edf6f5201e64acd4b08f5b8e703b79a6000000006a47304402206951c77f111798349509b29ac05f0b4b12e31b08a5af63dbee53736ddbe4144a02205c8049556deadd2452e0cd0ac418402a641b9b94bae2a4d41e04ac755c658afd012102d9b6098eacbb5a58f984c76d75c99b6bfc0fae73590f946a6a4c2634acf8cc8efeffffffd9339f48de978c7bfe9f518619d0ca8e908e2d3a8946ae74709b4f5afcde1b5a010000006a4730440220705673f1cbf506177ae65dafe87083df2aefc8f3652bfe367031252d41897a810220554082d80ed46c1f831cb33c50aaf9390b0c83f4a02955b3048958cb2a9f36cd012102532ad08c8e2084f3a4811fac622dff01dded81ee3ef200d3e7efbccce1f52d60feffffff025629a312000000001976a914ff65ae5ed06457a560130eb33befb79b7240807888acf7451600000000001976a914cff0d08dd8853b20d0ecefa3a48452157a54e1ac88aca5ea0400",
"time": 1547296216,
"blocktime": 1547296216
}
]
}
}
},
"handleFork": {
"syncRanges": [
{"lower": 322225, "upper": 322232}
],
"fakeBlocks": {
"322230": {
"height": 322230,
"hash": "39918a9e2be1ee0b67b0cdee18d5fa23c24e8770c19a2deeaf9782eb8d2e3803"
},
"322231": {
"height": 322231,
"hash": "6f796caa1d61b44e4c149a12b7ba9fa11db58293642f620bf94c96a39667d7ba"
},
"322232": {
"height": 322232,
"hash": "d41f4d45ba4bb1659674932183de4f9a26bfcf0df484e3fd70e75a475b85d038"
}
},
"realBlocks": {
"322230": {
"height": 322230,
"hash": "7c5a032930a9e0250cc976a70cbc633b440e569f45b53c77b2c1ad3438430add"
},
"322231": {
"height": 322231,
"hash": "a737e20511e55fe6b696475cc8c5ce43acb6bff49ce8eb09bf838bcdd0f49ccd"
},
"322232": {
"height": 322232,
"hash": "7c3a4671c8faf59b35fcaa91a33a9e24cd24714b22e40c2b8e3e3c82410c991d"
}
}
}
}

View File

@ -27,6 +27,11 @@
"EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],
"sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"]
},
"bitcore": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],
"sync": ["ConnectBlocksParallel", "ConnectBlocks", "HandleFork"]
},
"cpuchain": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateSmartFee", "EstimateFee"],