Add Bitcore (BTX)
parent
29af6eb34d
commit
e4231a2eaa
|
@ -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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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 |
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"],
|
||||
|
|
Loading…
Reference in New Issue