Skip to content

Commit

Permalink
New seed format and added TOR seeds
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBurkett committed May 30, 2022
1 parent 8dc9bc0 commit f7b8934
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 107 deletions.
128 changes: 84 additions & 44 deletions contrib/seeds/generate-seeds.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2017 Wladimir J. van der Laan
# Copyright (c) 2014-2021 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Expand All @@ -13,45 +13,55 @@
These files must consist of lines in the format
<ip>
<ip>:<port>
[<ipv6>]
[<ipv6>]:<port>
<onion>.onion
0xDDBBCCAA (IPv4 little-endian old pnSeeds format)
<onion>.onion:<port>
<i2p>.b32.i2p:<port>
The output will be two data structures with the peers in binary format:
static SeedSpec6 pnSeed6_main[]={
...
}
static SeedSpec6 pnSeed6_test[]={
static const uint8_t chainparams_seed_{main,test}[]={
...
}
These should be pasted into `src/chainparamsseeds.h`.
'''

from base64 import b32decode
from binascii import a2b_hex
from enum import Enum
import struct
import sys
import os
import re

# ipv4 in ipv6 prefix
pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff])
# tor-specific ipv6 prefix
pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43])

def name_to_ipv6(addr):
if len(addr)>6 and addr.endswith('.onion'):
class BIP155Network(Enum):
IPV4 = 1
IPV6 = 2
TORV2 = 3 # no longer supported
TORV3 = 4
I2P = 5
CJDNS = 6

def name_to_bip155(addr):
'''Convert address string to BIP155 (networkID, addr) tuple.'''
if addr.endswith('.onion'):
vchAddr = b32decode(addr[0:-6], True)
if len(vchAddr) != 16-len(pchOnionCat):
if len(vchAddr) == 35:
assert vchAddr[34] == 3
return (BIP155Network.TORV3, vchAddr[:32])
elif len(vchAddr) == 10:
return (BIP155Network.TORV2, vchAddr)
else:
raise ValueError('Invalid onion %s' % vchAddr)
return pchOnionCat + vchAddr
elif addr.endswith('.b32.i2p'):
vchAddr = b32decode(addr[0:-8] + '====', True)
if len(vchAddr) == 32:
return (BIP155Network.I2P, vchAddr)
else:
raise ValueError(f'Invalid I2P {vchAddr}')
elif '.' in addr: # IPv4
return pchIPv4 + bytearray((int(x) for x in addr.split('.')))
elif ':' in addr: # IPv6
return (BIP155Network.IPV4, bytes((int(x) for x in addr.split('.'))))
elif ':' in addr: # IPv6 or CJDNS
sub = [[], []] # prefix, suffix
x = 0
addr = addr.split(':')
Expand All @@ -67,13 +77,19 @@ def name_to_ipv6(addr):
sub[x].append(val & 0xff)
nullbytes = 16 - len(sub[0]) - len(sub[1])
assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
return bytearray(sub[0] + ([0] * nullbytes) + sub[1])
elif addr.startswith('0x'): # IPv4-in-little-endian
return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:])))
addr_bytes = bytes(sub[0] + ([0] * nullbytes) + sub[1])
if addr_bytes[0] == 0xfc:
# Assume that seeds with fc00::/8 addresses belong to CJDNS,
# not to the publicly unroutable "Unique Local Unicast" network, see
# RFC4193: https://datatracker.ietf.org/doc/html/rfc4193#section-8
return (BIP155Network.CJDNS, addr_bytes)
else:
return (BIP155Network.IPV6, addr_bytes)
else:
raise ValueError('Could not parse address %s' % addr)

def parse_spec(s, defaultport):
def parse_spec(s):
'''Convert endpoint string to BIP155 (networkID, addr, port) tuple.'''
match = re.match(r'\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s)
if match: # ipv6
host = match.group(1)
Expand All @@ -85,32 +101,57 @@ def parse_spec(s, defaultport):
(host,_,port) = s.partition(':')

if not port:
port = defaultport
port = 0
else:
port = int(port)

host = name_to_ipv6(host)

return (host,port)
host = name_to_bip155(host)

def process_nodes(g, f, structname, defaultport):
g.write('static SeedSpec6 %s[] = {\n' % structname)
first = True
if host[0] == BIP155Network.TORV2:
return None # TORV2 is no longer supported, so we ignore it
else:
return host + (port, )

def ser_compact_size(l):
r = b""
if l < 253:
r = struct.pack("B", l)
elif l < 0x10000:
r = struct.pack("<BH", 253, l)
elif l < 0x100000000:
r = struct.pack("<BI", 254, l)
else:
r = struct.pack("<BQ", 255, l)
return r

def bip155_serialize(spec):
'''
Serialize (networkID, addr, port) tuple to BIP155 binary format.
'''
r = b""
r += struct.pack('B', spec[0].value)
r += ser_compact_size(len(spec[1]))
r += spec[1]
r += struct.pack('>H', spec[2])
return r

def process_nodes(g, f, structname):
g.write('static const uint8_t %s[] = {\n' % structname)
for line in f:
comment = line.find('#')
if comment != -1:
line = line[0:comment]
line = line.strip()
if not line:
continue
if not first:
g.write(',\n')
first = False

(host,port) = parse_spec(line, defaultport)
hoststr = ','.join(('0x%02x' % b) for b in host)
g.write(' {{%s}, %i}' % (hoststr, port))
g.write('\n};\n')
spec = parse_spec(line)
if spec is None: # ignore this entry (e.g. no longer supported addresses like TORV2)
continue
blob = bip155_serialize(spec)
hoststr = ','.join(('0x%02x' % b) for b in blob)
g.write(f' {hoststr},\n')
g.write('};\n')

def main():
if len(sys.argv)<2:
Expand All @@ -121,17 +162,16 @@ def main():
g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n')
g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n')
g.write('/**\n')
g.write(' * List of fixed seed nodes for the litecoin network\n')
g.write(' * List of fixed seed nodes for the bitcoin network\n')
g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n')
g.write(' *\n')
g.write(' * Each line contains a 16-byte IPv6 address and a port.\n')
g.write(' * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.\n')
g.write(' * Each line contains a BIP155 serialized (networkID, addr, port) tuple.\n')
g.write(' */\n')
with open(os.path.join(indir,'nodes_main.txt'), 'r', encoding="utf8") as f:
process_nodes(g, f, 'pnSeed6_main', 9333)
process_nodes(g, f, 'chainparams_seed_main')
g.write('\n')
with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f:
process_nodes(g, f, 'pnSeed6_test', 19335)
process_nodes(g, f, 'chainparams_seed_test')
g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')

if __name__ == '__main__':
Expand Down
4 changes: 3 additions & 1 deletion contrib/seeds/nodes_main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
154.22.123.138:9333
174.62.70.234:9333
178.62.46.195:9333
213.244.192.149:9333
213.244.192.149:9333
xtmsopiy2ssu2vumfmnjq3nyflnq2pkpcxndi6rxgwnkljmzijafozqd.onion:9333
37am23y5vro3iorqlmjjty7ctsgz6myoaushxrfqct4ngakl7d7idgid.onion:9333
2 changes: 2 additions & 0 deletions contrib/seeds/nodes_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@
202.238.193.15:19335
203.216.0.105:19335
212.83.174.255:19335
mxk7vkfxvtap2aikbjqcx7b4eex2yiag5v5vhuljnvurpybv4a6q5cqd.onion:19335
octnr6yzgosiupuuivgla67p3ml6pc5qpozqn7zpmpbxge6pq5iq4had.onion:19335
4 changes: 2 additions & 2 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class CMainParams : public CChainParams {
bech32_hrp = "ltc";
mweb_hrp = "ltcmweb";

vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
vFixedSeeds = std::vector<uint8_t>(std::begin(chainparams_seed_main), std::end(chainparams_seed_main));

fDefaultConsistencyChecks = false;
fRequireStandard = true;
Expand Down Expand Up @@ -249,7 +249,7 @@ class CTestNetParams : public CChainParams {
bech32_hrp = "tltc";
mweb_hrp = "tmweb";

vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
vFixedSeeds = std::vector<uint8_t>(std::begin(chainparams_seed_test), std::end(chainparams_seed_test));

fDefaultConsistencyChecks = false;
fRequireStandard = false;
Expand Down
4 changes: 2 additions & 2 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class CChainParams
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::string& Bech32HRP() const { return bech32_hrp; }
const std::string& MWEB_HRP() const { return mweb_hrp; }
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const std::vector<uint8_t>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }
protected:
Expand All @@ -108,7 +108,7 @@ class CChainParams
std::string mweb_hrp;
std::string strNetworkID;
CBlock genesis;
std::vector<SeedSpec6> vFixedSeeds;
std::vector<uint8_t> vFixedSeeds;
bool fDefaultConsistencyChecks;
bool fRequireStandard;
bool m_is_test_chain;
Expand Down
101 changes: 52 additions & 49 deletions src/chainparamsseeds.h
Original file line number Diff line number Diff line change
@@ -1,59 +1,62 @@
#ifndef BITCOIN_CHAINPARAMSSEEDS_H
#define BITCOIN_CHAINPARAMSSEEDS_H
/**
* List of fixed seed nodes for the litecoin network
* List of fixed seed nodes for the bitcoin network
* AUTOGENERATED by contrib/seeds/generate-seeds.py
*
* Each line contains a 16-byte IPv6 address and a port.
* IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.
* Each line contains a BIP155 serialized (networkID, addr, port) tuple.
*/
static SeedSpec6 pnSeed6_main[] = {
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0xd6,0x9a,0x19}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x27,0x68,0xa3,0xc8}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x5a,0x89,0x79}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xfd,0x39,0xd7}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd7,0x7f,0x49}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa4,0xc4,0xef}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3f,0xaa,0x56}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x02,0x44,0xfa}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x0a,0x6e,0x8f}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x03,0x26,0xf7}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xb2,0x39,0x03}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x16,0x7b,0x8a}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x3e,0x46,0xea}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x2e,0xc3}, 9333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xf4,0xc0,0x95}, 9333}
static const uint8_t chainparams_seed_main[] = {
0x01,0x04,0x08,0xd6,0x9a,0x19,0x24,0x75,
0x01,0x04,0x27,0x68,0xa3,0xc8,0x24,0x75,
0x01,0x04,0x2f,0x5a,0x89,0x79,0x24,0x75,
0x01,0x04,0x2f,0xfd,0x39,0xd7,0x24,0x75,
0x01,0x04,0x3e,0xd7,0x7f,0x49,0x24,0x75,
0x01,0x04,0x45,0xa4,0xc4,0xef,0x24,0x75,
0x01,0x04,0x46,0x3f,0xaa,0x56,0x24,0x75,
0x01,0x04,0x55,0x02,0x44,0xfa,0x24,0x75,
0x01,0x04,0x56,0x0a,0x6e,0x8f,0x24,0x75,
0x01,0x04,0x68,0x03,0x26,0xf7,0x24,0x75,
0x01,0x04,0x8f,0xb2,0x39,0x03,0x24,0x75,
0x01,0x04,0x9a,0x16,0x7b,0x8a,0x24,0x75,
0x01,0x04,0xae,0x3e,0x46,0xea,0x24,0x75,
0x01,0x04,0xb2,0x3e,0x2e,0xc3,0x24,0x75,
0x01,0x04,0xd5,0xf4,0xc0,0x95,0x24,0x75,
0x04,0x20,0xbc,0xd9,0x27,0x3d,0x18,0xd4,0xa5,0x4d,0x56,0x8c,0x2b,0x1a,0x98,0x6d,0xb8,0x2a,0xdb,0x0d,0x3d,0x4f,0x15,0xda,0x34,0x7a,0x37,0x35,0x9a,0xa5,0xa5,0x99,0x42,0x40,0x24,0x75,
0x04,0x20,0xdf,0xc0,0xcd,0x6f,0x1d,0xac,0x5d,0xb4,0x3a,0x30,0x5b,0x12,0x99,0xe3,0xe2,0x9c,0x8d,0x9f,0x33,0x0e,0x05,0x24,0x7b,0xc4,0xb0,0x14,0xf8,0xd3,0x01,0x4b,0xf8,0xfe,0x24,0x75,
};

static SeedSpec6 pnSeed6_test[] = {
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x89,0x44,0x8c}, 49333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x96,0x70}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x3b,0x39,0x60}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x27,0x64,0x63,0x74}, 30008},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x73,0x61}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x0d,0x2a,0x7d}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xff,0x80,0x6e}, 19333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xab,0xa1,0xcb}, 19333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe3,0x13,0x5c}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1c,0xe1,0xa0}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x62,0x9f,0x07}, 19333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x26,0x03,0xc7}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x27,0x68,0xa7}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa0,0x9f,0x2d}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4f,0x37,0x1c}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x4c,0xe0}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x64,0x19,0x78,0x9a}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe7,0xbf,0x07}, 19333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xed,0x83,0x8a}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0x5d,0xc6,0x68}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0x87,0x0b,0x7c}, 49333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd1,0x28,0x3d}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd1,0x2a,0x07}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x2e,0xc3}, 19333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb4,0xdd,0xc9}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x66,0x12}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0xee,0xc1,0x0f}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xd8,0x00,0x69}, 19335},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0xae,0xff}, 19335}
static const uint8_t chainparams_seed_test[] = {
0x01,0x04,0x03,0x89,0x44,0x8c,0xc0,0xb5,
0x01,0x04,0x05,0x09,0x96,0x70,0x4b,0x87,
0x01,0x04,0x25,0x3b,0x39,0x60,0x4b,0x87,
0x01,0x04,0x27,0x64,0x63,0x74,0x75,0x38,
0x01,0x04,0x33,0x0f,0x73,0x61,0x4b,0x87,
0x01,0x04,0x34,0x0d,0x2a,0x7d,0x4b,0x87,
0x01,0x04,0x36,0xff,0x80,0x6e,0x4b,0x85,
0x01,0x04,0x3e,0xab,0xa1,0xcb,0x4b,0x85,
0x01,0x04,0x40,0xe3,0x13,0x5c,0x4b,0x87,
0x01,0x04,0x4e,0x1c,0xe1,0xa0,0x4b,0x87,
0x01,0x04,0x4f,0x62,0x9f,0x07,0x4b,0x85,
0x01,0x04,0x54,0x26,0x03,0xc7,0x4b,0x87,
0x01,0x04,0x59,0x27,0x68,0xa7,0x4b,0x87,
0x01,0x04,0x59,0xa0,0x9f,0x2d,0x4b,0x87,
0x01,0x04,0x5e,0x4f,0x37,0x1c,0x4b,0x87,
0x01,0x04,0x5f,0xd8,0x4c,0xe0,0x4b,0x87,
0x01,0x04,0x64,0x19,0x78,0x9a,0x4b,0x87,
0x01,0x04,0x67,0xe7,0xbf,0x07,0x4b,0x85,
0x01,0x04,0x68,0xed,0x83,0x8a,0x4b,0x87,
0x01,0x04,0x8e,0x5d,0xc6,0x68,0x4b,0x87,
0x01,0x04,0x93,0x87,0x0b,0x7c,0xc0,0xb5,
0x01,0x04,0xad,0xd1,0x28,0x3d,0x4b,0x87,
0x01,0x04,0xad,0xd1,0x2a,0x07,0x4b,0x87,
0x01,0x04,0xb2,0x3e,0x2e,0xc3,0x4b,0x85,
0x01,0x04,0xb9,0xb4,0xdd,0xc9,0x4b,0x87,
0x01,0x04,0xc6,0x3a,0x66,0x12,0x4b,0x87,
0x01,0x04,0xca,0xee,0xc1,0x0f,0x4b,0x87,
0x01,0x04,0xcb,0xd8,0x00,0x69,0x4b,0x87,
0x01,0x04,0xd4,0x53,0xae,0xff,0x4b,0x87,
0x04,0x20,0x65,0xd5,0xfa,0xa8,0xb7,0xac,0xc0,0xfd,0x01,0x0a,0x0a,0x60,0x2b,0xfc,0x3c,0x21,0x2f,0xac,0x20,0x06,0xed,0x7b,0x53,0xd1,0x69,0x6d,0x69,0x17,0xe0,0x35,0xe0,0x3d,0x4b,0x87,
0x04,0x20,0x70,0xa6,0xd8,0xfb,0x19,0x33,0xa4,0x8a,0x3e,0x94,0x45,0x4c,0xb0,0x7b,0xef,0xdb,0x17,0xe7,0x8b,0xb0,0x7b,0xb3,0x06,0xff,0x2f,0x63,0xc3,0x73,0x13,0xcf,0x87,0x51,0x4b,0x87,
};
#endif // BITCOIN_CHAINPARAMSSEEDS_H
Loading

0 comments on commit f7b8934

Please sign in to comment.