text: // Copyright (c) 2010 Satoshi Nakamoto
  // Copyright (c) 2009-2017 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 <tinyformat.h>
  #include <util.h>
  #include <utilstrencodings.h>
  
  #include <assert.h>
  
  #include <chainparamsseeds.h>
  
  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 = 2;
      txNew.vin.resize(1);
      txNew.vout.resize(1);
      txNew.vin[0].scriptSig = CScript() << CScriptNum(0) << 503382015 << 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;
  }
  
  /**
   * Build the genesis block. Note that the output of its generation
   * transaction cannot be spent since it did not originally exist in the
   * database.
   *
   * CBlock(hash=00000010ed34e2, ver=4, hashPrevBlock=00000000000000, hashMerkleRoot=082c26, nTime=1522681200, nBits=1e00ffff, nNonce=4454047, vtx=1)
   *  CTransaction(hash=082c2651a8, ver=2, vin.size=1, vout.size=1, nLockTime=0)
   *    CTxIn(COutPoint(0000000000, -1), coinbase 0004ffff001e01042848652069732072656e646572696e672070617374612073696e63652030332f4170722f323031382e)
   *    CScriptWitness()
   *    CTxOut(nValue=0.19850403, scriptPubKey=76a914a8afa48c98f70c3ccbc173fc)
   *
   */
  static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
  {
      const char* pszTimestamp = "He is rendering pasta since 03/Apr/2018.";
      const CScript genesisOutputScript = CScript() << OP_DUP << OP_HASH160 << ParseHex("a8afa48c98f70c3ccbc173fcdd49b6c62e240326") << OP_EQUALVERIFY << OP_CHECKSIG;
      return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
  }
  
  void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
  {
      consensus.vDeployments[d].nStartTime = nStartTime;
      consensus.vDeployments[d].nTimeout = nTimeout;
  }
  
  /**
   * Main network
   */
  /**
   * What makes a good checkpoint block?
   * + Is surrounded by blocks with reasonable timestamps
   *   (no blocks before with a timestamp after, none after with
   *    timestamp before)
   * + Contains no strange transactions
   */
  
  class CMainParams : public CChainParams {
  public:
      CMainParams() {
          strNetworkID = "main";
          consensus.nSubsidyHalvingInterval = 1460;
          consensus.BIP16Height = 0;
          consensus.BIP34Height = 0;
          consensus.BIP34Hash = uint256();
          consensus.BIP65Height = 0;
          consensus.BIP66Height = 0;
          consensus.powLimit = uint256S("000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.nPowTargetTimespan = 10 * 60; // 10 minute
          consensus.nPowTargetSpacing = 60;
          consensus.fPowAllowMinDifficultyBlocks = false;
          consensus.fPowNoRetargeting = false;
          consensus.nRuleChangeActivationThreshold = 16128; // 80% of 20160
          consensus.nMinerConfirmationWindow = 20160; // 2 weeks
          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
  
          // Deployment of BIP68, BIP112, and BIP113.
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
  
          // Deployment of SegWit (BIP141, BIP143, and BIP147)
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].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");
  
          /**
           * 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] = 0xf1;
          pchMessageStart[1] = 0xa5;
          pchMessageStart[2] = 0x85;
          pchMessageStart[3] = 0xc0;
          nDefaultPort = 8543;
          nPruneAfterHeight = 100000;
  
          genesis = CreateGenesisBlock(1522681200, 4454047, 0x1e00ffff, 4, 19850403);
          consensus.hashGenesisBlock = genesis.GetHash();
          assert(consensus.hashGenesisBlock == uint256S("0x00000010ed34e226ed31c5f84e8e2d6f72bb0f7e4d14fe1fb05b7da428715981"));
          assert(genesis.hashMerkleRoot == uint256S("0x082c2651a8735b696ad502c09d5ffcae11e7b8b8692df5f336861e2f712690a4"));
  
          // 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 dont 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("dnsseed.yama-co.in");
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,28);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,78);
          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 = "xyc";
  
          vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
  
          fDefaultConsistencyChecks = false;
          fRequireStandard = true;
          fMineBlocksOnDemand = false;
  
          checkpointData = {
              {
                  {0, uint256S("0x00000010ed34e226ed31c5f84e8e2d6f72bb0f7e4d14fe1fb05b7da428715981")}
              }
          };
  
          chainTxData = ChainTxData{
              0,
              0,
              0
          };
      }
  };
  
  /**
   * Testnet
   */
  class CTestNetParams : public CChainParams {
  public:
      CTestNetParams() {
          strNetworkID = "test";
          consensus.nSubsidyHalvingInterval = 1460;
          consensus.BIP16Height = 0;
          consensus.BIP34Height = 0;
          consensus.BIP34Hash = uint256();
          consensus.BIP65Height = 0;
          consensus.BIP66Height = 0;
          consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.nPowTargetTimespan = 10 * 60; // 10 minute
          consensus.nPowTargetSpacing = 60;
          consensus.fPowAllowMinDifficultyBlocks = true;
          consensus.fPowNoRetargeting = false;
          consensus.nRuleChangeActivationThreshold = 13104; // 65% for testchains
          consensus.nMinerConfirmationWindow = 20160; // 2 weeks
          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
  
          // Deployment of BIP68, BIP112, and BIP113.
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
  
          // Deployment of SegWit (BIP141, BIP143, and BIP147)
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].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] = 0xf1;
          pchMessageStart[1] = 0xa5;
          pchMessageStart[2] = 0x87;
          pchMessageStart[3] = 0xc1;
          nDefaultPort = 18543;
          nPruneAfterHeight = 1000;
  
          genesis = CreateGenesisBlock(1522681200, 5990674, 0x1e00ffff, 4, 19850403);
          consensus.hashGenesisBlock = genesis.GetHash();
          assert(consensus.hashGenesisBlock == uint256S("0x0000003d6e61a4054d58905c85f390b0e4e3eb0e1aa4b86a098c1b5d24754abf"));
          assert(genesis.hashMerkleRoot == uint256S("0x082c2651a8735b696ad502c09d5ffcae11e7b8b8692df5f336861e2f712690a4"));
  
          vFixedSeeds.clear();
          vSeeds.clear();
          // nodes with support for servicebits filtering should be at the top
          vSeeds.emplace_back("dnsseed.testnet.yama-co.in");
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,87);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,140);
          base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,239);
          base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
          base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
  
          bech32_hrp = "txyc";
  
          vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
  
          fDefaultConsistencyChecks = false;
          fRequireStandard = false;
          fMineBlocksOnDemand = false;
  
  
          checkpointData = {
              {
                  {0, uint256S("0x0000003d6e61a4054d58905c85f390b0e4e3eb0e1aa4b86a098c1b5d24754abf")},
              }
          };
  
          chainTxData = ChainTxData{
              0,
              0,
              0
          };
  
      }
  };
  
  /**
   * Regression test
   */
  class CRegTestParams : public CChainParams {
  public:
      CRegTestParams() {
          strNetworkID = "regtest";
          consensus.nSubsidyHalvingInterval = 146;
          consensus.BIP16Height = 0; // always enforce P2SH BIP16 on regtest
          consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests)
          consensus.BIP34Hash = uint256();
          consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
          consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
          consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
          consensus.nPowTargetTimespan = 10 * 60; // 10 minute
          consensus.nPowTargetSpacing = 60;
          consensus.fPowAllowMinDifficultyBlocks = true;
          consensus.fPowNoRetargeting = true;
          consensus.nRuleChangeActivationThreshold = 936; // 65% for testchains
          consensus.nMinerConfirmationWindow = 1440; // 1 day
          consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
          consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
          consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
          consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
          consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].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] = 0xf1;
          pchMessageStart[1] = 0xa5;
          pchMessageStart[2] = 0x89;
          pchMessageStart[3] = 0xc2;
          nDefaultPort = 28543;
          nPruneAfterHeight = 1000;
  
          genesis = CreateGenesisBlock(1522681200, 77361, 0x207fffff, 4, 19850403);
          consensus.hashGenesisBlock = genesis.GetHash();
          assert(consensus.hashGenesisBlock == uint256S("0x008b38958bda5b821c8b6fcdb15b51c4994a0c37333e72a47ccf95752009ec2d"));
          assert(genesis.hashMerkleRoot == uint256S("0x082c2651a8735b696ad502c09d5ffcae11e7b8b8692df5f336861e2f712690a4"));
  
          vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
          vSeeds.clear();      //!< Regtest mode doesn't have any DNS seeds.
  
          fDefaultConsistencyChecks = true;
          fRequireStandard = false;
          fMineBlocksOnDemand = true;
  
          checkpointData = {
              {
                  {0, uint256S("0x00")},
              }
          };
  
          chainTxData = ChainTxData{
              0,
              0,
              0
          };
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,87);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,140);
          base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,239);
          base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
          base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
  
          bech32_hrp = "xycrt";
      }
  };
  
  static std::unique_ptr<CChainParams> globalChainParams;
  
  const CChainParams &Params() {
      assert(globalChainParams);
      return *globalChainParams;
  }
  
  std::unique_ptr<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());
      throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
  }
  
  void SelectParams(const std::string& network)
  {
      SelectBaseParams(network);
      globalChainParams = CreateChainParams(network);
  }
  
  void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
  {
      globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout);
  }
  