diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 3a9533ff1a..841951f75c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -601,6 +601,145 @@ public: } }; +/** + * Liquid v1 + */ +class CLiquidV1Params : public CChainParams { +public: + CLiquidV1Params() + { + + strNetworkID = "liquidv1"; + consensus.nSubsidyHalvingInterval = 150; + consensus.BIP16Exception = uint256(); + consensus.BIP34Height = 0; + consensus.BIP34Hash = uint256(); + consensus.BIP65Height = 0; + consensus.BIP66Height = 0; + consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks; + consensus.nPowTargetSpacing = 60; // Minute block assumption + consensus.fPowAllowMinDifficultyBlocks = true; + consensus.fPowNoRetargeting = true; + consensus.nRuleChangeActivationThreshold = 108; + consensus.nMinerConfirmationWindow = 144; + + consensus.nMinimumChainWork = uint256(); + consensus.defaultAssumeValid = uint256(); + + nPruneAfterHeight = 1000; + fDefaultConsistencyChecks = false; + fRequireStandard = true; + fMineBlocksOnDemand = false; + m_fallback_fee_enabled = false; // TODO Will this break stuff? + + bech32_hrp = "ex"; // ex(plicit) + blech32_hrp = "lq"; // l(i)q(uid) + parent_bech32_hrp = "bc"; + parent_blech32_hrp = "bc"; // Doesn't exist but... + + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 57); + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 39); + base58Prefixes[SECRET_KEY] = std::vector(1, 128); + base58Prefixes[BLINDED_ADDRESS]= std::vector(1,12); + + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; + + base58Prefixes[PARENT_PUBKEY_ADDRESS] = std::vector(1,0); + base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector(1,5); + + pchMessageStart[0] = 0xfa; + pchMessageStart[1] = 0xbf; + pchMessageStart[2] = 0xb5; + pchMessageStart[3] = 0xda; + + nDefaultPort = 7042; + + vSeeds.clear(); + vSeeds.emplace_back("seed.liquidnetwork.io"); + vFixedSeeds = std::vector(pnSeed6_liquidv1, pnSeed6_liquidv1 + ARRAYLEN(pnSeed6_liquidv1)); + + // + // ELEMENTS fields + + consensus.genesis_style = "elements"; // unused here but let's set it anyways + + // Block signing encumberance script, default of 51 aka OP_TRUE + std::vector sign_bytes = ParseHex("5b21026a2a106ec32c8a1e8052e5d02a7b0a150423dbd9b116fc48d46630ff6e6a05b92102791646a8b49c2740352b4495c118d876347bf47d0551c01c4332fdc2df526f1a2102888bda53a424466b0451627df22090143bbf7c060e9eacb1e38426f6b07f2ae12102aee8967150dee220f613de3b239320355a498808084a93eaf39a34dcd62024852102d46e9259d0a0bb2bcbc461a3e68f34adca27b8d08fbe985853992b4b104e27412102e9944e35e5750ab621e098145b8e6cf373c273b7c04747d1aa020be0af40ccd62102f9a9d4b10a6d6c56d8c955c547330c589bb45e774551d46d415e51cd9ad5116321033b421566c124dfde4db9defe4084b7aa4e7f36744758d92806b8f72c2e943309210353dcc6b4cf6ad28aceb7f7b2db92a4bf07ac42d357adf756f3eca790664314b621037f55980af0455e4fb55aad9b85a55068bb6dc4740ea87276dc693f4598db45fa210384001daa88dabd23db878dbb1ce5b4c2a5fa72c3113e3514bf602325d0c37b8e21039056d089f2fe72dbc0a14780b4635b0dc8a1b40b7a59106325dd1bc45cc70493210397ab8ea7b0bf85bc7fc56bb27bf85e75502e94e76a6781c409f3f2ec3d1122192103b00e3b5b77884bf3cae204c4b4eac003601da75f96982ffcb3dcb29c5ee419b92103c1f3c0874cfe34b8131af34699589aacec4093399739ae352e8a46f80a6f68375fae"); + consensus.signblockscript = CScript(sign_bytes.begin(), sign_bytes.end()); + consensus.max_block_signature_size = 12*74; // 11 signatures plus wiggle room + g_signed_blocks = true; + + g_con_blockheightinheader = true; + g_con_elementswitness = true; + + consensus.genesis_subsidy = 0; + + // All non-zero coinbase outputs must go to this scriptPubKey + std::vector man_bytes = ParseHex("76a914fc26751a5025129a2fd006c6fbfa598ddd67f7e188ac"); + consensus.mandatory_coinbase_destination = CScript(man_bytes.begin(), man_bytes.end()); // Blank script allows any coinbase destination + + // Custom chains connect coinbase outputs to db by default + consensus.connect_genesis_outputs = true; + + initialFreeCoins = 0; + + anyonecanspend_aremine = false; + + consensus.has_parent_chain = true; + + enforce_pak = true; + + multi_data_permitted = true; + + parentGenesisBlockHash = uint256S("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); + const bool parent_genesis_is_null = parentGenesisBlockHash == uint256(); + assert(consensus.has_parent_chain != parent_genesis_is_null); + consensus.parentChainPowLimit = uint256S("0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.parent_chain_signblockscript = CScript(); // It has PoW + consensus.pegin_min_depth = 100; + + const CScript default_script(CScript() << OP_TRUE); + consensus.fedpegScript = StrHexToScriptWithDefault("745c87635b21020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b678172612102675333a4e4b8fb51d9d4e22fa5a8eaced3fdac8a8cbf9be8c030f75712e6af992102896807d54bc55c24981f24a453c60ad3e8993d693732288068a23df3d9f50d4821029e51a5ef5db3137051de8323b001749932f2ff0d34c82e96a2c2461de96ae56c2102a4e1a9638d46923272c266631d94d36bdb03a64ee0e14c7518e49d2f29bc40102102f8a00b269f8c5e59c67d36db3cdc11b11b21f64b4bffb2815e9100d9aa8daf072103079e252e85abffd3c401a69b087e590a9b86f33f574f08129ccbd3521ecf516b2103111cf405b627e22135b3b3733a4a34aa5723fb0f58379a16d32861bf576b0ec2210318f331b3e5d38156da6633b31929c5b220349859cc9ca3d33fb4e68aa08401742103230dae6b4ac93480aeab26d000841298e3b8f6157028e47b0897c1e025165de121035abff4281ff00660f99ab27bb53e6b33689c2cd8dcd364bc3c90ca5aea0d71a62103bd45cddfacf2083b14310ae4a84e25de61e451637346325222747b157446614c2103cc297026b06c71cbfa52089149157b5ff23de027ac5ab781800a578192d175462103d3bde5d63bdb3a6379b461be64dad45eabff42f758543a9645afd42f6d4248282103ed1e8d5109c9ed66f7941bc53cc71137baa76d50d274bda8d5e8ffbd6e61fe9a5f6702c00fb275522103aab896d53a8e7d6433137bbba940f9c521e085dd07e60994579b64a6d992cf79210291b7d0b1b692f8f524516ed950872e5da10fb1b808b5a526dedc6fed1cf29807210386aa9372fbab374593466bc5451dc59954e90787f08060964d95c87ef34ca5bb5368ae", default_script); + + + // Calculate pegged Bitcoin asset + std::vector commit = CommitToArguments(consensus, strNetworkID); + uint256 entropy; + GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash); + + // Elements serialization uses derivation, bitcoin serialization uses 0x00 + if (g_con_elementswitness) { + CalculateAsset(consensus.pegged_asset, entropy); + } else { + assert(consensus.pegged_asset == CAsset()); + } + + consensus.parent_pegged_asset.SetHex("0x00"); // No parent pegged asset + initial_reissuance_tokens = 0; + + consensus.subsidy_asset = consensus.pegged_asset; + + // CSV always active + 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; + // Segwit, likewise + 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; + + + // Finally, create genesis block + genesis = CreateGenesisBlock(consensus, CScript(commit), CScript(OP_RETURN), 1296688602, 2, 0x207fffff, 1, 0); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock.GetHex() == "1466275836220db2944ca059a3a10ef6fd2ea684b0688d2c379296888a206003"); + } + +}; + + static std::unique_ptr globalChainParams; const CChainParams &Params() { @@ -617,6 +756,8 @@ std::unique_ptr CreateChainParams(const std::string& chain) return std::unique_ptr(new CTestNetParams()); else if (chain == CBaseChainParams::REGTEST) return std::unique_ptr(new CRegTestParams(gArgs)); + else if (chain == CBaseChainParams::LIQUID1) + return std::unique_ptr(new CLiquidV1Params()); return std::unique_ptr(new CCustomParams(chain, gArgs)); } diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 9f856be51f..26510ea95f 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -14,6 +14,7 @@ const std::string CBaseChainParams::MAIN = "main"; const std::string CBaseChainParams::TESTNET = "test"; const std::string CBaseChainParams::REGTEST = "regtest"; +const std::string CBaseChainParams::LIQUID1 = "liquidv1"; void SetupChainParamsBaseOptions() { diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 4d3617eb6e..273128178f 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -20,6 +20,7 @@ public: static const std::string MAIN; static const std::string TESTNET; static const std::string REGTEST; + static const std::string LIQUID1; const std::string& DataDir() const { return strDataDir; } int RPCPort() const { return nRPCPort; } diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 4b982a4715..6bc7f85d9c 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -1287,4 +1287,15 @@ static SeedSpec6 pnSeed6_test[] = { {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x47,0xb1,0xe4,0x55,0xd1,0xb0,0x14,0x3f,0xb6,0xdb}, 18333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa0,0x60,0x9e,0x46,0x54,0xdb,0x61,0x3b,0xb2,0x6f}, 18333} }; + +static SeedSpec6 pnSeed6_liquidv1[] = { + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xc4,0x10,0xfe}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xed,0xb0,0x3f}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xed,0x51,0x0e}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xed,0x93,0x15}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xe3,0x5f,0x6d}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xe7,0x8d,0xad}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc4,0x30,0xb8}, 7042}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xe7,0x0a,0x93}, 7042} +}; #endif // BITCOIN_CHAINPARAMSSEEDS_H