Complete parameter reference for BTCP node operators and developers: network identity, mainnet/testnet/signet/regtest parameters, address encoding, HD key version bytes, genesis block, consensus & emission schedule, 120-block difficulty adjustment algorithm, soft-fork activation, ElectrumX coin definition and Docker patch, Electrum constants.py reference, checkpoints format, Lightning Network chain identification (chain_hash, BOLT11 HRP, block-time-scaled timeout parameters), and bitcoinpurple.conf annotated configuration
44 KiB
BitcoinPurple — Technical Reference
Parameter reference for BitcoinPurple (BTCP) node operators and developers building on top of the network: ElectrumX server, Electrum wallet fork, Lightning Network fork. All values are sourced directly from the codebase unless noted otherwise.
Quick Reference
The most-looked-up values, all in one place.
| Parameter | Mainnet | Testnet | Signet | Regtest |
|---|---|---|---|---|
| P2P port | 13496 |
23496 |
33496 |
18444 |
| RPC port | 13495 |
23495 |
33495 |
18443 |
| ElectrumX TCP | 50001 |
60001 |
— | — |
| ElectrumX SSL | 50002 |
60002 |
— | — |
| Magic bytes | fc991395 |
29fbc5fe |
— | 31346ac9 |
| Bech32 / BOLT11 HRP | btcp |
tbtcp |
tbtcp |
rbtcp |
| P2PKH prefix | 56 (0x38) → P |
56 (0x38) |
56 | 56 |
| P2SH prefix | 55 (0x37) → P |
55 (0x37) |
55 | 55 |
| WIF prefix | 183 (0xb7) |
183 (0xb7) |
183 | 183 |
| BIP32 xpub | 0488B21E |
043587CF |
043587CF |
043587CF |
| BIP32 xprv | 0488ADE4 |
04358394 |
04358394 |
04358394 |
| Block time | 60 s | 60 s | 60 s | instant |
| Halving interval | 500,000 blocks | — | — | 150 blocks |
Monetary cap (MAX_MONEY) |
1,000,000 BTCP | — | — | — |
| Genesis hash | 000003823f…c015 |
000002fdc3…d998 |
00000131aa…b403 |
6f6ffbda…e1df |
| LN chain_hash | 15c04ef0…0000 |
98d9f92e…0000 |
— | — |
1. Network Identity
| Parameter | Value | Source |
|---|---|---|
| Full name | BitcoinPurple | — |
| Ticker | BTCP | — |
| Version | 1.1.1 | configure.ac |
| Daemon binary | bitcoinpurpled |
— |
| Config file | ~/.bitcoinpurple/bitcoinpurple.conf |
— |
| PoW algorithm | SHA256d (identical to Bitcoin) | — |
| Protocol version | 70016 | src/version.h:12 |
| Min peer protocol | 31800 | src/version.h:18 |
2. Mainnet Parameters
2.1 Ports
| Service | Port | Source |
|---|---|---|
| P2P | 13496 |
src/kernel/chainparams.cpp:116 |
| RPC | 13495 |
src/chainparamsbase.cpp:47 |
| Tor onion | 8334 |
src/chainparamsbase.cpp:47 |
2.2 Address Encoding
| Type | Decimal | Hex | Address prefix | Source |
|---|---|---|---|---|
P2PKH (PUBKEY_ADDRESS) |
56 | 0x38 |
P |
src/kernel/chainparams.cpp:154 |
P2SH (SCRIPT_ADDRESS) |
55 | 0x37 |
P |
src/kernel/chainparams.cpp:155 |
| WIF secret key | 183 | 0xb7 |
— | src/kernel/chainparams.cpp:156 |
| Bech32 HRP | — | — | btcp1… |
src/kernel/chainparams.cpp:160 |
2.3 HD Key Version Bytes
BIP32 standard (xpub / xprv):
| Type | Bytes (hex) | Base58 prefix | Source |
|---|---|---|---|
| xpub | 0488B21E |
xpub |
src/kernel/chainparams.cpp:157 |
| xprv | 0488ADE4 |
xprv |
src/kernel/chainparams.cpp:158 |
SLIP-0132 extended headers (all script types):
BTCP uses the same BIP32 root bytes as Bitcoin mainnet, so the registered
SLIP-0132 SegWit version bytes are identical to Bitcoin mainnet. Taproot/BIP86
does not have registered SLIP-0132 trub / trpv headers; use standard
xpub / xprv plus the BIP86 derivation path or descriptors.
XPRV_HEADERS = {
'standard': 0x0488ade4, # xprv
'p2wpkh-p2sh': 0x049d7878, # yprv
'p2wsh-p2sh': 0x0295b005, # Yprv
'p2wpkh': 0x04b2430c, # zprv
'p2wsh': 0x02aa7a99, # Zprv
}
XPUB_HEADERS = {
'standard': 0x0488b21e, # xpub
'p2wpkh-p2sh': 0x049d7cb2, # ypub
'p2wsh-p2sh': 0x0295b43f, # Ypub
'p2wpkh': 0x04b24746, # zpub
'p2wsh': 0x02aa7ed3, # Zpub
}
2.4 Magic Bytes (P2P message header)
fc 99 13 95 — Source: src/kernel/chainparams.cpp:112-115
2.5 Genesis Block
| Parameter | Value | Source |
|---|---|---|
| Hash (display) | 000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015 |
src/kernel/chainparams.cpp:144 |
| LN chain_hash (wire, reversed bytes) | 15c04ef0bc1856d6b1ec199ca25d0aa7e77c6114e2cb0649ea82bf3f82030000 |
derived |
| Merkle root | b5f46757618a0aa2961b23f51de039ef23a77c24decc43d600348aff051f0a05 |
src/kernel/chainparams.cpp:145 |
| Timestamp (Unix) | 1691126832 |
src/kernel/chainparams.cpp:121 |
| Timestamp (UTC) | 2023-08-04T05:27:12Z |
— |
| Nonce | 1302816 (0x13E120) |
src/kernel/chainparams.cpp:121 |
| nBits | 1e0ffff0 |
src/kernel/chainparams.cpp:121 |
| Version | 1 |
src/kernel/chainparams.cpp:121 |
| Coinbase message | "Global transactions for everyone around the world" |
src/kernel/chainparams.cpp:64 |
| Coinbase pubkey | 04f26c8111029cf40de900c7075706cb58e5ed1e7f1d4911790019ee8c345eeb84060b1a09fb655c88e58ff35357ffe28678e62008f759ea260c7c37c9fae23869 |
src/kernel/chainparams.cpp:65 |
2.6 Consensus & Emission
| Parameter | Value | Source |
|---|---|---|
Block time (nPowTargetSpacing) |
60 seconds | src/kernel/chainparams.cpp:88 |
| Difficulty retarget window | 120 blocks (~2 hours) | src/kernel/chainparams.cpp:87-88 |
| PoW target timespan | 7200 seconds | src/kernel/chainparams.cpp:87 |
| PoW limit | 00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff |
src/kernel/chainparams.cpp:86 |
| Halving interval | 500,000 blocks | src/kernel/chainparams.cpp:78 |
| Initial block reward | 1 BTCP | src/validation.cpp:1549 |
| COIN (satoshis per BTCP) | 100,000,000 | src/consensus/amount.h:16 |
| MAX_MONEY validation cap | 1,000,000 BTCP | src/consensus/amount.h:27 |
| Coinbase maturity | 100 blocks | src/consensus/consensus.h:19 |
| Rule change activation threshold | 108 / 120 blocks (90%) | src/kernel/chainparams.cpp:91 |
Block reward schedule (source: src/validation.cpp:1542-1551):
| Era | Block range | Reward | Era total |
|---|---|---|---|
| 0 | 0 – 499,999 | 1.00000000 BTCP | 500,000 BTCP |
| 1 | 500,000 – 999,999 | 0.50000000 BTCP | 250,000 BTCP |
| 2 | 1,000,000 – 1,499,999 | 0.25000000 BTCP | 125,000 BTCP |
| 3 | 1,500,000 – 1,999,999 | 0.12500000 BTCP | 62,500 BTCP |
| ∞ | — | — | ~1,000,000 BTCP generated subsidy |
MAX_MONEY is the consensus money-range sanity cap, not a direct UTXO supply
counter. The genesis coinbase follows the normal 1 BTCP subsidy construction,
but like Bitcoin Core-derived chains it is not spendable from the UTXO set.
For user-facing supply text, distinguish:
- Maximum generated subsidy: asymptotically ~1,000,000 BTCP.
- Maximum spendable subsidy: asymptotically ~999,999 BTCP if the genesis coinbase remains unspendable.
2.7 Difficulty Adjustment
BTCP keeps Bitcoin's compact target / SHA256d proof-of-work validation, but the retarget interval is much shorter:
| Parameter | Mainnet value | Source |
|---|---|---|
| Target spacing | 60 seconds | src/kernel/chainparams.cpp:88 |
| Target timespan | 7,200 seconds | src/kernel/chainparams.cpp:87 |
| Adjustment interval | 120 blocks | nPowTargetTimespan / nPowTargetSpacing |
| Retarget boundary | every block height divisible by 120 | src/pow.cpp:18-47 |
| Minimum actual timespan | 1,800 seconds | src/pow.cpp:56 |
| Maximum actual timespan | 28,800 seconds | src/pow.cpp:58 |
| Max change per retarget | 4x easier or 4x harder | src/pow.cpp:56-66 |
| Mainnet min-difficulty blocks | disabled | fPowAllowMinDifficultyBlocks=false |
| No-retarget mode | disabled | fPowNoRetargeting=false |
Retarget flow for a candidate block at height H:
- If
H % 120 != 0, the block must keep the previous block'snBits. - If
H % 120 == 0, take the previous 120-block window:first = H - 120,last = H - 1. - Compute
actual_timespan = last.time - first.time. - Clamp it to
[7200 / 4, 7200 * 4], i.e.[1800, 28800]seconds. - Decode previous
nBitsto a target, then:
new_target = old_target * actual_timespan / 7200
new_target = min(new_target, powLimit)
new_nBits = compact(new_target)
Interpretation:
- Blocks faster than 60 seconds make
actual_timespan < 7200, so target decreases and difficulty increases. - Blocks slower than 60 seconds make
actual_timespan > 7200, so target increases and difficulty decreases. - The clamp prevents a single retarget from changing difficulty by more than 4x.
2.8 Soft-Fork Activation
All soft-forks are active from genesis (height 0). Source: src/kernel/chainparams.cpp:79-102
| BIP | Feature | Activation height |
|---|---|---|
| BIP34 | Block height in coinbase | 0 |
| BIP65 | CHECKLOCKTIMEVERIFY |
0 |
| BIP66 | Strict DER signatures | 0 |
| BIP68/112/113 | CheckSequenceVerify (CSV) |
0 |
| BIP141/143/147 | SegWit | 0 |
| BIP340-342 | Taproot (ALWAYS_ACTIVE) |
0 |
2.9 Chain Validation
| Parameter | Value | Source |
|---|---|---|
| Minimum chain work | 00000000000000000000000000000000000000000000074e7000dc41ac550926 |
src/kernel/chainparams.cpp:104 |
| Default assume valid | 00000000000009733cf805e87e19261ae833319b874c694d4d74995ea526c968 |
src/kernel/chainparams.cpp:105 |
| Prune after height | 100,000 | src/kernel/chainparams.cpp:117 |
| TX count reference | 1,189,400 at block 1,048,808 | src/kernel/chainparams.cpp:178-184 |
2.10 DNS Seeds
| Seed | Source |
|---|---|
node3.walletbuilders.com |
src/kernel/chainparams.cpp:152 |
3. Testnet Parameters
| Parameter | Value | Source |
|---|---|---|
| P2P port | 23496 |
src/kernel/chainparams.cpp:230 |
| RPC port | 23495 |
src/chainparamsbase.cpp:49 |
| Magic bytes | 29 fb c5 fe |
src/kernel/chainparams.cpp:226-229 |
| Bech32 / BOLT11 HRP | tbtcp |
src/kernel/chainparams.cpp:270 |
| P2PKH | 56 (0x38) |
src/kernel/chainparams.cpp:264 |
| P2SH | 55 (0x37) |
src/kernel/chainparams.cpp:265 |
| WIF prefix | 183 (0xb7) |
src/kernel/chainparams.cpp:266 |
| BIP32 xpub | 043587CF |
src/kernel/chainparams.cpp:267 |
| BIP32 xprv | 04358394 |
src/kernel/chainparams.cpp:268 |
| Genesis hash (display) | 000002fdc3921c1ad368816fcc587f499698d42b42ab5a5d94ee67882ef9d998 |
src/kernel/chainparams.cpp:259 |
| LN chain_hash (wire) | 98d9f92e8867ee945d5aab422bd49896497f58cc6f8168d31a1c92c3fd020000 |
derived |
| Genesis merkle root | b5f46757618a0aa2961b23f51de039ef23a77c24decc43d600348aff051f0a05 |
same as mainnet |
| Genesis timestamp | 1691126837 |
src/kernel/chainparams.cpp:235 |
| Genesis nonce | 521609 (0x7F589) |
src/kernel/chainparams.cpp:235 |
| Genesis nBits | 1e0ffff0 |
src/kernel/chainparams.cpp:235 |
| ElectrumX TCP / SSL | 60001 / 60002 |
coins_btcp.py |
SLIP-0132 HD headers — testnet (identical to Bitcoin testnet, since BIP32 bytes are 043587CF/04358394; Taproot/BIP86 still uses standard tpub / tprv plus path/descriptor metadata):
XPRV_HEADERS = {
'standard': 0x04358394, # tprv
'p2wpkh-p2sh': 0x044a4e28, # uprv
'p2wsh-p2sh': 0x024285b5, # Uprv
'p2wpkh': 0x045f18bc, # vprv
'p2wsh': 0x02575048, # Vprv
}
XPUB_HEADERS = {
'standard': 0x043587cf, # tpub
'p2wpkh-p2sh': 0x044a5262, # upub
'p2wsh-p2sh': 0x024289ef, # Upub
'p2wpkh': 0x045f1cf6, # vpub
'p2wsh': 0x02575483, # Vpub
}
4. Signet Parameters
| Parameter | Value | Source |
|---|---|---|
| P2P port | 33496 |
src/kernel/chainparams.cpp:375 |
| RPC port | 33495 |
src/chainparamsbase.cpp:51 |
| Bech32 HRP | tbtcp |
src/kernel/chainparams.cpp:412 |
| P2PKH / P2SH / WIF | 56 / 55 / 183 | src/kernel/chainparams.cpp:406-408 |
| BIP32 xpub / xprv | 043587CF / 04358394 |
src/kernel/chainparams.cpp:409-410 |
| Genesis hash | 00000131aa3124412b7ba8473f137922692c88da8fe26042e250c6cd76b7b403 |
src/kernel/chainparams.cpp:402 |
| Genesis timestamp | 1691126842 |
src/kernel/chainparams.cpp:378 |
| Genesis nonce | 1829993 (0x1be0a9) |
src/kernel/chainparams.cpp:378 |
| Genesis nBits | 1e0377ae |
src/kernel/chainparams.cpp:378 |
| PoW limit | 00000377ae000000000000000000000000000000000000000000000000000000 |
src/kernel/chainparams.cpp:350 |
| Default signet challenge | 512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae |
src/kernel/chainparams.cpp:308 |
5. Regtest Parameters
| Parameter | Value | Source |
|---|---|---|
| P2P port | 18444 |
src/kernel/chainparams.cpp:466 |
| RPC port | 18443 |
src/chainparamsbase.cpp:53 |
| Magic bytes | 31 34 6a c9 |
src/kernel/chainparams.cpp:462-465 |
| Bech32 HRP | rbtcp |
src/kernel/chainparams.cpp:556 |
| P2PKH / P2SH / WIF | 56 / 55 / 183 | src/kernel/chainparams.cpp:550-552 |
| BIP32 xpub / xprv | 043587CF / 04358394 |
src/kernel/chainparams.cpp:553-554 |
| Genesis hash | 6f6ffbda4cb789c69d885d4624ea4a28841d3689fbaf969262150ca45a1ae1df |
src/kernel/chainparams.cpp:521 |
| Genesis timestamp | 1691126837 |
src/kernel/chainparams.cpp:497 |
| Genesis nonce | 4 |
src/kernel/chainparams.cpp:497 |
| Genesis nBits | 207fffff |
src/kernel/chainparams.cpp:497 |
| Halving interval | 150 blocks | src/kernel/chainparams.cpp:433 |
| No retargeting | true |
src/kernel/chainparams.cpp:440 |
6. ElectrumX Server
6.1 Coin Definition (coins_btcp.py)
Drop-in patch for electrumx/lib/coins.py. Place as
electrumx-patch/coins_btcp.py and apply via the Docker patch snippet below.
# coins_btcp.py — BitcoinPurple (BTCP) coin definitions for ElectrumX
# Patch into electrumx/lib/coins.py alongside the Bitcoin class.
class BitcoinPurple(Bitcoin):
NAME = 'BitcoinPurple'
SHORTNAME = 'BTCP'
NET = 'mainnet'
DESERIALIZER = lib_tx.DeserializerSegWit
GENESIS_HASH = (
'000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015'
)
# Base58 address prefixes
P2PKH_VERBYTE = bytes([56]) # 0x38
P2SH_VERBYTES = (bytes([55]),) # 0x37
WIF_BYTE = bytes([183]) # 0xb7
# BIP32 HD key version bytes
XPUB_VERBYTES = bytes.fromhex('0488B21E')
XPRV_VERBYTES = bytes.fromhex('0488ADE4')
# Bech32 / SegWit metadata for forks; ElectrumX indexes scripts directly.
SEGWIT_HRP = 'btcp'
# Do not inherit Bitcoin Electrum peers or Bitcoin Core version gates.
PEERS = []
MIN_REQUIRED_DAEMON_VERSION = '1.1.1'
BLACKLIST_URL = None
# 1-minute blocks: keep enough undo data for practical reorg handling.
REORG_LIMIT = 1200
# Chain stats — updated from fully synced mainnet node at block 1,048,808 (Apr 2026)
TX_COUNT = 1_189_400
TX_COUNT_HEIGHT = 1_048_808
TX_PER_BLOCK = 2
# RPC port (bitcoinpurpled mainnet default)
RPC_PORT = 13495
PEER_DEFAULT_PORTS = {'t': '50001', 's': '50002'}
class BitcoinPurpleTestnet(BitcoinPurple):
NAME = 'BitcoinPurple Testnet'
SHORTNAME = 'TBTCP'
NET = 'testnet'
GENESIS_HASH = (
'000002fdc3921c1ad368816fcc587f499698d42b42ab5a5d94ee67882ef9d998'
)
XPUB_VERBYTES = bytes.fromhex('043587CF')
XPRV_VERBYTES = bytes.fromhex('04358394')
SEGWIT_HRP = 'tbtcp'
TX_COUNT = 1
TX_COUNT_HEIGHT = 0
TX_PER_BLOCK = 1
RPC_PORT = 23495
PEERS = []
REORG_LIMIT = 1200
PEER_DEFAULT_PORTS = {'t': '60001', 's': '60002'}
Notes for this coin class:
PEERS = []is intentional until there are known-good BTCP ElectrumX peers. ElectrumX peer discovery verifies genesis, but inheriting Bitcoin peers wastes resources and can leak confusing peer data.MIN_REQUIRED_DAEMON_VERSIONmust not inherit Bitcoin's current upstream requirement. Keep it aligned with the BTCP daemon version you ship, or remove the version gate in your ElectrumX fork.TX_COUNT,TX_COUNT_HEIGHT, andTX_PER_BLOCKare sync-estimation hints, not consensus values. Refresh them from a synced BTCP node before release.- ElectrumX does not need ZMQ to index; it polls RPC. ZMQ is useful for lower latency only if your chosen ElectrumX build/plugin uses it.
6.1.1 ElectrumX Node Requirements
Required full-node settings:
| Requirement | Value / setting | Reason |
|---|---|---|
| RPC server | server=1, rpcport=13495 |
ElectrumX reads blocks and transactions through JSON-RPC |
| Transaction index | txindex=1 |
Required for historical transaction lookups |
| Pruning | disabled (prune=0) |
ElectrumX must be able to index from genesis |
| Chain | mainnet unless NET=testnet |
Must match COIN/NET in ElectrumX |
| Disk | full block data + ElectrumX DB | DB grows with history; do not run from a tiny volume |
Minimum RPC methods used by ElectrumX-compatible servers include
getblockhash, getblock, getrawtransaction, getnetworkinfo,
getblockchaininfo, estimatesmartfee, and sendrawtransaction.
Recommended public Electrum services:
| Service | Mainnet | Testnet | Notes |
|---|---|---|---|
| Plain TCP | 50001 |
60001 |
Standard Electrum convention |
| TLS/SSL TCP | 50002 |
60002 |
Recommended for public wallets |
| Local admin RPC | 8000 |
8000 or private |
Keep firewalled; do not advertise publicly |
For servers.json, replace your-server.example.com with a real DNS name or
public IP. The current file only documents the format; it does not configure a
real public server.
6.2 Docker Patch Snippet
COPY electrumx-patch/coins_btcp.py /tmp/coins_btcp.py
RUN python3 - <<'PATCH'
import pathlib, re
patch = pathlib.Path('/tmp/coins_btcp.py').read_text()
classes = re.split(r'^(?=class )', patch, flags=re.MULTILINE)
classes = [c for c in classes if c.strip().startswith('class ')]
body = '\n' + '\n'.join(classes)
for target in [
'/usr/local/lib/python3.13/dist-packages/electrumx/lib/coins.py',
'/electrumx/src/electrumx/lib/coins.py',
]:
p = pathlib.Path(target)
if p.exists():
s = p.read_text()
if 'class BitcoinPurple(Bitcoin):' not in s:
p.write_text(s + body)
print('>> Patched ElectrumX with BitcoinPurple coin classes')
PATCH
6.3 Environment Variables
# ── Identity ──────────────────────────────────────────────────────────────────
COIN=BitcoinPurple
NET=mainnet # or: testnet
# ── Node connection ───────────────────────────────────────────────────────────
DAEMON_URL=http://btcpuser:CHANGE_ME@bitcoinpurpled:13495/
# testnet: DAEMON_URL=http://btcpuser:CHANGE_ME@bitcoinpurpled:23495/
# ── Storage ───────────────────────────────────────────────────────────────────
DB_DIRECTORY=/data/electrumx
# ── Services exposed ──────────────────────────────────────────────────────────
SERVICES=tcp://0.0.0.0:50001,ssl://0.0.0.0:50002,rpc://0.0.0.0:8000
# Override only if auto-detected public IP is wrong:
# REPORT_SERVICES=tcp://your-server-ip:50001,ssl://your-server-ip:50002
# ── TLS ───────────────────────────────────────────────────────────────────────
SSL_CERTFILE=/certs/server.crt
SSL_KEYFILE=/certs/server.key
# ── Performance ───────────────────────────────────────────────────────────────
CACHE_MB=1200
MAX_SESSIONS=1000
INITIAL_CONCURRENT=2
# ── Rate limiting (0 = disabled) ─────────────────────────────────────────────
COST_SOFT_LIMIT=0
COST_HARD_LIMIT=0
# ── Peer discovery ────────────────────────────────────────────────────────────
PEER_DISCOVERY=on
PEER_ANNOUNCE=true
Protocol version served: 1.4.2
OS ulimit — set nofile to at least 1048576 (open file descriptors):
ulimits:
nofile:
soft: 1048576
hard: 1048576
6.4 ZMQ Notification Ports
These are recommended local ports if you enable ZMQ notifications. BitcoinPurple
Core does not assign default ZMQ bind ports; the port only exists if you set the
corresponding bitcoinpurple.conf value.
bitcoinpurple.conf key |
Recommended local port | Payload |
|---|---|---|
zmqpubrawblock |
28332 |
full serialised block |
zmqpubrawtx |
28333 |
raw transaction (mempool + confirmed) |
zmqpubhashblock |
28334 |
32-byte block hash |
zmqpubhashtx |
28335 |
32-byte tx hash |
Prevent dropped messages under load:
zmqpubrawblockhwm=500
zmqpubrawtxhwm=500
7. Electrum Wallet (constants.py)
Reference for building an Electrum wallet fork targeting BTCP.
Modelled after the AbstractNet interface (see pallectrum for a working example).
7.1 Parameter Table
| Field | Mainnet | Testnet | Source / Note |
|---|---|---|---|
NET_NAME |
"bitcoinpurple" |
"testnet" |
wallet data subfolder |
TESTNET |
False |
True |
|
WIF_PREFIX |
0xb7 (183) |
0xb7 (183) |
same on both — chainparams.cpp:156/266 |
ADDRTYPE_P2PKH |
56 |
56 |
addresses start with P |
ADDRTYPE_P2SH |
55 |
55 |
addresses start with P |
SEGWIT_HRP |
"btcp" |
"tbtcp" |
Bech32 human-readable part |
BOLT11_HRP |
"btcp" |
"tbtcp" |
LN invoice prefix |
GENESIS |
000003823f…c015 |
000002fdc3…d998 |
full hashes in §2.5 / §3 |
DEFAULT_PORTS |
{'t':'50001','s':'50002'} |
{'t':'60001','s':'60002'} |
|
BIP44_COIN_TYPE |
TBD / private project constant | 1 |
not registered for BitcoinPurple — see note |
LN_REALM_BYTE |
0 |
1 |
LN DNS realm byte; unused while LN_DNS_SEEDS=[] |
LN_DNS_SEEDS |
[] |
[] |
no LN seeds configured |
SKIP_POW_DIFFICULTY_VALIDATION |
False only after BTCP retarget support |
False only after BTCP retarget support |
see §7.7 |
POW_TARGET_SPACING |
60 |
60 |
seconds per block |
COINBASE_MATURITY |
100 |
100 |
blocks before coinbase is spendable |
BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS |
0 |
0 |
allowed from genesis if LN is enabled |
BIP44 coin type: BitcoinPurple has no SLIP-0044 entry.
BTCPat index183is already assigned to Bitcoin Private, so do not reuse it for BitcoinPurple. In Electrum constants, store the non-hardened index (0 <= value < 0x80000000); wallet derivation code adds the hardened bit when building paths such asm/44'/COIN_TYPE'/0'. Use one project-wide provisional integer until an official SLIP-0044 slot is registered. The13496value below is a project-local placeholder chosen to match the BTCP P2P port, not a registered SLIP-0044 value.
7.2 constants.py Class Definitions
# constants.py — BitcoinPurple network definitions for an Electrum wallet fork
# Drop these classes into electrum/constants.py alongside BitcoinMainnet.
class BitcoinPurple(AbstractNet):
NET_NAME = "bitcoinpurple"
TESTNET = False
# Address & key encoding
WIF_PREFIX = 0xb7 # 183 — chainparams.cpp:156
ADDRTYPE_P2PKH = 56 # 0x38 — chainparams.cpp:154
ADDRTYPE_P2SH = 55 # 0x37 — chainparams.cpp:155
SEGWIT_HRP = "btcp" # chainparams.cpp:160
BOLT11_HRP = SEGWIT_HRP
GENESIS = "000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015"
DEFAULT_PORTS = {'t': '50001', 's': '50002'}
# Consensus
COINBASE_MATURITY = 100 # consensus/consensus.h:19
POW_TARGET_SPACING = 60 # 60-second blocks
# BIP44 coin type — not registered in SLIP-0044
BIP44_COIN_TYPE = 13496 # provisional private constant; update when registered
# Lightning. Height 0 means "allowed from genesis" in Electrum.
BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS = 0
LN_REALM_BYTE = 0
LN_DNS_SEEDS = []
# PoW validation — requires BTCP's 120-block retarget implementation.
SKIP_POW_DIFFICULTY_VALIDATION = False
# SLIP-0132 HD key version bytes — identical to Bitcoin mainnet
# BTCP mainnet uses the same BIP32 root bytes: 0488B21E / 0488ADE4
XPRV_HEADERS = {
'standard': 0x0488ade4, # xprv
'p2wpkh-p2sh': 0x049d7878, # yprv
'p2wsh-p2sh': 0x0295b005, # Yprv
'p2wpkh': 0x04b2430c, # zprv
'p2wsh': 0x02aa7a99, # Zprv
}
XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
XPUB_HEADERS = {
'standard': 0x0488b21e, # xpub
'p2wpkh-p2sh': 0x049d7cb2, # ypub
'p2wsh-p2sh': 0x0295b43f, # Ypub
'p2wpkh': 0x04b24746, # zpub
'p2wsh': 0x02aa7ed3, # Zpub
}
XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
class BitcoinPurpleTestnet(BitcoinPurple):
NET_NAME = "testnet"
TESTNET = True
# Testnet uses the same address/WIF prefixes as mainnet (see chainparams)
WIF_PREFIX = 0xb7 # chainparams.cpp:266
ADDRTYPE_P2PKH = 56 # chainparams.cpp:264
ADDRTYPE_P2SH = 55 # chainparams.cpp:265
SEGWIT_HRP = "tbtcp" # chainparams.cpp:270
BOLT11_HRP = SEGWIT_HRP
GENESIS = "000002fdc3921c1ad368816fcc587f499698d42b42ab5a5d94ee67882ef9d998"
DEFAULT_PORTS = {'t': '60001', 's': '60002'}
BIP44_COIN_TYPE = 1 # standard testnet coin type
LN_REALM_BYTE = 1
# SLIP-0132 — standard Bitcoin testnet values (BIP32 root: 043587CF / 04358394)
XPRV_HEADERS = {
'standard': 0x04358394, # tprv
'p2wpkh-p2sh': 0x044a4e28, # uprv
'p2wsh-p2sh': 0x024285b5, # Uprv
'p2wpkh': 0x045f18bc, # vprv
'p2wsh': 0x02575048, # Vprv
}
XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
XPUB_HEADERS = {
'standard': 0x043587cf, # tpub
'p2wpkh-p2sh': 0x044a5262, # upub
'p2wsh-p2sh': 0x024289ef, # Upub
'p2wpkh': 0x045f1cf6, # vpub
'p2wsh': 0x02575483, # Vpub
}
XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
7.3 Derivation Paths (BIP44 / 49 / 84 / 86)
Standard HD paths for each script type. Replace COIN_TYPE with the registered
value (TBD — see §7.1 note).
| BIP | Script type | Path template | xpub/xprv prefix |
|---|---|---|---|
| BIP44 | P2PKH (legacy) | m/44'/COIN_TYPE'/0'/0/n |
xpub / xprv |
| BIP49 | P2WPKH-P2SH (wrapped SegWit) | m/49'/COIN_TYPE'/0'/0/n |
ypub / yprv |
| BIP84 | P2WPKH (native SegWit) | m/84'/COIN_TYPE'/0'/0/n |
zpub / zprv |
| BIP86 | P2TR (Taproot) | m/86'/COIN_TYPE'/0'/0/n |
xpub / xprv or descriptors |
ACCOUNT=0'(first account, hardened)CHANGE=0(receive) or1(change)INDEX= address index (unhardened)
7.4 Checkpoints (checkpoints.json)
Electrum uses checkpoints for SPV header chain verification.
The file lives at electrum/chains/bitcoinpurple/checkpoints.json.
Format: a JSON array of [header_hash_hex, accumulated_work_int] pairs,
one entry per 2016-block chunk. Chunk n covers blocks n*2016 to (n+1)*2016-1.
[
[
"000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015",
1048592
]
]
The first entry (chunk 0) is the genesis block hash with its accumulated PoW work
(0x00000000000000000000000000000000000000000000074e7000dc41ac550926 — from nMinimumChainWork in chainparams.cpp:104, updated at block 1,048,808).
To generate a full checkpoints.json from a running node:
import json, subprocess, math
def get_header(height):
h = subprocess.check_output(
['bitcoinpurple-cli', 'getblockhash', str(height)]).decode().strip()
return subprocess.check_output(
['bitcoinpurple-cli', 'getblockheader', h, 'true']).decode()
checkpoints = []
tip = int(subprocess.check_output(
['bitcoinpurple-cli', 'getblockcount']).decode().strip())
for chunk in range(tip // 2016 + 1):
height = chunk * 2016
import json as _j
header = _j.loads(get_header(height))
checkpoints.append([header['hash'], int(header['chainwork'], 16)])
print(json.dumps(checkpoints, indent=2))
7.5 servers.json Format
Place at electrum/chains/bitcoinpurple/servers.json (mainnet)
and electrum/chains/testnet/servers.json (testnet).
{
"your-server.example.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4.2"
}
}
| Field | Meaning |
|---|---|
| key | hostname or IP of the ElectrumX server |
"pruning" |
"-" = full node; a number = pruned at that height |
"s" |
SSL port |
"t" |
TCP plain port |
"version" |
minimum Electrum protocol version required |
7.6 Dust Thresholds
Minimum output values below which an output is considered "dust" and non-standard. These are the same as Bitcoin since BTCP uses identical script formats.
| Script type | Dust limit | Policy fee rate |
|---|---|---|
| P2PKH | 546 sat | DUST_RELAY_TX_FEE = 3000 sat/kvB (src/policy/policy.h:55) |
| P2WPKH (native SegWit) | 294 sat | same |
| P2WSH | 330 sat | same |
| P2TR (Taproot) | 294 sat | same |
OP_RETURN |
0 (unspendable) | max 83 bytes (src/script/standard.h:34) |
7.7 Electrum Header Verification
Do not reuse Bitcoin's 2016-block difficulty verification logic unchanged. BTCP uses Bitcoin-style compact targets and double-SHA256 proof-of-work, but retargets every 120 blocks with a 7,200 second target timespan.
Wallet constants / chain-verifier values:
POW_LIMIT = int(
"00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16
)
TARGET_SPACING = 60
TARGET_TIMESPAN = 120 * 60
DIFFICULTY_ADJUSTMENT_INTERVAL = 120
MAX_ADJUSTMENT_FACTOR = 4
Header validation must perform:
- Verify
double_sha256(header) <= target_from_nbits(header.bits). - Verify target is
> 0and<= POW_LIMIT. - If
height % 120 != 0, requireheader.bits == previous.bits. - If
height % 120 == 0, compute expectedbitsfrom the previous 120-block window using the §2.7 formula. - Verify each header links to the previous header hash.
- Use
GENESISto anchor the chain andcheckpoints.jsonto accelerate SPV verification.
If the Electrum fork does not yet implement BTCP's 120-block retarget logic,
set SKIP_POW_DIFFICULTY_VALIDATION = True temporarily for development only.
Do not ship a production wallet with difficulty validation disabled.
7.8 Electrum Wallet Build Checklist
Files that must be added or changed in an Electrum fork:
| File / area | Required BTCP change |
|---|---|
electrum/constants.py |
Add BitcoinPurple and BitcoinPurpleTestnet classes |
electrum/chains/bitcoinpurple/servers.json |
Add real ElectrumX host(s), ports 50001 / 50002 |
electrum/chains/bitcoinpurple/checkpoints.json |
Generate from a synced BTCP node |
| header chain verifier | Use 120-block retarget and BTCP powLimit |
| address module | Accept Base58 versions 56/55 and Bech32 HRP btcp |
| transaction/wallet formats | Use BTCP provisional BIP44 coin type consistently |
| Lightning invoice parser | Accept lnbtcp / lntbtcp BOLT11 prefixes if LN is enabled |
| UI/network selector | Expose BitcoinPurple mainnet/testnet names and datadirs |
8. Lightning Network
This section documents the chain-specific parameters required to build or fork a Lightning Network implementation for BTCP. General BOLT protocol behaviour (onion routing, payment flow, gossip) is identical to Bitcoin LN.
8.1 Chain Identification
In BOLT1, every message that references a specific chain carries a chain_hash.
This is the genesis block hash in wire byte order (i.e. the display hex reversed byte-by-byte).
| Network | Genesis hash (display) | chain_hash (BOLT1 wire) |
|---|---|---|
| Mainnet | 000003823fbf82ea…c015 |
15c04ef0bc1856d6b1ec199ca25d0aa7e77c6114e2cb0649ea82bf3f82030000 |
| Testnet | 000002fdc3921c1a…d998 |
98d9f92e8867ee945d5aab422bd49896497f58cc6f8168d31a1c92c3fd020000 |
The chain_hash appears in channel-establishment, channel-gossip, and gossip-query
messages such as open_channel, accept_channel, funding_created,
channel_announcement, channel_update, query_channel_range, and
reply_channel_range. BOLT11 invoices do not normally carry chain_hash; their
network is selected by the invoice HRP.
8.2 BOLT11 Invoice Prefix
| Network | HRP | Example invoice start |
|---|---|---|
| Mainnet | btcp |
lnbtcp1… |
| Testnet | tbtcp |
lntbtcp1… |
Amount suffix multipliers (same as Bitcoin):
| Multiplier | Value |
|---|---|
m |
0.001 BTCP (100,000 sat) |
u |
0.000001 BTCP (100 sat) |
n |
0.000000001 BTCP (0.1 sat) |
p |
0.000000000001 BTCP (0.0001 sat) |
8.3 Block-Time-Scaled Timeout Parameters
This is the most critical section for LN on BTCP.
BTCP has 1-minute blocks (vs Bitcoin's 10-minute blocks). All LN timeout parameters expressed in blocks must be scaled by ×10 to achieve the same real-world security windows as Bitcoin LN. Failure to do this results in dangerously short penalty and payment expiry windows.
| Parameter | Source type | Bitcoin common default | BTCP recommended (1 min/block) | Real-world time |
|---|---|---|---|---|
to_self_delay (justice window) |
implementation policy | 144 blocks | 1440 blocks | ~24 hours |
cltv_expiry_delta per routing hop |
implementation policy / BOLT7 field | 40 blocks | 400 blocks | ~6.7 hours |
min_final_cltv_expiry_delta (last hop) |
implementation policy / BOLT11 field | 9 blocks | 90 blocks | ~90 minutes |
maximum remote to_self_delay accepted |
BOLT2 policy limit | 2016 blocks | 20160 blocks | ~14 days |
max_cltv_expiry (max payment timeout) |
implementation policy | 2016 blocks | 20160 blocks | ~14 days |
| Channel funding confirmation target | best practice | 3–6 blocks | 30–60 blocks | ~30–60 minutes |
Why this matters: if a remote party broadcasts a revoked commitment transaction, your node has until
to_self_delayblocks to publish the penalty transaction. With 1-min blocks and Bitcoin's default of 144, you would have only 2.4 hours. Using the recommended 1440 gives a full 24 hours — the same window as Bitcoin.
8.4 Channel Parameters
These match Bitcoin LN defaults and do not need to change for BTCP.
| Parameter | Value | Note |
|---|---|---|
dust_limit_satoshis |
354 sat (P2WPKH anchor) or 546 sat (legacy) | minimum output in commitment tx |
max_htlc_value_in_flight_msat |
0 (unlimited) or % of capacity | channel-operator choice |
max_accepted_htlcs |
483 | BOLT3 protocol maximum (script complexity limit) |
htlc_minimum_msat |
1 msat | minimum HTLC size |
channel_reserve_satoshis |
~1% of channel capacity (min 1000 sat) | reserves the counterparty cannot spend |
fee_base_msat |
1000 (1 sat) | routing fee base |
fee_proportional_millionths |
1 (0.0001%) | routing fee rate |
feerate_per_kw |
node-determined | initial commitment transaction fee rate |
8.5 Feature Bits (BOLT1 init)
LN feature bits are chain-agnostic; BTCP uses the same bit assignments as Bitcoin LN.
| Feature | Bit pair | Status |
|---|---|---|
var_onion_optin |
8/9 | mandatory |
option_static_remotekey |
12/13 | mandatory |
payment_secret |
14/15 | mandatory |
basic_mpp (multi-part payments) |
16/17 | optional |
option_anchors_zero_fee_htlc_tx |
22/23 | optional (preferred over legacy anchors) |
option_scid_alias |
46/47 | optional |
option_zero_conf |
50/51 | optional |
8.6 Shared Implementation Fork Notes
All major LN implementations (LND, CLN, Eclair, LDK) hardcode Bitcoin's chain hash. Forking any of them for BTCP requires at minimum:
- Replace the genesis hash / chain_hash constant with the BTCP value (§8.1)
- Replace the BOLT11 invoice HRP with
btcp(§8.2) - Update all block-count-based timeout defaults (§8.3)
- Point the Bitcoin RPC backend to
bitcoinpurpledon port13495 - Update the network / bech32 address validation to accept
btcp1…addresses
Also update any constants derived from Bitcoin's 10-minute block cadence: confirmation targets, fee-estimation targets, CLTV deltas, wallet rescan lookbacks, channel announcement depth policy, and watchtower/penalty windows.
8.7 Core Lightning (CLN) Fork Parameters
Core Lightning is Bitcoin-specific upstream. A BTCP fork needs a new chain
definition or equivalent patches wherever CLN selects bitcoin, testnet,
signet, or regtest.
| Area | BTCP mainnet value / action |
|---|---|
| Network name | add bitcoinpurple / btcp network selector |
| Chain hash | 15c04ef0bc1856d6b1ec199ca25d0aa7e77c6114e2cb0649ea82bf3f82030000 |
| On-chain RPC backend | bitcoinpurple-cli / bitcoinpurpled RPC on 127.0.0.1:13495 |
| Bech32 address HRP | btcp |
| BOLT11 HRP | btcp (lnbtcp...) |
| Native unit | 1 BTCP = 100,000,000 sat; 1 sat = 1,000 msat |
| Genesis display hash | 000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015 |
| P2P gossip chain filter | accept only BTCP chain_hash |
| Fee estimates | call BTCP daemon estimatesmartfee; scale targets for 1-minute blocks |
| Confirmation policy | use 30-60 blocks where you want Bitcoin-like 30-60 minute confidence |
| Timeout defaults | use §8.3 scaled block counts |
| DNS bootstrap | empty until BTCP LN seed infrastructure exists |
CLN does not require Bitcoin Core ZMQ or txindex=1 for normal operation; it
polls the backend over RPC. If CLN and ElectrumX share one bitcoinpurpled,
increase rpcworkqueue and monitor RPC latency.
8.8 LND Fork Parameters
LND uses btcsuite chain parameters and Bitcoin-specific network selection. A BTCP
fork needs equivalent new chaincfg / chain registry parameters.
| Area | BTCP mainnet value / action |
|---|---|
| Chain registry | add BitcoinPurple params instead of chaincfg.MainNetParams |
| RPC backend | bitcoind-style backend pointed to bitcoinpurpled:13495 |
| ZMQ raw block | bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 if using ZMQ |
| ZMQ raw tx | bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 if using ZMQ |
| Address params | P2PKH 56, P2SH 55, Bech32 btcp, WIF 183 |
| Chain hash | same §8.1 wire value |
| Invoice HRP | btcp |
| Coin type | use the same provisional Electrum value until SLIP-0044 registration |
| Timeout defaults | use §8.3 scaled block counts |
| Fee estimator | ensure targets are interpreted as 1-minute BTCP blocks |
Unlike ElectrumX, LND normally benefits from ZMQ for prompt block/transaction notifications. If ZMQ is omitted, use the implementation's RPC polling mode and expect higher latency.
8.9 Lightning Difficulty / Block Cadence Implications
LN implementations do not recalculate proof-of-work difficulty themselves for
normal operation; the full node validates blocks. The LN daemon consumes validated
block headers/blocks from bitcoinpurpled and uses block heights for timeouts.
What must still be changed in LN code:
- Treat one BTCP block as ~60 seconds when converting user-facing time windows to block counts.
- Use BTCP's
chain_hasheverywhere gossip or channel messages identify a chain. - Use BTCP's address and BOLT11 HRPs for invoices, fallback addresses, and on-chain outputs.
- Do not connect to Bitcoin LN peers or DNS seeds; BTCP LN needs its own network graph and bootstrap peers.
9. bitcoinpurple.conf Reference
9.1 Default Values
| Parameter | Default | Source |
|---|---|---|
dbcache |
450 MiB | src/txdb.h:30 |
maxmempool |
300 MB | src/kernel/mempool_options.h:20 |
mempoolexpiry |
336 h (14 days) | src/kernel/mempool_options.h:24 |
blockmaxweight |
3,996,000 wu | src/policy/policy.h:23 |
rpcthreads |
4 | src/httpserver.h:12 |
rpcworkqueue |
16 | src/httpserver.h:13 |
rpcservertimeout |
30 s | src/httpserver.h:14 |
maxconnections |
125 | src/net.h |
9.2 Full Annotated Config
##############################################################################
# bitcoinpurple.conf — full node + solo mining + ElectrumX backend
# Location: ~/.bitcoinpurple/bitcoinpurple.conf
##############################################################################
# ── Network ──────────────────────────────────────────────────────────────────
# mainnet by default; uncomment for testnet
#testnet=1
listen=1
maxconnections=125
# addnode=node3.walletbuilders.com
# ── Chain & Indexes ───────────────────────────────────────────────────────────
# txindex=1 is REQUIRED by ElectrumX — incompatible with prune
txindex=1
# blockfilterindex=1 # optional: BIP157/158 compact filters for light clients
# prune=0 # never prune when txindex=1
# ── Performance ───────────────────────────────────────────────────────────────
dbcache=450 # MiB (default: 450; raise on high-RAM machines)
maxmempool=300 # MB (default: 300)
mempoolexpiry=336 # hours before unconfirmed txs are evicted (default: 336 = 14 days)
# ── RPC Server (required by ElectrumX) ───────────────────────────────────────
server=1
rpcport=13495
rpcbind=127.0.0.1
rpcallowip=127.0.0.1 # set to container subnet when ElectrumX is in Docker
rpcuser=btcpuser
rpcpassword=CHANGE_ME_USE_STRONG_PASSWORD
rpcthreads=4
rpcworkqueue=64 # raised from default 16 for ElectrumX parallel RPC calls
rpcservertimeout=30
# ── ZMQ Notifications (optional real-time updates) ───────────────────────────
zmqpubrawblock=tcp://127.0.0.1:28332
zmqpubrawtx=tcp://127.0.0.1:28333
zmqpubhashblock=tcp://127.0.0.1:28334
zmqpubhashtx=tcp://127.0.0.1:28335
zmqpubrawblockhwm=500
zmqpubrawtxhwm=500
zmqpubhashblockhwm=500
zmqpubhashtxhwm=500
# ── Mining ────────────────────────────────────────────────────────────────────
# MAX_BLOCK_WEIGHT = 4,000,000 wu (consensus/consensus.h:15)
blockmaxweight=3996000
blockmintxfee=0.00001
# blocknotify=/usr/local/bin/notify_new_block.sh %s
# ── Wallet (disable if mining to an external address via getblocktemplate) ───
# disablewallet=1
9.3 Notes
txindex=1andpruneare mutually exclusive. ElectrumX requirestxindex=1.- ZMQ requires
--enable-zmqat build time. Verify:bitcoinpurple-cli getnetworkinfo | grep zmq. ElectrumX can index through RPC polling; LND-style backends usually use ZMQ for low-latency block/tx notifications. - Solo mining via
getblocktemplate(BIP22): point your miner tohttp://btcpuser:CHANGE_ME@127.0.0.1:13495. - Docker networking: set
rpcallowipto the container subnet (e.g.172.17.0.0/16) when ElectrumX runs in a separate container. - LN node: the LN daemon also connects to
bitcoinpurpledvia RPC. Setrpcworkqueuehigh enough (128+) if both ElectrumX and an LN node share the same node instance.
9.4 Minimal ElectrumX env (standalone / non-Docker)
COIN=BitcoinPurple
NET=mainnet
DAEMON_URL=http://btcpuser:CHANGE_ME@127.0.0.1:13495/
DB_DIRECTORY=/data/electrumx
SERVICES=tcp://0.0.0.0:50001,ssl://0.0.0.0:50002,rpc://0.0.0.0:8000
REPORT_SERVICES=tcp://YOUR_PUBLIC_IP:50001,ssl://YOUR_PUBLIC_IP:50002
SSL_CERTFILE=/certs/server.crt
SSL_KEYFILE=/certs/server.key
CACHE_MB=1200
MAX_SESSIONS=1000
INITIAL_CONCURRENT=2
COST_SOFT_LIMIT=0
COST_HARD_LIMIT=0
PEER_DISCOVERY=on
PEER_ANNOUNCE=true