text: // Copyright (c) 2010 Satoshi Nakamoto
  // Copyright (c) 2009-2019 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 <chainparamsseeds.h>
  #include <consensus/merkle.h>
  #include <consensus/consensus.h>
  #include <tinyformat.h>
  #include <util/system.h>
  #include <util/strencodings.h>
  #include <versionbitsinfo.h>
  #include <arith_uint256.h>
  #include <boost/date_time/posix_time/posix_time.hpp>
  #include <assert.h>
  
  #include <boost/algorithm/string/classification.hpp>
  #include <boost/algorithm/string/split.hpp>
  
  static bool CheckInitialProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params);
  
  static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
  {
      CMutableTransaction txNew;
      txNew.nVersion = 1;
      txNew.vin.resize(1);
      txNew.vout.resize(1);
      txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
      txNew.vout[0].nValue = genesisReward;
      txNew.vout[0].scriptPubKey = genesisOutputScript;
  
      CBlock genesis;
      genesis.nTime    = nTime;
      genesis.nBits    = nBits;
      genesis.nNonce   = nNonce;
      genesis.nVersion = nVersion;
      genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
      genesis.hashPrevBlock.SetNull();
      genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
      return genesis;
  }
  
  static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
  {
      const char* pszTimestamp = "BitcoinS 02-OCT-2020 PoS and The Roadmap To Monetary Freedom";
      const CScript genesisOutputScript = CScript();
      return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
  }
  
  /**
   * Main network
   */
  class CMainParams : public CChainParams {
  public:
      CMainParams() {
          strNetworkID = CBaseChainParams::MAIN;
          consensus.nSubsidyHalvingInterval = 700000;
          consensus.BIP16Exception = uint256S("0x00000bcd2d9ccbb28606a8b2d962b97394f612bf6e021ce1d64d71cecb008029");
          consensus.BIP34Height = 1;
          consensus.BIP34Hash = uint256S("0x00000b3b403a2b37780a8dc3813e02463cbaceab135efffe4aaacf0446f862d5");
          consensus.BIP65Height = 1;
          consensus.BIP66Height = 1;
          consensus.CSVHeight = 1;
          consensus.SegwitHeight = 1;
          consensus.MinBIP9WarningHeight = consensus.SegwitHeight + consensus.nMinerConfirmationWindow;
          consensus.BPSRewardMatchStep = 40000;
          consensus.BPSRewardMatchHeight = 3 * consensus.BPSRewardMatchStep;
          consensus.BPSDiffAdjHeight = 130000;
          consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.posLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.nPowTargetTimespan = 10 * 3 * 60; // every 10 blocks
          consensus.nPowTargetSpacing = 3 * 60;
          consensus.fPowAllowMinDifficultyBlocks = false;
          consensus.fPowNoRetargeting = false;
          consensus.fPoSNoRetargeting = false;
          consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
          consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
          consensus.nLastPOWBlock = 5000;
          consensus.nMPoSRewardRecipients = 10;
          consensus.nFirstMPoSBlock = consensus.nLastPOWBlock + 
                                      consensus.nMPoSRewardRecipients + 
                                      COINBASE_MATURITY;
          consensus.nEnableHeaderSignatureHeight = 0;
          consensus.nCheckpointSpan = COINBASE_MATURITY;
          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
  
          // The best chain should have at least this much work.
          consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000000001"); //block 1
  
          // By default assume that the signatures in ancestors of this block are valid.
          consensus.defaultAssumeValid = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); //block 1
  
          /**
           * The message start string is designed to be unlikely to occur in normal data.
           * The characters are rarely used upper ASCII, not valid as UTF-8, and produce
           * a large 32-bit integer with any alignment.
           */
          pchMessageStart[0] = 0x9d;
          pchMessageStart[1] = 0xf7;
          pchMessageStart[2] = 0x2c;
          pchMessageStart[3] = 0x1e;
          nDefaultPort = 8777;
          nPruneAfterHeight = 100000;
          m_assumed_blockchain_size = 2;
          m_assumed_chain_state_size = 1;
  
  
          // uint32_t nTime=time(nullptr);
          // uint32_t nNonce=0;
          // bool proof_of_work_valid = false;
          // std::cout << "Create Genesis block: " << nTime << std::endl;
          // while(true)
          // {
          //     nTime=time(nullptr);
          //     genesis = CreateGenesisBlock(nTime, nNonce, 0x1e0fffff, 1, 50 * COIN);
          //     for (genesis.nNonce = 0; genesis.nNonce <= 0xff0000; genesis.nNonce++)
          //     {
          //         proof_of_work_valid = CheckInitialProofOfWork(genesis.GetHash(), genesis.nBits, consensus);
          //         if (proof_of_work_valid) {
          //             break;
          //         }
          //     }
          //     if (proof_of_work_valid) {
          //         break;
          //     }
  
          //     std::cout << "time: " << nTime << std::endl;
          // }
  
          // Create Genesis block: 1602160971
          // consensus.hashGenesisBlock: 0000091185a04dbbcee63ad911d786ef77e4d9c2a06d51c2eaecd17234a6bb4c
          // genesis.hashMerkleRoot: aa7c82960d1f8a8354b301053cf2c692a6b18a0af56afdf4dfa7aa7abd0723d8
          // genesis.nNonce: 2044995
  
          uint32_t nTime=1602160971;
          uint32_t nNonce=2044995; 
          genesis = CreateGenesisBlock(nTime, nNonce, 0x1e0fffff, 1, 50 * COIN);
          consensus.hashGenesisBlock = genesis.GetHash();
          // std::cout << "consensus.hashGenesisBlock: " << consensus.hashGenesisBlock.ToString() << std::endl;
          // std::cout << "genesis.hashMerkleRoot: " << genesis.hashMerkleRoot.ToString() << std::endl;   
          // std::cout << "genesis.nNonce: " << genesis.nNonce << std::endl;
  
          assert(consensus.hashGenesisBlock == uint256S("0x0000091185a04dbbcee63ad911d786ef77e4d9c2a06d51c2eaecd17234a6bb4c"));
          assert(genesis.hashMerkleRoot == uint256S("0xaa7c82960d1f8a8354b301053cf2c692a6b18a0af56afdf4dfa7aa7abd0723d8"));
  
          // Note that of those which support the service bits prefix, most only support a subset of
          // possible options.
          // This is fine at runtime as we'll fall back to using them as a oneshot if they don't support the
          // service bits we want, but we should get them updated to support all service bits wanted by any
          // release ASAP to avoid it where possible.
          vSeeds.emplace_back("seed1.bitcoinstaking.org");
          vSeeds.emplace_back("seed2.bitcoinstaking.org");
          vSeeds.emplace_back("seed3.bitcoinstaking.org");
          vSeeds.emplace_back("seed4.bitcoinstaking.org");
          vSeeds.emplace_back("seed5.bitcoinstaking.org");
          vSeeds.emplace_back("seed6.bitcoinstaking.org");
          vSeeds.emplace_back("seed7.bitcoinstaking.org");
          vSeeds.emplace_back("seed8.bitcoinstaking.org");
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
          base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,128);
          base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
          base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
  
          bech32_hrp = "bc";
  
          vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
  
          fDefaultConsistencyChecks = false;
          fRequireStandard = true;
          m_is_test_chain = false;
          m_is_mockable_chain = false;
  
          checkpointData = {
              {
                  {           0, uint256S("0x0000091185a04dbbcee63ad911d786ef77e4d9c2a06d51c2eaecd17234a6bb4c")},
                  {        5000, uint256S("0x00000d13c755a4d0ac398322f93cfde68ca7ed2e959f06a57a2282497451698c")}
              }
          };
  
          chainTxData = ChainTxData{
              // Data from RPC: getchaintxstats
              /* nTime    */ 1601750080,
              /* nTxCount */ 10000,
              /* dTxRate  */ 0.05818143895062515,
          };
      }
  };
  
  /**
   * Testnet (v3)
   */
  class CTestNetParams : public CChainParams {
  public:
      CTestNetParams() {
          strNetworkID = CBaseChainParams::TESTNET;
          consensus.nSubsidyHalvingInterval = 700000;
          consensus.BIP16Exception = uint256S("0x00000fe2acf48e35c5b594d9ff7db2a7bbafa1b73205b2789a6833be70595818");
          consensus.BIP34Height = 1;
          consensus.BIP34Hash = uint256S("0x00000fe2acf48e35c5b594d9ff7db2a7bbafa1b73205b2789a6833be70595818");
          consensus.BIP65Height = 1;
          consensus.BIP66Height = 1;
          consensus.CSVHeight = 1;
          consensus.SegwitHeight = 1;
          consensus.MinBIP9WarningHeight = consensus.SegwitHeight + consensus.nMinerConfirmationWindow;
          consensus.BPSRewardMatchStep = 400;
          consensus.BPSRewardMatchHeight = 3 * consensus.BPSRewardMatchStep;
          consensus.BPSDiffAdjHeight = 1500;
          consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.posLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.nPowTargetTimespan = 10 * 3 * 60; // every 10 blocks
          consensus.nPowTargetSpacing = 3 * 60;
          consensus.fPowAllowMinDifficultyBlocks = true;
          consensus.fPowNoRetargeting = false;
          consensus.fPoSNoRetargeting = false;
          consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
          consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
          consensus.nLastPOWBlock = 501;
          consensus.nMPoSRewardRecipients = 10;
          consensus.nFirstMPoSBlock = consensus.nLastPOWBlock + 
                                      consensus.nMPoSRewardRecipients + 
                                      COINBASE_MATURITY;
          consensus.nEnableHeaderSignatureHeight = 0;
          consensus.nCheckpointSpan = COINBASE_MATURITY;
          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
  
          // The best chain should have at least this much work.
          consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000");
  
          // By default assume that the signatures in ancestors of this block are valid.
          consensus.defaultAssumeValid = uint256S("0x00000fe2acf48e35c5b594d9ff7db2a7bbafa1b73205b2789a6833be70595818"); // 0
  
          pchMessageStart[0] = 0xd5;
          pchMessageStart[1] = 0x1f;
          pchMessageStart[2] = 0x35;
          pchMessageStart[3] = 0x29;
          nDefaultPort = 48932;
          nPruneAfterHeight = 1000;
          m_assumed_blockchain_size = 40;
          m_assumed_chain_state_size = 2;
  
          uint32_t nTime=1601661242;
          uint32_t nNonce=4559986;        
          genesis = CreateGenesisBlock(nTime, nNonce, 0x1e0fffff, 1, 50 * COIN);
          consensus.hashGenesisBlock = genesis.GetHash();
          // std::cout << "consensus.hashGenesisBlock: " << consensus.hashGenesisBlock.ToString() << std::endl;
          // std::cout << "genesis.hashMerkleRoot: " << genesis.hashMerkleRoot.ToString() << std::endl;   
          // std::cout << "genesis.nNonce: " << genesis.nNonce << std::endl;
  
          assert(consensus.hashGenesisBlock == uint256S("0x00000aba6dbb5d4250ca76041f18c4939241e3f3d3bfff1e81e2866df3a2f995"));
          assert(genesis.hashMerkleRoot == uint256S("0xaa7c82960d1f8a8354b301053cf2c692a6b18a0af56afdf4dfa7aa7abd0723d8"));
  
          vFixedSeeds.clear();
          vSeeds.clear();
          // nodes with support for servicebits filtering should be at the top
          vSeeds.emplace_back("testnet-seed1.bitcoinstaking.net");
          vSeeds.emplace_back("testnet-seed2.bitcoinstaking.net");
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,65);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,78);
          base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,130);
          base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
          base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
  
          bech32_hrp = "bt";
  
          vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
  
          fDefaultConsistencyChecks = false;
          fRequireStandard = false;
          m_is_test_chain = true;
          m_is_mockable_chain = false;
  
          checkpointData = {
              {
                  {0, uint256S("0x00000fe2acf48e35c5b594d9ff7db2a7bbafa1b73205b2789a6833be70595818")},
              }
          };
  
          chainTxData = ChainTxData{
              // Data from RPC: getchaintxstats 4096 00000000000000b7ab6ce61eb6d571003fbe5fe892da4c9b740c49a07542462d
              /* nTime    */ 1588417200,
              /* nTxCount */ 0,
              /* dTxRate  */ 0.0,
          };
      }
  };
  
  /**
   * Regression test
   */
  class CRegTestParams : public CChainParams {
  public:
      explicit CRegTestParams(const ArgsManager& args) {
          strNetworkID =  CBaseChainParams::REGTEST;
          consensus.nSubsidyHalvingInterval = 150;
          consensus.BIP16Exception = uint256();
          consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
          consensus.BIP34Hash = uint256();
          consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in functional tests)
          consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in functional tests)
          consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests)
          consensus.SegwitHeight = 0; // SEGWIT is always activated on regtest unless overridden
          consensus.MinBIP9WarningHeight = 0;
          consensus.BPSRewardMatchStep = 400;
          consensus.BPSRewardMatchHeight = 3 * consensus.BPSRewardMatchStep;
          consensus.BPSDiffAdjHeight = 1500;
          consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.posLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.nPowTargetTimespan = 10 * 3 * 60; // every 10 blocks
          consensus.nPowTargetSpacing = 3 * 60;
          consensus.fPowAllowMinDifficultyBlocks = true;
          consensus.fPowNoRetargeting = true;
          consensus.fPoSNoRetargeting = true;
          consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
          consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
          consensus.nLastPOWBlock = 0x7fffffff;
          consensus.nMPoSRewardRecipients = 10;
          consensus.nFirstMPoSBlock = 5000;
          consensus.nEnableHeaderSignatureHeight = 0;
          consensus.nCheckpointSpan = COINBASE_MATURITY;
          consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
          consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
          consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
  
          // The best chain should have at least this much work.
          consensus.nMinimumChainWork = uint256S("0x00");
  
          // By default assume that the signatures in ancestors of this block are valid.
          consensus.defaultAssumeValid = uint256S("0x00");
  
          pchMessageStart[0] = 0xfa;
          pchMessageStart[1] = 0xbf;
          pchMessageStart[2] = 0xb5;
          pchMessageStart[3] = 0xda;
          nDefaultPort = 48934;
          nPruneAfterHeight = 1000;
          m_assumed_blockchain_size = 0;
          m_assumed_chain_state_size = 0;
  
          UpdateActivationParametersFromArgs(args);
  
          uint32_t nTime=1601661242;
          uint32_t nNonce=4559986;        
          genesis = CreateGenesisBlock(nTime, nNonce, 0x1e0fffff, 1, 50 * COIN);
          consensus.hashGenesisBlock = genesis.GetHash();
          // std::cout << "consensus.hashGenesisBlock: " << consensus.hashGenesisBlock.ToString() << std::endl;
          // std::cout << "genesis.hashMerkleRoot: " << genesis.hashMerkleRoot.ToString() << std::endl;   
          // std::cout << "genesis.nNonce: " << genesis.nNonce << std::endl;
  
          assert(consensus.hashGenesisBlock == uint256S("0x00000aba6dbb5d4250ca76041f18c4939241e3f3d3bfff1e81e2866df3a2f995"));
          assert(genesis.hashMerkleRoot == uint256S("0xaa7c82960d1f8a8354b301053cf2c692a6b18a0af56afdf4dfa7aa7abd0723d8"));
  
          vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
          vSeeds.clear();      //!< Regtest mode doesn't have any DNS seeds.
  
          fDefaultConsistencyChecks = true;
          fRequireStandard = true;
          m_is_test_chain = true;
          m_is_mockable_chain = true;
  
          checkpointData = {
              {
                  {0, uint256S("0x2b8d445931aa4ea9b52db1488d3641fa2d4f7a3c1f8151bfa99d017493129e97")},
              }
          };
  
          chainTxData = ChainTxData{
              1588417200,
              0,
              0
          };
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,65);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,78);
          base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,130);
          base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
          base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
  
          bech32_hrp = "bpt";
      }
  
      /**
       * Allows modifying the Version Bits regtest parameters.
       */
      void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
      {
          consensus.vDeployments[d].nStartTime = nStartTime;
          consensus.vDeployments[d].nTimeout = nTimeout;
      }
      void UpdateActivationParametersFromArgs(const ArgsManager& args);
  };
  
  void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
  {
      if (gArgs.IsArgSet("-segwitheight")) {
          int64_t height = gArgs.GetArg("-segwitheight", consensus.SegwitHeight);
          if (height < -1 || height >= std::numeric_limits<int>::max()) {
              throw std::runtime_error(strprintf("Activation height %ld for segwit is out of valid range. Use -1 to disable segwit.", height));
          } else if (height == -1) {
              LogPrintf("Segwit disabled for testing\n");
              height = std::numeric_limits<int>::max();
          }
          consensus.SegwitHeight = static_cast<int>(height);
      }
  
      if (!args.IsArgSet("-vbparams")) return;
  
      for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
          std::vector<std::string> vDeploymentParams;
          boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
          if (vDeploymentParams.size() != 3) {
              throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end");
          }
          int64_t nStartTime, nTimeout;
          if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
              throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
          }
          if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
              throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
          }
          bool found = false;
          for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
              if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
                  UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
                  found = true;
                  LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout);
                  break;
              }
          }
          if (!found) {
              throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0]));
          }
      }
  }
  
  static std::unique_ptr<const CChainParams> globalChainParams;
  
  const CChainParams &Params() {
      assert(globalChainParams);
      return *globalChainParams;
  }
  
  std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
  {
      if (chain == CBaseChainParams::MAIN)
          return std::unique_ptr<CChainParams>(new CMainParams());
      else if (chain == CBaseChainParams::TESTNET)
          return std::unique_ptr<CChainParams>(new CTestNetParams());
      else if (chain == CBaseChainParams::REGTEST)
          return std::unique_ptr<CChainParams>(new CRegTestParams(gArgs));
      throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
  }
  
  void SelectParams(const std::string& network)
  {
      SelectBaseParams(network);
      globalChainParams = CreateChainParams(network);
  }
  
  bool CheckInitialProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
  {
      bool fNegative;
      bool fOverflow;
      arith_uint256 bnTarget;
  
      bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
  
      // Check range
      if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
          return false;
  
      // Check proof of work matches claimed amount
      if (UintToArith256(hash) > bnTarget)
          return false;
  
      return true;
  }
  