// Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparams.h" #include "consensus/merkle.h" #include "issuance.h" #include "tinyformat.h" #include "util.h" #include "utilstrencodings.h" #include "amount.h" #include "crypto/sha256.h" #include #include // Safer for users if they load incorrect parameters via arguments. static std::vector CommitToArguments(const Consensus::Params& params, const std::string& networkID, const CScript& signblockscript) { CSHA256 sha2; unsigned char commitment[32]; sha2.Write((const unsigned char*)networkID.c_str(), networkID.length()); sha2.Write((const unsigned char*)HexStr(params.fedpegScript).c_str(), HexStr(params.fedpegScript).length()); sha2.Write((const unsigned char*)HexStr(signblockscript).c_str(), HexStr(signblockscript).length()); sha2.Finalize(commitment); return std::vector(commitment, commitment + 32); } static CScript StrHexToScriptWithDefault(std::string strScript, const CScript defaultScript) { CScript returnScript; if (!strScript.empty()) { std::vector scriptData = ParseHex(strScript); returnScript = CScript(scriptData.begin(), scriptData.end()); } else { returnScript = defaultScript; } return returnScript; } static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion) { CMutableTransaction txNew; txNew.nVersion = 1; txNew.vin.resize(1); // Any consensus-related values that are command-line set can be added here for anti-footgun txNew.vin[0].scriptSig = CScript(CommitToArguments(params, networkID, scriptChallenge)); txNew.vout.clear(); txNew.vout.push_back(CTxOut(CAsset(), 0, CScript() << OP_RETURN)); CBlock genesis; genesis.nTime = nTime; genesis.proof = CProof(scriptChallenge, CScript()); genesis.nVersion = nVersion; genesis.vtx.push_back(MakeTransactionRef(std::move(txNew))); genesis.hashPrevBlock.SetNull(); genesis.hashMerkleRoot = BlockMerkleRoot(genesis); return genesis; } /** Add an issuance transaction to the genesis block. Typically used to pre-issue * the policyAsset of a blockchain. The genesis block is not actually validated, * so this transaction simply has to match issuance structure. */ static void AppendInitialIssuance(CBlock& genesis_block, const COutPoint& prevout, const uint256& contract, const int64_t asset_outputs, const int64_t asset_values, const int64_t reissuance_outputs, const int64_t reissuance_values, const CScript& issuance_destination) { uint256 entropy; GenerateAssetEntropy(entropy, prevout, contract); CAsset asset; CalculateAsset(asset, entropy); // Re-issuance of policyAsset is always unblinded CAsset reissuance; CalculateReissuanceToken(reissuance, entropy, false); // Note: Genesis block isn't actually validated, outputs are entered into utxo db only CMutableTransaction txNew; txNew.nVersion = 1; txNew.vin.resize(1); txNew.vin[0].prevout = prevout; txNew.vin[0].assetIssuance.assetEntropy = contract; txNew.vin[0].assetIssuance.nAmount = asset_values*asset_outputs; txNew.vin[0].assetIssuance.nInflationKeys = reissuance_values*reissuance_outputs; for (unsigned int i = 0; i < asset_outputs; i++) { txNew.vout.push_back(CTxOut(asset, asset_values, issuance_destination)); } for (unsigned int i = 0; i < reissuance_outputs; i++) { txNew.vout.push_back(CTxOut(reissuance, reissuance_values, issuance_destination)); } genesis_block.vtx.push_back(MakeTransactionRef(std::move(txNew))); genesis_block.hashMerkleRoot = BlockMerkleRoot(genesis_block); } void CChainParams::UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) { consensus.vDeployments[d].nStartTime = nStartTime; consensus.vDeployments[d].nTimeout = nTimeout; } /** * Custom chain params */ class CCustomParams : public CChainParams { protected: void UpdateFromArgs() { consensus.nSubsidyHalvingInterval = GetArg("-con_nsubsidyhalvinginterval", 150); // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests) consensus.BIP34Height = GetArg("-con_bip34height", 100000000); consensus.BIP34Hash = uint256S(GetArg("-con_bip34hash", "0x00")); consensus.BIP65Height = GetArg("-con_bip65height", 1351); consensus.BIP66Height = GetArg("-con_bip66height", 1251); consensus.powLimit = uint256S(GetArg("-con_powlimit", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); consensus.parentChainPowLimit = uint256S(GetArg("-con_parentpowlimit", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); consensus.nPowTargetTimespan = GetArg("-con_npowtargettimespan", 14 * 24 * 60 * 60); // two weeks consensus.nPowTargetSpacing = GetArg("-con_npowtargetspacing", 10 * 60); consensus.fPowAllowMinDifficultyBlocks = GetBoolArg("-con_fpowallowmindifficultyblocks", true); consensus.fPowNoRetargeting = GetBoolArg("-con_fpownoretargeting", true); consensus.nRuleChangeActivationThreshold = GetArg("-con_nrulechangeactivationthreshold", 108); // 75% for testchains consensus.nMinerConfirmationWindow = GetArg("-con_nminerconfirmationwindow", 144); // Faster than normal for custom (144 instead of 2016) // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S(GetArg("-con_nminimumchainwork", "0x00")); // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S(GetArg("-con_defaultassumevalid", "0x00")); nDefaultPort = GetArg("-ndefaultport", 7042); nPruneAfterHeight = GetArg("-npruneafterheight", 1000); fMiningRequiresPeers = GetBoolArg("-fminingrequirespeers", false); fDefaultConsistencyChecks = GetBoolArg("-fdefaultconsistencychecks", true); fRequireStandard = GetBoolArg("-frequirestandard", false); fMineBlocksOnDemand = GetBoolArg("-fmineblocksondemand", true); anyonecanspend_aremine = GetBoolArg("-anyonecanspendaremine", true); } public: CCustomParams(const std::string& chain) : CChainParams(chain) { this->UpdateFromArgs(); const CScript defaultRegtestScript(CScript() << OP_TRUE); CScript genesisChallengeScript = StrHexToScriptWithDefault(GetArg("-signblockscript", ""), defaultRegtestScript); consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", ""), defaultRegtestScript); consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; parentGenesisBlockHash = uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"); // Generate pegged Bitcoin asset std::vector commit = CommitToArguments(consensus, strNetworkID, genesisChallengeScript); uint256 entropy; GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash); CalculateAsset(consensus.pegged_asset, entropy); genesis = CreateGenesisBlock(consensus, strNetworkID, 1296688602, genesisChallengeScript, 1); AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, 100, 21000000000000, 0, 0, CScript() << OP_TRUE); consensus.hashGenesisBlock = genesis.GetHash(); scriptCoinbaseDestination = CScript(); // Allow any coinbase destination vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. checkpointData = (CCheckpointData){ boost::assign::map_list_of ( 0, consensus.hashGenesisBlock), }; chainTxData = ChainTxData{ 0, 0, 0 }; base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,235); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,75); base58Prefixes[BLINDED_ADDRESS]= std::vector(1,4); base58Prefixes[SECRET_KEY] = std::vector(1,239); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); base58Prefixes[PARENT_PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector(1,196); } }; /** * Use base58 and other old configurations for outdated unittests */ class CMainParams : public CCustomParams { public: CMainParams(const std::string& chain) : CCustomParams(chain) { consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016 consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); base58Prefixes[BLINDED_ADDRESS]= std::vector(1,11); base58Prefixes[SECRET_KEY] = std::vector(1,128); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container >(); base58Prefixes[PARENT_PUBKEY_ADDRESS] = std::vector(1,0); base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector(1,5); } }; const std::vector CChainParams::supportedChains = boost::assign::list_of ( CHAINPARAMS_REGTEST ) ; static std::unique_ptr globalChainParams; const CChainParams &Params() { assert(globalChainParams); return *globalChainParams; } std::unique_ptr CreateChainParams(const std::string& chain) { if (chain == CBaseChainParams::MAIN) return std::unique_ptr(new CMainParams(chain)); return std::unique_ptr(new CCustomParams(chain)); } void SelectParams(const std::string& network) { SelectBaseParams(network); globalChainParams = CreateChainParams(network); } void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) { globalChainParams->UpdateBIP9Parameters(d, nStartTime, nTimeout); }