Technical Spec
This doc aims to help developers understand the internals of BTG (Bitcoin Gold).
It can also provide useful information for 3rd party library / application integration.
Reference: https://github.com/BTCGPU/BTCGPU/issues/331
Changes:
- Fork height: 536200 (accomplished via successful hardfork on July 3rd, 2018, at 9:59:26 PM UTC)
- Switch to Equihash-BTG
- N,K: 144,5 #315
- Personalization string: BgoldPoW #326
- Solution size: 100 bytes
- Typical memory usage for mining: ~2.5G per thread
- Difficulty adjustment: #330
- At the fork height, the difficulty will be reduced to 1/100th
- Subsequent per-block Difficulty adjustments will be made via the LWMA difficulty adjustment algorithm.
- Network protocol version
- Change from
70015
to70016
- Come with the new block header format for Equihash and hard fork.
- Change from
- Network magic
-
mainnet
:[e1 47 6d 44]
-
testnet
:[e2 48 6e 45]
-
- Default p2p port
-
mainnet
: 8338 -
testnet
: 18338
-
- Default RPC port
-
mainnet
: 8332 -
testnet
: 18332
-
- Compact block
- Enabled since
v0.17.1
- Since
v0.15.0.1
, the node will not send out or respond to CMPCTBLOCK commands.
- Enabled since
- DNS Seed
-
mainnet
:- dnsseed.bitcoingold.org
- dnsseed.bitcoingold.dev
- eu-dnsseed.bitcoingold-official.org
-
testnet
:- test-dnsseed.bitcoingold.org
- test-dnsseed.bitcoingold.dev
- eu-test-dnsseed.bitcoingold-official.org
-
Clients MUST adopt the network protocol version, magic and default p2p port. Compact block is OPTIONAL as it's not currently supported by Core client yet. Clients MAY adopt the DNS Seed of Bitcoin Gold in order to find the seed nodes of the P2P network.
Clients in the P2P network are supposed to follow protocol version 70016
(or newer in the future). A client MAY refuse to connect to a peer with older protocol version for simplicity. However, a client SHOULD accept lower protocol version if it's needed to allow simple clients like crawlers.
The block header is compatible with Zcash by design for out-of-box miner software support.
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
uint32_t nHeight;
uint32_t nReserved[7]; // Always be zero
uint32_t nTime;
uint32_t nBits;
uint256 nNonce;
std::vector<unsigned char> nSolution;
- Compared with Bitcoin
- Add field
nHeight
,nReserved
,nSolution
- Extend field
nNonce
from 32 bits to 256 bits- When storing pre-fork blocks, only the lower 32 bits are used
- Add field
- Compared with Zcash
- Utilize the first 4 bytes of Zcash's reserved field to store block height
sizeof(nHeight) + sizeof(nReserved) == sizeof(Zcash.nReserved)
- Utilize the first 4 bytes of Zcash's reserved field to store block height
- Hash calculation
- For post-fork blocks, serialize the full block header and output its double sha256 hash.
- For pre-fork blocks, convert to the regular 80 bytes Bitcoin block header then calculate its double sha256 hash.
Clients MUST adopt the new block header format. Besides the existing block validation rules of Bitcoin, clients MUST validate the Equihash solution and the block height (in nHeight
) for post-fork blocks.
Clients MUST calculate the hash of the block differently for pre-fork and post-fork blocks. However, the block serialization/de-serialization logic falls back to Bitcoin's when talking to a legacy peer (protocol version lower than 70016
) if the client supports legacy peers.
- Equihash PoW change
- Check Equihash solution before the regular double-SHA256 validation for post-fork blocks.
- PR: #15
- After July 2018 hardfork: Equihash-BTG (144,5) with personalization string is used #315, #326
- Difficulty adjustment algorithm
- After July 2018 hardfork: Zawy's LWMA.
- Before: A variant of to DigiShieldV3
- Adjust per block
- Details (
mainnet
&testnet
)- Prefork: same as Bitcoin
- Post fork / Endowment Premine (
491407
to499406
):nPowAveragingWindow = 30
powLimit = 0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
- See also "Hard fork - Premine"
- DigiShieldV3 warm-up period:
- 30 blocks
target = 0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
- Postfork (
499407
): Begin to dynamically adjust target - July 2018 hardfork,
536200
:- Change DAA to LWMA #330
- Averaging window = 45
- Warm-up period:
- 45 blocks
- target = 0.01 * target_last_block
- Code:
chainparams.cpp
,pow.cpp
- First post-fork block:
491407
- Endowment
- 8000 blocks (
491407
to499406
) - Minimal difficulty (difficulty = 1, or bits = powLimit)
- 8000 blocks (
- Coinbase output enforcement in premine period
- Full two-way strong SIGHASH_FORKID replay protection.
- ForkID = 79
- All post-fork transactions follow BIP143 style SIGHASH.
- Legacy signing logic is kept for pre-fork tx validation.
- PR
(A full introduction of transaction signing will be added soon.)
-
mainnet
- Version 38 for P2PKH (base58 prefix “G”)
- Version 23 for P2SH (base58 prefix “A”)
-
testnet
/regtest
is not changed. - Legacy & new addresses are convertible
- PR: #80
- Bech32:
-
btg
formainnet
-
tbtg
fortestnet
- Definition: slip-0173
-
import base58
# btc_addr = '1FpDNrU4dHCDnphJzPMYnGrrmWJHQXrYbM'
version_map = {b'\x00': b'\x26', b'\x05': b'\x17'}
btc_data = base58.b58decode_check(btc_addr)
btg_data = version_map[btc_data[0:1]] + btc_data[1:]
btg_addr = base58.b58encode_check(btg_data)
# assert btg_addr == 'GYf8nyo1c8oWsHzbvL1fD3Ckgg68UzBi5J'
(To be done)
- Json RPC
- getblocktemplate
- getblockheader
- getblock
- submitblock
- getblocksubsidy
- REST