Skip to content

Technical Spec

h4x3rotab edited this page Nov 14, 2019 · 19 revisions

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.

Update 2018-08-01: PoW hardfork upgrade

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

  • Network protocol version
    • Change from 70015 to 70016
    • Come with the new block header format for Equihash and hard fork.
  • 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.
  • 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.

Block header

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
  • Compared with Zcash
    • Utilize the first 4 bytes of Zcash's reserved field to store block height
      • sizeof(nHeight) + sizeof(nReserved) == sizeof(Zcash.nReserved)
  • 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.

Consensus

  • 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 to 499406):
        • 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

Hard fork

  • First post-fork block: 491407
  • Endowment
    • 8000 blocks (491407 to 499406)
    • Minimal difficulty (difficulty = 1, or bits = powLimit)
  • Coinbase output enforcement in premine period
    • 4-of-6 mult-sig wallet
    • Endowment coins are time-locked
      • 40% no time-lock
      • 60% time-locked, will be unlocked monthly in 3 years.
    • PR: #162, #168

Replay protection

  • 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
    • Implementation: #109
    • BIP143 SIGHASH: #150

(A full introduction of transaction signing will be added soon.)

Unique address format

  • 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 for mainnet
    • tbtg for testnet
    • Definition: slip-0173

Python conversion example

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'

RPC

(To be done)

  • Json RPC
    • getblocktemplate
    • getblockheader
    • getblock
    • submitblock
    • getblocksubsidy
  • REST

Misc

  • BIP44/49/84 HD wallet coin type
    • Index: 156
    • Hex: 0x8000009c
    • Definition: slip-0044
    • Prefer P2WPKH (/84'/156'/0'/0/0)
  • strMessageMagic: Bitcoin Gold Signed Message:\n
  • URI prefix: bitcoingold:
  • Stratum: discussion at #37