text: // Copyright (c) 2010 Satoshi Nakamoto
  // Copyright (c) 2009-2012 The Bitcoin developers
  // Distributed under the MIT/X11 software license, see the accompanying
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  
  #include "assert.h"
  
  #include "chainparams.h"
  #include "main.h"
  #include "util.h"
  
  #include <boost/assign/list_of.hpp>
  
  using namespace boost::assign;
  
  struct SeedSpec6 {
      uint8_t addr[16];
      uint16_t port;
  };
  
  #include "chainparamsseeds.h"
  
  //
  // Main network
  //
  
  // Convert the pnSeeds6 array into usable address objects.
  static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
  {
      // It'll only connect to one or two seed nodes because once it connects,
      // it'll get a pile of addresses with newer timestamps.
      // Seed nodes are given a random 'last seen time' of between one and two
      // weeks ago.
      const int64_t nOneWeek = 7*24*60*60;
      for (unsigned int i = 0; i < count; i++)
      {
          struct in6_addr ip;
          memcpy(&ip, data[i].addr, sizeof(ip));
          CAddress addr(CService(ip, data[i].port));
          addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
          vSeedsOut.push_back(addr);
      }
  }
  
  class CMainParams : public CChainParams {
  public:
      CMainParams() {
          // 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 4-byte int at any alignment.
          pchMessageStart[0] = 0x44;
          pchMessageStart[1] = 0xf3;
          pchMessageStart[2] = 0x6a;
          pchMessageStart[3] = 0xc2;
          vAlertPubKey = ParseHex("046bd5b9f0f92cc59f7a17363e88bbe084af9b36750354b6d5bde5950505b70ce6ff68734630bce1938b5ec84707f1cd55138c737ebd9b683b450a9b546ab8aba3");
          nDefaultPort = 27188;
          nRPCPort = 27187;
          bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);
  
          // Build the genesis block. Note that the output of the genesis coinbase cannot
          // be spent as it did not originally exist in the database.
          //
          //CBlock(hash=000001afe7e57492997002fe7a1002fa186587d69937fff24232a51b00a56bc5, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=ee5cc2eb1b482ba3e01832dc7aab340e60943b4f382a246c5c9cd6fdff027f59, nTime=1610179207, nBits=1e0fffff, nNonce=80624, vtx=1, vchBlockSig=)
          //  Coinbase(hash=12630d16a9, nTime=1610179207, ver=1, vin.size=1, vout.size=1, nLockTime=0)
          //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 00012a24323020466562203230313420426974636f696e2041544d7320636f6d6520746f20555341)
          //    CTxOut(empty)
          //  vMerkleTree: 12630d16a9
          const char* pszTimestamp = "The time 1 Gennaio 2021 made swap FLG";
          std::vector<CTxIn> vin;
          vin.resize(1);
          vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
          std::vector<CTxOut> vout;
          vout.resize(1);
          vout[0].SetEmpty();
          CTransaction txNew(1, 1610179207, vin, vout, 0);
          genesis.vtx.push_back(txNew);
          genesis.hashPrevBlock = 0;
          genesis.hashMerkleRoot = genesis.BuildMerkleTree();
          genesis.nVersion = 1;
          genesis.nTime    = 1610179207;
          genesis.nBits    = bnProofOfWorkLimit.GetCompact();
          genesis.nNonce   = 80624;
  
          hashGenesisBlock = genesis.GetHash();
          assert(hashGenesisBlock == uint256("0x000001afe7e57492997002fe7a1002fa186587d69937fff24232a51b00a56bc5"));
          assert(genesis.hashMerkleRoot == uint256("0xee5cc2eb1b482ba3e01832dc7aab340e60943b4f382a246c5c9cd6fdff027f59"));
  
          vSeeds.push_back(CDNSSeedData("walletbuilders.com", "node1.walletbuilders.com"));
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 36);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 35);
          base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1, 163);
          base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
          base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
  
          convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
  
          nLastPOWBlock = 1000000;
      }
  
      virtual const CBlock& GenesisBlock() const { return genesis; }
      virtual Network NetworkID() const { return CChainParams::MAIN; }
  
      virtual const vector<CAddress>& FixedSeeds() const {
          return vFixedSeeds;
      }
  protected:
      CBlock genesis;
      vector<CAddress> vFixedSeeds;
  };
  static CMainParams mainParams;
  
  
  //
  // Testnet
  //
  
  class CTestNetParams : public CMainParams {
  public:
      CTestNetParams() {
          // 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 4-byte int at any alignment.
          pchMessageStart[0] = 0x49;
          pchMessageStart[1] = 0x75;
          pchMessageStart[2] = 0xf8;
          pchMessageStart[3] = 0x0b;
          bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
          vAlertPubKey = ParseHex("0489d957d5e293e182a2fc78c5714899a065b57371e98b715cac2eda5e6dacee999cbe0d7597da9b96a6fd4e6d78f373126bd0a9bb814d3b283e70315499c66a96");
          nDefaultPort = 37188;
          nRPCPort = 37187;
          strDataDir = "testnet";
  
          // Modify the testnet genesis block so the timestamp is valid for a later start.
          genesis.nBits  = bnProofOfWorkLimit.GetCompact();
          genesis.nNonce = 18193735;
          hashGenesisBlock = genesis.GetHash();
          assert(hashGenesisBlock == uint256("0x000001bde62e0c78b02214aaba58e81775c6f651d99de9518e9d19010042f0cb"));
  
          vFixedSeeds.clear();
          vSeeds.clear();
  
          base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 111);
          base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 196);
          base58Prefixes[SECRET_KEY]     = std::vector<unsigned char>(1, 239);
          base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
          base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
  
          convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
  
          nLastPOWBlock = 0x7fffffff;
      }
      virtual Network NetworkID() const { return CChainParams::TESTNET; }
  };
  static CTestNetParams testNetParams;
  
  
  //
  // Regression test
  //
  class CRegTestParams : public CTestNetParams {
  public:
      CRegTestParams() {
          pchMessageStart[0] = 0x6d;
          pchMessageStart[1] = 0xf0;
          pchMessageStart[2] = 0x29;
          pchMessageStart[3] = 0xfb;
          bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
          genesis.nTime = 1610179212;
          genesis.nBits  = bnProofOfWorkLimit.GetCompact();
          genesis.nNonce = 8405714;
          hashGenesisBlock = genesis.GetHash();
          nDefaultPort = 18444;
          strDataDir = "regtest";
          assert(hashGenesisBlock == uint256("0x0000017024da90ba9c4887df5896cba04d02de3e063dfb4d570e03e50ae9c901"));
  
          vSeeds.clear();  // Regtest mode doesn't have any DNS seeds.
      }
  
      virtual bool RequireRPCPassword() const { return false; }
      virtual Network NetworkID() const { return CChainParams::REGTEST; }
  };
  static CRegTestParams regTestParams;
  
  static CChainParams *pCurrentParams = &mainParams;
  
  const CChainParams &Params() {
      return *pCurrentParams;
  }
  
  void SelectParams(CChainParams::Network network) {
      switch (network) {
          case CChainParams::MAIN:
              pCurrentParams = &mainParams;
              break;
          case CChainParams::TESTNET:
              pCurrentParams = &testNetParams;
              break;
          case CChainParams::REGTEST:
              pCurrentParams = &regTestParams;
              break;
          default:
              assert(false && "Unimplemented network");
              return;
      }
  }
  
  bool SelectParamsFromCommandLine() {
      bool fRegTest = GetBoolArg("-regtest", false);
      bool fTestNet = GetBoolArg("-testnet", false);
  
      if (fTestNet && fRegTest) {
          return false;
      }
  
      if (fRegTest) {
          SelectParams(CChainParams::REGTEST);
      } else if (fTestNet) {
          SelectParams(CChainParams::TESTNET);
      } else {
          SelectParams(CChainParams::MAIN);
      }
      return true;
  }
  