// Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2015-2019 The PIVX developers // Copyright (c) 2026 Agrarian Developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "libzerocoin/Params.h" #include "chainparams.h" #include "random.h" #include "util.h" #include "utilstrencodings.h" #include #include using namespace std; 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& 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); } } // 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 static Checkpoints::MapCheckpoints mapCheckpoints = boost::assign::map_list_of (0, uint256("000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e")); static const Checkpoints::CCheckpointData data = { &mapCheckpoints, 1643790201, // * UNIX timestamp of last checkpoint block 0, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) 0 // * estimated number of transactions per day after checkpoint }; static Checkpoints::MapCheckpoints mapCheckpointsTestnet = boost::assign::map_list_of (0, uint256("0x001")); static const Checkpoints::CCheckpointData dataTestnet = { &mapCheckpointsTestnet, 1643790201, 0, 0 }; static Checkpoints::MapCheckpoints mapCheckpointsRegtest = boost::assign::map_list_of(0, uint256("0x001")); static const Checkpoints::CCheckpointData dataRegtest = { &mapCheckpointsRegtest, 1643790201, 0, 0 }; libzerocoin::ZerocoinParams* CChainParams::Zerocoin_Params(bool useModulusV1) const { assert(this); static CBigNum bnHexModulus = 0; if (!bnHexModulus) bnHexModulus.SetHex(zerocoinModulus); static libzerocoin::ZerocoinParams ZCParamsHex = libzerocoin::ZerocoinParams(bnHexModulus); static CBigNum bnDecModulus = 0; if (!bnDecModulus) bnDecModulus.SetDec(zerocoinModulus); static libzerocoin::ZerocoinParams ZCParamsDec = libzerocoin::ZerocoinParams(bnDecModulus); return useModulusV1 ? &ZCParamsHex : &ZCParamsDec; } class CMainParams : public CChainParams { public: CMainParams() { networkID = CBaseChainParams::MAIN; strNetworkID = "main"; /** * 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] = 0x0b; pchMessageStart[1] = 0x23; pchMessageStart[2] = 0xa0; pchMessageStart[3] = 0xb9; vAlertPubKey = ParseHex("04aa33fe2c682fa60d5ee6fd76d73336c34978408a9c938cb3683f1f26f64793a76665f0045c8066c04f239fda81ea4631631c8f1b8eb835d8b1d417099308c2be"); nDefaultPort = 51336; bnProofOfWorkLimit = ~uint256(0) >> 20; // Agrarian starting difficulty is 1 / 2^12 nSubsidyHalvingInterval = 210000; nMaxReorganizationDepth = 100; nEnforceBlockUpgradeMajority = 0; nRejectBlockOutdatedMajority = 0; nToCheckBlockUpgradeMajority = 0; nMinerThreads = 0; nTargetTimespan = 10 * 60; nTargetSpacing = 10 * 60; nMaturity = 20; nMasternodeCountDrift = 20; // Preserve the historical mainnet cap produced by the old overflowing // expression `999999999999 * COIN` on 64-bit builds. nMaxMoneyOut = 7766279631352241920LL; /** Height or Time Based Activations **/ // // Hybrid PoW/PoS schedule: // - PoW is permitted for ~50 years (based on target spacing) // - After that, the chain becomes PoS-only // // We use the Julian year (365.25 days) for a deterministic conversion. static const int64_t JULIAN_YEAR_SECONDS = 31557600; // 365.25 * 24 * 60 * 60 nLastPOWBlock = (int)((50LL * JULIAN_YEAR_SECONDS) / nTargetSpacing); // Hybrid consensus: PoW mining and PoS staking are both permitted beginning at block 2. // PoW remains permitted until nLastPOWBlock. nFirstPoSBlock = 2; // PIVX-style modifier upgrade: keep aligned with PoS activation. nModifierUpdateBlock = 2; nZerocoinStartHeight = 0; nZerocoinStartTime = 1643790201; nBlockEnforceSerialRange = 1; // Enforce serial range starting this block nBlockRecalculateAccumulators = 999999999; // Trigger a recalculation of accumulators nBlockFirstFraudulent = 999999999; // First block that bad serials emerged nBlockLastGoodCheckpoint = 999999999; // Last valid accumulator checkpoint nBlockEnforceInvalidUTXO = 999999999; // Start enforcing the invalid UTXO's nInvalidAmountFiltered = 0; // Amount of invalid coins filtered through exchanges, that should be considered valid nBlockZerocoinV2 = 999999999; nBlockDoubleAccumulated = 999999999; nEnforceNewSporkKey = 1643790201; nRejectOldSporkKey = 1527811200; // Public coin spend enforcement nPublicZCSpends = 1; // Fake Serial Attack nFakeSerialBlockheightEnd = 0; nSupplyBeforeFakeSerial = 0; // zerocoin supply at block nFakeSerialBlockheightEnd /** * 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=00000ffd590b14, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=e0028e, nTime=1390095618, nBits=1e0ffff0, nNonce=28917698, vtx=1) * CTransaction(hash=e0028e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73) * CTxOut(nValue=50.00000000, scriptPubKey=0xA9037BAC7050C479B121CF) * vMerkleTree: e0028e */ const char* pszTimestamp = "CBS 02FEB2022 Pfizer asks FDA to authorize vaccine for kids under 5"; CMutableTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04fe3d7e5608ebba6d822948eff929c822ad35b5f8ecd00977d0e59ed67da697bd88e0ed8bd58797bde6fe6750236f5dae4cf403af0925c8339f0a91b682254b39") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1643790201; genesis.nBits = 0x1e0ffff0; genesis.nNonce = 21936323; hashGenesisBlock = genesis.GetHash(); assert(hashGenesisBlock == uint256("0x000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e")); assert(genesis.hashMerkleRoot == uint256("0x3bb054bb772e1bee1547d4b0e06c0ce34d636ee1daf56b37f1a017ce8136da00")); vSeeds.push_back(CDNSSeedData("pacificao.com", "agr1.pacificao.com")); vSeeds.push_back(CDNSSeedData("n2.pacificao.com", "agr2.pacificao.com")); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 23); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 24); base58Prefixes[SECRET_KEY] = std::vector(1, 151); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x02)(0x2D)(0x25)(0x33).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x02)(0x21)(0x31)(0x2B).convert_to_container >(); // BIP44 coin type is from https://github.com/satoshilabs/slips/blob/master/slip-0044.md base58Prefixes[EXT_COIN_TYPE] = boost::assign::list_of(0x80)(0x00)(0x00)(0x77).convert_to_container >(); convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main)); fMiningRequiresPeers = true; fAllowMinDifficultyBlocks = false; fDefaultConsistencyChecks = false; fRequireStandard = true; fMineBlocksOnDemand = false; fSkipProofOfWorkCheck = false; fTestnetToBeDeprecatedFieldRPC = false; fHeadersFirstSyncingActive = false; nPoolMaxTransactions = 3; nBudgetCycleBlocks = 4320; strSporkKey = "04f939e9c41b524e82e79080d034fcade7a588a8f02ab28f1047308e45d5a055b7de39a5f0ae4e4249694c4cde65e95cb89d9864eded0047f399f0634622bc571b"; strSporkKeyOld = "04B433E6598390C992F4F022F20D3B4CBBE691652EE7C48243B81701CBDB7CC7D7BF0EE09E154E6FCBF2043D65AF4E9E97B89B5DBAF830D83B9B7F469A6C45A717"; strObfuscationPoolDummyAddress = "Aef8NvJcvuSzunLfgRUwhLvnCaW2rpgcLK"; nStartMasternodePayments = 1643790201; /** Zerocoin */ zerocoinModulus = "25195908475657893494027183240048398571429282126204032027777137836043662020707595556264018525880784" "4069182906412495150821892985591491761845028084891200728449926873928072877767359714183472702618963750149718246911" "6507761337985909570009733045974880842840179742910064245869181719511874612151517265463228221686998754918242243363" "7259085141865462043576798423387184774447920739934236584823824281198163815010674810451660377306056201619676256133" "8441436038339044149526344321901146575444541784240209246165157233507787077498171257724679629263863563732899121548" "31438167899885040445364023527381951378636564391212010397122822120720357"; nMaxZerocoinSpendsPerTransaction = 7; // Assume about 20kb each nMaxZerocoinPublicSpendsPerTransaction = 637; // Assume about 220 bytes each input nMinZerocoinMintFee = 1 * CENT; // high fee required for zerocoin mints nMintRequiredConfirmations = 20; // the maximum amount of confirmations until accumulated in 19 nRequiredAccumulation = 1; nDefaultSecurityLevel = 100; // full security level for accumulators nZerocoinHeaderVersion = 4; // Block headers must be this version once zerocoin is active nZerocoinRequiredStakeDepth = 200; // The required confirmations for a zagr to be stakable nBudget_Fee_Confirmations = 6; // Number of confirmations for the finalization fee nProposalEstablishmentTime = 60 * 60 * 24; // Proposals must be at least a day old to make it into a budget } const Checkpoints::CCheckpointData& Checkpoints() const { return data; } }; static CMainParams mainParams; /** * Testnet (v3) */ class CTestNetParams : public CMainParams { public: CTestNetParams() { networkID = CBaseChainParams::TESTNET; strNetworkID = "test"; pchMessageStart[0] = 0x63; pchMessageStart[1] = 0xe3; pchMessageStart[2] = 0xe0; pchMessageStart[3] = 0x0d; vAlertPubKey = ParseHex("047f692cb9b0694eef8509d45aa8b7432c2730a48ae29f531e2732450ba640dda64ba051daca3dedf795a2d89cdcd66c5f187cf47932f8aa81dd64db7adfe8e236"); nDefaultPort = 61336; nEnforceBlockUpgradeMajority = 0; nRejectBlockOutdatedMajority = 0; nToCheckBlockUpgradeMajority = 0; nMinerThreads = 0; nTargetTimespan = 10 * 60; nTargetSpacing = 10 * 60; nLastPOWBlock = 200; // Hybrid consensus: PoS staking permitted from block 2 in testnet as well. nFirstPoSBlock = 2; nMaturity = 15; nMasternodeCountDrift = 4; // Keep aligned with PoS activation in this chain. nModifierUpdateBlock = 2; nMaxMoneyOut = 43199500 * COIN; nZerocoinStartHeight = 0; nZerocoinStartTime = 1643790201; nBlockEnforceSerialRange = 1; // Enforce serial range starting this block nBlockRecalculateAccumulators = 999999999; // Trigger a recalculation of accumulators nBlockFirstFraudulent = 999999999; // First block that bad serials emerged nBlockLastGoodCheckpoint = 999999999; // Last valid accumulator checkpoint nBlockEnforceInvalidUTXO = 999999999; // Start enforcing the invalid UTXO's nInvalidAmountFiltered = 0; // Amount of invalid coins filtered through exchanges, that should be considered valid nBlockZerocoinV2 = 999999999; //!> The block that zerocoin v2 becomes active nEnforceNewSporkKey = 1643790201; nRejectOldSporkKey = 1522454400; // Public coin spend enforcement nPublicZCSpends = 1; // Fake Serial Attack nFakeSerialBlockheightEnd = -1; nSupplyBeforeFakeSerial = 0; //! Modify the testnet genesis block so the timestamp is valid for a later start. genesis.nTime = 1643790201; genesis.nNonce = 21936323; hashGenesisBlock = genesis.GetHash(); assert(hashGenesisBlock == uint256("0x000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e")); vFixedSeeds.clear(); vSeeds.clear(); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 38); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 39); base58Prefixes[SECRET_KEY] = std::vector(1, 166); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x3a)(0x80)(0x61)(0xa0).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x3a)(0x80)(0x58)(0x37).convert_to_container >(); // Testnet agrarian BIP44 coin type is '1' (All coin's testnet default) base58Prefixes[EXT_COIN_TYPE] = boost::assign::list_of(0x80)(0x00)(0x00)(0x01).convert_to_container >(); convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test)); fMiningRequiresPeers = true; fAllowMinDifficultyBlocks = true; fDefaultConsistencyChecks = false; fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; nPoolMaxTransactions = 2; nBudgetCycleBlocks = 144; //!< Ten cycles per day on testnet strSporkKey = "04ce490c66a62abd3af22be9a561beee84e487dc6b84c22b73928b15f9b305b3785744ad0728588b89808bca7d52f89bf192f36013baf6e57f0428f4c48422fe77"; strSporkKeyOld = "04348C2F50F90267E64FACC65BFDC9D0EB147D090872FB97ABAE92E9A36E6CA60983E28E741F8E7277B11A7479B626AC115BA31463AC48178A5075C5A9319D4A38"; strObfuscationPoolDummyAddress = "GQ7aNidDjkmcfCrHuVzB67Qeh6RV42cusu"; nStartMasternodePayments = 1643790201; nBudget_Fee_Confirmations = 3; // Number of confirmations for the finalization fee. We have to make this very short // here because we only have a 8 block finalization window on testnet nProposalEstablishmentTime = 60 * 5; // Proposals must be at least 5 mns old to make it into a test budget } const Checkpoints::CCheckpointData& Checkpoints() const { return dataTestnet; } }; static CTestNetParams testNetParams; /** * Regression test */ class CRegTestParams : public CTestNetParams { public: CRegTestParams() { networkID = CBaseChainParams::REGTEST; strNetworkID = "regtest"; pchMessageStart[0] = 0x6f; pchMessageStart[1] = 0x94; pchMessageStart[2] = 0x98; pchMessageStart[3] = 0xaa; nDefaultPort = 51476; nSubsidyHalvingInterval = 150; nEnforceBlockUpgradeMajority = 0; nRejectBlockOutdatedMajority = 0; nToCheckBlockUpgradeMajority = 0; nMinerThreads = 1; nTargetTimespan = 24 * 60 * 60; // Agrarian: 1 day nTargetSpacing = 1 * 60; // Agrarian: 1 minutes bnProofOfWorkLimit = ~uint256(0) >> 1; nLastPOWBlock = 250; // Hybrid consensus: PoS staking permitted from block 2 in regtest as well. nFirstPoSBlock = 2; nMaturity = 20; nMasternodeCountDrift = 4; // Keep aligned with PoS activation in this chain. nModifierUpdateBlock = 2; nMaxMoneyOut = 43199500 * COIN; nZerocoinStartHeight = 300; nBlockZerocoinV2 = 300; nZerocoinStartTime = 1643790201; nBlockEnforceSerialRange = 1; // Enforce serial range starting this block nBlockRecalculateAccumulators = 999999999; // Trigger a recalculation of accumulators nBlockFirstFraudulent = 999999999; // First block that bad serials emerged nBlockLastGoodCheckpoint = 999999999; // Last valid accumulator checkpoint // Public coin spend enforcement nPublicZCSpends = 350; // Fake Serial Attack nFakeSerialBlockheightEnd = -1; //! Modify the regtest genesis block so the timestamp is valid for a later start. genesis.nTime = 1643790201; genesis.nNonce = 21936323; hashGenesisBlock = genesis.GetHash(); assert(hashGenesisBlock == uint256("0x000003452250d81f8b07d42e127c92729802e3c48f3c7b9834256fd0fb9a0c2e")); //assert(hashGenesisBlock == uint256("0x17ce7900e21ae0ba9288440bdfcd020bcfb38714717745b4c6a7388990b4764b")); vFixedSeeds.clear(); //! Testnet mode doesn't have any fixed seeds. vSeeds.clear(); //! Testnet mode doesn't have any DNS seeds. fMiningRequiresPeers = false; fAllowMinDifficultyBlocks = true; fDefaultConsistencyChecks = true; fRequireStandard = false; fMineBlocksOnDemand = true; fSkipProofOfWorkCheck = true; fTestnetToBeDeprecatedFieldRPC = false; } const Checkpoints::CCheckpointData& Checkpoints() const { return dataRegtest; } }; static CRegTestParams regTestParams; /** * Unit test */ class CUnitTestParams : public CMainParams, public CModifiableParams { public: CUnitTestParams() { networkID = CBaseChainParams::UNITTEST; strNetworkID = "unittest"; nDefaultPort = 51478; vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds. vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds. fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; fAllowMinDifficultyBlocks = false; fMineBlocksOnDemand = true; } const Checkpoints::CCheckpointData& Checkpoints() const { // UnitTest share the same checkpoints as MAIN return data; } //! Published setters to allow changing values in unit test cases virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval = anSubsidyHalvingInterval; } virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority = anEnforceBlockUpgradeMajority; } virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority = anRejectBlockOutdatedMajority; } virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority = anToCheckBlockUpgradeMajority; } virtual void setDefaultConsistencyChecks(bool afDefaultConsistencyChecks) { fDefaultConsistencyChecks = afDefaultConsistencyChecks; } virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks = afAllowMinDifficultyBlocks; } virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; } }; static CUnitTestParams unitTestParams; static CChainParams* pCurrentParams = 0; CModifiableParams* ModifiableParams() { assert(pCurrentParams); assert(pCurrentParams == &unitTestParams); return (CModifiableParams*)&unitTestParams; } const CChainParams& Params() { assert(pCurrentParams); return *pCurrentParams; } CChainParams& Params(CBaseChainParams::Network network) { switch (network) { case CBaseChainParams::MAIN: return mainParams; case CBaseChainParams::TESTNET: return testNetParams; case CBaseChainParams::REGTEST: return regTestParams; case CBaseChainParams::UNITTEST: return unitTestParams; default: assert(false && "Unimplemented network"); return mainParams; } } void SelectParams(CBaseChainParams::Network network) { SelectBaseParams(network); pCurrentParams = &Params(network); } bool SelectParamsFromCommandLine() { CBaseChainParams::Network network = NetworkIdFromCommandLine(); if (network == CBaseChainParams::MAX_NETWORK_TYPES) return false; SelectParams(network); return true; }