/** * Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.bitcoin.core; import com.google.bitcoin.bouncycastle.util.encoders.Hex; import java.io.ByteArrayOutputStream; import java.io.Serializable; import java.math.BigInteger; /** * NetworkParameters contains the data needed for working with an instantiation of a BitCoin chain. * * Currently there are only two, the production chain and the test chain. But in future as BitCoin * evolves there may be more. You can create your own as long as they don't conflict. */ public class NetworkParameters implements Serializable { /** * The protocol version this library implements. A value of 31800 means 0.3.18.00. */ public static final int PROTOCOL_VERSION = 31800; private static final long serialVersionUID = 2579833727976661964L; // TODO: Seed nodes and checkpoint values should be here as well. /** * Genesis block for this chain.<p> * * The first block in every chain is a well known constant shared between all BitCoin implemenetations. For a * block to be valid, it must be eventually possible to work backwards to the genesis block by following the * prevBlockHash pointers in the block headers.<p> * * The genesis blocks for both test and prod networks contain the timestamp of when they were created, * and a message in the coinbase transaction. It says, <i>"The Times 03/Jan/2009 Chancellor on brink of second * bailout for banks"</i>. */ public Block genesisBlock; /** What the easiest allowable proof of work should be. */ public BigInteger proofOfWorkLimit; /** Default TCP port on which to connect to nodes. */ public int port; /** The header bytes that identify the start of a packet on this network. */ public long packetMagic; /** First byte of a base58 encoded address. */ public byte addressHeader; /** How many blocks pass between difficulty adjustment periods. BitCoin standardises this to be 2015. */ public int interval; /** * How much time in seconds is supposed to pass between "interval" blocks. If the actual elapsed time is * significantly different from this value, the network difficulty formula will produce a different value. Both * test and production BitCoin networks use 2 weeks (1209600 seconds). */ public int targetTimespan; private static Block createGenesis(NetworkParameters n) { Block genesisBlock = new Block(n); Transaction t = new Transaction(n); try { // A script containing the difficulty bits and the following message: // // "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" byte[] bytes = Hex.decode ("04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73"); t.inputs.add(new TransactionInput(n, bytes)); ByteArrayOutputStream scriptPubKeyBytes = new ByteArrayOutputStream(); Script.writeBytes(scriptPubKeyBytes, Hex.decode ("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")); scriptPubKeyBytes.write(Script.OP_CHECKSIG); t.outputs.add(new TransactionOutput(n, scriptPubKeyBytes.toByteArray())); } catch (Exception e) { // Cannot happen. } genesisBlock.addTransaction(t); return genesisBlock; } static private final int TARGET_TIMESPAN = 14 * 24 * 60 * 60; // 2 weeks per difficulty cycle, on average. static private final int TARGET_SPACING = 10 * 60; // 10 minutes per block. static private final int INTERVAL = TARGET_TIMESPAN / TARGET_SPACING; /** Sets up the given NetworkParameters with testnet values. */ private static NetworkParameters createTestNet(NetworkParameters n) { // Genesis hash is 0000000224b1593e3ff16a0e3b61285bbc393a39f78c8aa48c456142671f7110 // The proof of work limit has to start with 00, as otherwise the value will be interpreted as negative. n.proofOfWorkLimit = new BigInteger("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16); n.packetMagic = 0xfabfb5daL; n.port = 18333; n.addressHeader = 111; n.interval = INTERVAL; n.targetTimespan = TARGET_TIMESPAN; n.genesisBlock = createGenesis(n); n.genesisBlock.setTime(1296688602L); n.genesisBlock.setDifficultyTarget(0x1d07fff8L); n.genesisBlock.setNonce(384568319); String genesisHash = n.genesisBlock.getHashAsString(); assert genesisHash.equals("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"); return n; } /** The test chain created by Gavin. */ public static NetworkParameters testNet() { NetworkParameters n = new NetworkParameters(); return createTestNet(n); } /** The primary BitCoin chain created by Satoshi. */ public static NetworkParameters prodNet() { NetworkParameters n = new NetworkParameters(); n.proofOfWorkLimit = new BigInteger("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16); n.port = 8333; n.packetMagic = 0xf9beb4d9L; n.addressHeader = 0; n.interval = INTERVAL; n.targetTimespan = TARGET_TIMESPAN; n.genesisBlock = createGenesis(n); n.genesisBlock.setDifficultyTarget(0x1d00ffffL); n.genesisBlock.setTime(1231006505L); n.genesisBlock.setNonce(2083236893); String genesisHash = n.genesisBlock.getHashAsString(); assert genesisHash.equals("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") : genesisHash; return n; } /** Returns a testnet params modified to allow any difficulty target. */ static NetworkParameters unitTests() { NetworkParameters n = new NetworkParameters(); n = createTestNet(n); n.proofOfWorkLimit = new BigInteger("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16); n.genesisBlock.setDifficultyTarget(Block.EASIEST_DIFFICULTY_TARGET); n.interval = 10; n.targetTimespan = 200000000; // 6 years. Just a very big number. return n; } }