2013-05-07 15:16:25 +02:00
|
|
|
// Copyright (c) 2010 Satoshi Nakamoto
|
2016-12-31 11:01:21 -07:00
|
|
|
// Copyright (c) 2009-2016 The Bitcoin Core developers
|
2014-10-25 17:24:16 +08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-05-07 15:16:25 +02:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
|
|
#include "chainparams.h"
|
2015-11-17 17:35:44 +01:00
|
|
|
#include "consensus/merkle.h"
|
2017-08-09 16:48:13 -04:00
|
|
|
#include "issuance.h"
|
2013-04-13 00:13:08 -05:00
|
|
|
|
2015-06-30 21:39:49 +02:00
|
|
|
#include "tinyformat.h"
|
2013-05-07 15:16:25 +02:00
|
|
|
#include "util.h"
|
2014-09-24 23:32:36 -04:00
|
|
|
#include "utilstrencodings.h"
|
2016-03-14 16:27:43 -07:00
|
|
|
#include "amount.h"
|
2017-08-17 15:18:25 -07:00
|
|
|
#include "crypto/sha256.h"
|
2013-05-07 15:16:25 +02:00
|
|
|
|
2014-08-28 22:56:53 +02:00
|
|
|
#include <assert.h>
|
|
|
|
|
|
2013-06-23 02:33:47 +02:00
|
|
|
#include <boost/assign/list_of.hpp>
|
|
|
|
|
|
2016-12-23 09:12:47 -05:00
|
|
|
// Safer for users if they load incorrect parameters via arguments.
|
|
|
|
|
static std::vector<unsigned char> CommitToArguments(const Consensus::Params& params, const std::string& networkID, const CScript& signblockscript)
|
|
|
|
|
{
|
2017-08-17 15:18:25 -07:00
|
|
|
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<unsigned char>(commitment, commitment + 32);
|
2016-12-23 09:12:47 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-23 03:02:40 +02:00
|
|
|
static CScript StrHexToScriptWithDefault(std::string strScript, const CScript defaultScript)
|
|
|
|
|
{
|
|
|
|
|
CScript returnScript;
|
|
|
|
|
if (!strScript.empty()) {
|
|
|
|
|
std::vector<unsigned char> scriptData = ParseHex(strScript);
|
|
|
|
|
returnScript = CScript(scriptData.begin(), scriptData.end());
|
|
|
|
|
} else {
|
|
|
|
|
returnScript = defaultScript;
|
|
|
|
|
}
|
|
|
|
|
return returnScript;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-15 10:06:55 -04:00
|
|
|
static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion)
|
2015-07-03 14:29:57 +02:00
|
|
|
{
|
|
|
|
|
CMutableTransaction txNew;
|
|
|
|
|
txNew.nVersion = 1;
|
|
|
|
|
txNew.vin.resize(1);
|
2016-12-23 09:12:47 -05:00
|
|
|
// 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));
|
2017-09-15 10:06:55 -04:00
|
|
|
txNew.vout.clear();
|
|
|
|
|
txNew.vout.push_back(CTxOut(CAsset(), 0, CScript() << OP_RETURN));
|
2015-07-03 14:29:57 +02:00
|
|
|
|
|
|
|
|
CBlock genesis;
|
|
|
|
|
genesis.nTime = nTime;
|
2016-03-18 21:39:01 -07:00
|
|
|
genesis.proof = CProof(scriptChallenge, CScript());
|
2015-07-03 14:29:57 +02:00
|
|
|
genesis.nVersion = nVersion;
|
2016-11-10 17:34:17 -08:00
|
|
|
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
|
2015-07-03 14:29:57 +02:00
|
|
|
genesis.hashPrevBlock.SetNull();
|
2015-11-17 17:35:44 +01:00
|
|
|
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
|
2015-07-03 14:29:57 +02:00
|
|
|
return genesis;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-15 10:06:55 -04:00
|
|
|
/** 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);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-22 03:50:01 +02:00
|
|
|
void CChainParams::UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
|
|
|
|
|
{
|
|
|
|
|
consensus.vDeployments[d].nStartTime = nStartTime;
|
|
|
|
|
consensus.vDeployments[d].nTimeout = nTimeout;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-25 17:24:16 +08:00
|
|
|
/**
|
2018-02-19 07:40:27 +01:00
|
|
|
* Custom chain params
|
2014-10-25 17:24:16 +08:00
|
|
|
*/
|
2018-02-19 07:40:27 +01:00
|
|
|
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"));
|
2018-03-28 11:40:20 -04:00
|
|
|
consensus.pegin_min_depth = GetArg("-peginconfirmationdepth", DEFAULT_PEGIN_CONFIRMATION_DEPTH);
|
2018-04-02 12:14:20 -07:00
|
|
|
consensus.mandatory_coinbase_destination = StrHexToScriptWithDefault(GetArg("-con_mandatorycoinbase", ""), CScript()); // Blank script allows any coinbase destination
|
2018-03-12 20:40:44 +01:00
|
|
|
// bitcoin regtest is the parent chain by default
|
|
|
|
|
parentGenesisBlockHash = uint256S(GetArg("-parentgenesisblockhash", "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
|
2018-02-19 07:40:27 +01:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-07 15:16:25 +02:00
|
|
|
public:
|
2018-02-19 07:40:27 +01:00
|
|
|
CCustomParams(const std::string& chain) : CChainParams(chain)
|
|
|
|
|
{
|
|
|
|
|
this->UpdateFromArgs();
|
|
|
|
|
|
2016-06-23 11:50:34 +02:00
|
|
|
const CScript defaultRegtestScript(CScript() << OP_TRUE);
|
|
|
|
|
CScript genesisChallengeScript = StrHexToScriptWithDefault(GetArg("-signblockscript", ""), defaultRegtestScript);
|
2016-03-22 23:06:10 +01:00
|
|
|
consensus.fedpegScript = StrHexToScriptWithDefault(GetArg("-fedpegscript", ""), defaultRegtestScript);
|
2016-06-23 11:50:34 +02:00
|
|
|
|
2016-03-09 16:00:53 -05:00
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
|
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
|
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL;
|
2016-02-20 23:37:13 +01:00
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
|
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
|
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL;
|
2015-11-06 01:42:38 +01:00
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
|
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0;
|
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL;
|
2015-07-29 21:13:36 +02:00
|
|
|
|
2013-05-07 15:16:25 +02:00
|
|
|
pchMessageStart[0] = 0xfa;
|
|
|
|
|
pchMessageStart[1] = 0xbf;
|
|
|
|
|
pchMessageStart[2] = 0xb5;
|
|
|
|
|
pchMessageStart[3] = 0xda;
|
|
|
|
|
|
2017-08-09 16:48:13 -04:00
|
|
|
// Generate pegged Bitcoin asset
|
2017-08-17 15:18:25 -07:00
|
|
|
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID, genesisChallengeScript);
|
2017-08-09 16:48:13 -04:00
|
|
|
uint256 entropy;
|
2017-08-17 15:18:25 -07:00
|
|
|
GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash);
|
2017-08-09 16:48:13 -04:00
|
|
|
CalculateAsset(consensus.pegged_asset, entropy);
|
2017-08-09 16:17:26 -04:00
|
|
|
|
2017-09-15 10:06:55 -04:00
|
|
|
genesis = CreateGenesisBlock(consensus, strNetworkID, 1296688602, genesisChallengeScript, 1);
|
|
|
|
|
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, 100, 21000000000000, 0, 0, CScript() << OP_TRUE);
|
2015-07-29 21:13:36 +02:00
|
|
|
consensus.hashGenesisBlock = genesis.GetHash();
|
|
|
|
|
|
2016-08-15 11:06:05 -04:00
|
|
|
|
2016-03-26 16:13:39 -07:00
|
|
|
|
2016-04-03 11:49:36 +02:00
|
|
|
vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
|
|
|
|
|
vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds.
|
2013-05-07 15:16:25 +02:00
|
|
|
|
2015-06-05 15:36:34 -04:00
|
|
|
checkpointData = (CCheckpointData){
|
2015-04-23 18:30:55 -04:00
|
|
|
boost::assign::map_list_of
|
2015-07-01 19:02:51 +02:00
|
|
|
( 0, consensus.hashGenesisBlock),
|
2017-01-04 07:31:56 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
chainTxData = ChainTxData{
|
2015-04-23 18:30:55 -04:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0
|
|
|
|
|
};
|
2017-01-10 10:28:26 -05:00
|
|
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,235);
|
2017-07-07 16:10:53 -04:00
|
|
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,75);
|
2017-01-10 10:28:26 -05:00
|
|
|
base58Prefixes[BLINDED_ADDRESS]= std::vector<unsigned char>(1,4);
|
2015-07-03 14:30:18 +02:00
|
|
|
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> >();
|
2017-01-10 10:28:26 -05:00
|
|
|
|
|
|
|
|
base58Prefixes[PARENT_PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
|
|
|
|
|
base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
|
2014-08-31 21:32:23 +02:00
|
|
|
}
|
2013-05-07 15:16:25 +02:00
|
|
|
};
|
|
|
|
|
|
2018-02-17 08:49:49 +01:00
|
|
|
/**
|
|
|
|
|
* Use base58 and other old configurations for outdated unittests
|
|
|
|
|
*/
|
2018-02-19 07:40:27 +01:00
|
|
|
class CMainParams : public CCustomParams {
|
2018-02-17 08:49:49 +01:00
|
|
|
public:
|
2018-02-21 01:11:42 +01:00
|
|
|
CMainParams(const std::string& chain) : CCustomParams(chain)
|
2018-02-17 08:49:49 +01:00
|
|
|
{
|
|
|
|
|
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<unsigned char>(1,0);
|
|
|
|
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
|
|
|
|
|
base58Prefixes[BLINDED_ADDRESS]= std::vector<unsigned char>(1,11);
|
|
|
|
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
|
|
|
|
|
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> >();
|
|
|
|
|
base58Prefixes[PARENT_PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
|
|
|
|
|
base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-08 16:04:37 -08:00
|
|
|
|
2017-06-21 20:36:26 +09:00
|
|
|
const std::vector<std::string> CChainParams::supportedChains =
|
|
|
|
|
boost::assign::list_of
|
|
|
|
|
( CHAINPARAMS_REGTEST )
|
2016-02-08 16:04:37 -08:00
|
|
|
;
|
|
|
|
|
|
2015-05-22 03:50:01 +02:00
|
|
|
static std::unique_ptr<CChainParams> globalChainParams;
|
2013-05-07 15:16:25 +02:00
|
|
|
|
|
|
|
|
const CChainParams &Params() {
|
2015-05-22 03:50:01 +02:00
|
|
|
assert(globalChainParams);
|
|
|
|
|
return *globalChainParams;
|
2013-05-07 15:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
2015-05-22 03:50:01 +02:00
|
|
|
std::unique_ptr<CChainParams> CreateChainParams(const std::string& chain)
|
2015-06-30 21:39:49 +02:00
|
|
|
{
|
|
|
|
|
if (chain == CBaseChainParams::MAIN)
|
2018-02-21 01:11:42 +01:00
|
|
|
return std::unique_ptr<CChainParams>(new CMainParams(chain));
|
2018-02-19 07:40:27 +01:00
|
|
|
return std::unique_ptr<CChainParams>(new CCustomParams(chain));
|
2015-05-22 03:50:01 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-30 21:39:49 +02:00
|
|
|
void SelectParams(const std::string& network)
|
|
|
|
|
{
|
2014-08-02 19:54:57 +01:00
|
|
|
SelectBaseParams(network);
|
2015-05-22 03:50:01 +02:00
|
|
|
globalChainParams = CreateChainParams(network);
|
2014-08-02 19:54:57 +01:00
|
|
|
}
|
2016-07-25 17:22:37 -04:00
|
|
|
|
2015-05-22 03:50:01 +02:00
|
|
|
void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
|
2016-07-25 17:22:37 -04:00
|
|
|
{
|
2015-05-22 03:50:01 +02:00
|
|
|
globalChainParams->UpdateBIP9Parameters(d, nStartTime, nTimeout);
|
2016-07-25 17:22:37 -04:00
|
|
|
}
|
2015-11-06 01:42:38 +01:00
|
|
|
|