Esempio n. 1
0
        public CityRegTest()
        {
            this.Name                  = "CityRegTest";
            this.NetworkType           = NetworkType.Regtest;
            this.Magic                 = 0x43525901; // .CRT
            this.DefaultPort           = 14333;
            this.DefaultRPCPort        = 14334;
            this.DefaultAPIPort        = 14335;
            this.MinTxFee              = 0;
            this.FallbackFee           = 0;
            this.MinRelayTxFee         = 0;
            this.CoinTicker            = "TCITY";
            this.DefaultBanTimeSeconds = 16000; // 500 (MaxReorg) * 64 (TargetSpacing) / 2 = 4 hours, 26 minutes and 40 seconds

            var powLimit = new Target(new uint256("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            this.GenesisTime    = 1538568000; // 10/03/2018 @ 12:00pm (UTC)
            this.GenesisNonce   = 82501;
            this.GenesisBits    = 0x1F00FFFF;
            this.GenesisVersion = 1;
            this.GenesisReward  = Money.Zero;

            // 2018-07-26: "We don’t need to fight the existing system, we just need to create a new one."
            // https://futurethinkers.org/vit-jedlicka-liberland/
            string pszTimestamp = "July 26, 2018, Future Thinkers, We don’t need to fight existing system, we create a new one";

            Block genesisBlock = CreateCityGenesisBlock(pszTimestamp, consensusFactory, this.GenesisTime, this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward);

            //genesisBlock.Header.Time = 1494909211;
            //genesisBlock.Header.Nonce = 2433759;
            //genesisBlock.Header.Bits = powLimit;

            this.Genesis = genesisBlock;

            var consensusOptions = new CityPosConsensusOptions(
                maxBlockBaseSize: 1_000_000,
                maxStandardVersion: 2,
                maxStandardTxWeight: 100_000,
                maxBlockSigopsCost: 20_000,
                maxStandardTxSigopsCost: 20_000 / 5
                );

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            var bip9Deployments = new CityBIP9Deployments()
            {
                [CityBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters(2,
                                                                                  new DateTime(2018, 12, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                  new DateTime(2019, 12, 1, 0, 0, 0, DateTimeKind.Utc))
            };

            this.Consensus = new Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: 1926,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 210000,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: bip9Deployments,
                bip34Hash: new uint256("0x0000da5d40883d6c8aade797d8d6dcbf5cbc8e6428569170da39d2f01e8290e5"),
                ruleChangeActivationThreshold: 1916, // 95% of 2016
                minerConfirmationWindow: 2016,       // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: null,            // turn off assumevalid for regtest.
                maxMoney: long.MaxValue,
                coinbaseMaturity: 10,
                premineHeight: 2,
                premineReward: Money.Coins(13736000000),
                proofOfWorkReward: Money.Coins(2),
                powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
                powAllowMinDifficultyBlocks: true,
                posNoRetargeting: false,
                powNoRetargeting: true,
                powLimit: powLimit,
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: 125000,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(20)
                );

            this.Checkpoints = new Dictionary <int, CheckpointInfo>();

            this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (66) };
            this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (196) };
            this.Base58Prefixes[(int)Base58Type.SECRET_KEY]     = new byte[] { (66 + 128) };

            this.DNSSeeds = new List <DNSSeedData>
            {
                new DNSSeedData("city-chain.org", "regtestseed.city-chain.org"),
                new DNSSeedData("city-coin.org", "regtestseed.city-coin.org"),
                new DNSSeedData("citychain.foundation", "regtestseed.citychain.foundation")
            };

            this.SeedNodes = new List <NetworkAddress>
            {
                new NetworkAddress(IPAddress.Parse("13.73.143.193"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("40.115.2.6"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("13.66.158.6"), this.DefaultPort),
            };

            this.StandardScriptsRegistry = new CityStandardScriptsRegistry();

            // 64 below should be changed to TargetSpacingSeconds when we move that field.
            Assert(this.DefaultBanTimeSeconds <= this.Consensus.MaxReorgLength * 64 / 2);
            Assert(this.Consensus.HashGenesisBlock == uint256.Parse("0x0000da5d40883d6c8aade797d8d6dcbf5cbc8e6428569170da39d2f01e8290e5"));
            Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("0x49f8ad9e1d47aec09a38b7b54e282ed0ba30099b8632152931be74e2865266d5"));

            this.RegisterRules(this.Consensus);
        }
Esempio n. 2
0
        public CityTest()
        {
            // START MODIFICATIONS OF GENERATED CODE
            var consensusOptions = new CityPosConsensusOptions
            {
                MaxBlockBaseSize        = 1_000_000,
                MaxStandardVersion      = 2,
                MaxStandardTxWeight     = 100_000,
                MaxBlockSigopsCost      = 20_000,
                MaxStandardTxSigopsCost = 20_000 / 5,
                WitnessScaleFactor      = 4
            };
            // END MODIFICATIONS

            CoinSetup    setup   = CitySetup.Instance.Setup;
            NetworkSetup network = CitySetup.Instance.Test;

            NetworkType = NetworkType.Testnet;

            Name           = network.Name;
            CoinTicker     = network.CoinTicker;
            Magic          = ConversionTools.ConvertToUInt32(setup.Magic, true);
            RootFolderName = network.RootFolderName;
            DefaultPort    = network.DefaultPort;
            DefaultRPCPort = network.DefaultRPCPort;
            DefaultAPIPort = network.DefaultAPIPort;

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            GenesisTime    = network.GenesisTime;
            GenesisNonce   = network.GenesisNonce;
            GenesisBits    = network.GenesisBits;
            GenesisVersion = network.GenesisVersion;
            GenesisReward  = network.GenesisReward;

            Block genesisBlock = CreateGenesisBlock(consensusFactory,
                                                    GenesisTime,
                                                    GenesisNonce,
                                                    GenesisBits,
                                                    GenesisVersion,
                                                    GenesisReward,
                                                    setup.GenesisText);

            Genesis = genesisBlock;

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            var bip9Deployments = new CityBIP9Deployments()
            {
                [CityBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters("ColdStaking", 2,
                                                                                  new DateTime(2018, 12, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                  new DateTime(2019, 12, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                  BIP9DeploymentsParameters.DefaultMainnetThreshold)
            };

            consensusFactory.Protocol = new ConsensusProtocol()
            {
                ProtocolVersion    = ProtocolVersion.FEEFILTER_VERSION,
                MinProtocolVersion = ProtocolVersion.POS_PROTOCOL_VERSION,
            };

            Consensus = new Blockcore.Consensus.Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: setup.CoinType,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 24333,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: bip9Deployments,
                bip34Hash: null,
                minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: null,
                maxMoney: long.MaxValue,
                coinbaseMaturity: 10,
                premineHeight: 2,
                premineReward: Money.Coins(setup.PremineReward),
                proofOfWorkReward: Money.Coins(setup.PoWBlockReward),
                targetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                targetSpacing: setup.TargetSpacing,
                powAllowMinDifficultyBlocks: false,
                posNoRetargeting: false,
                powNoRetargeting: false,
                powLimit: new Target(new uint256("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: setup.LastPowBlock,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(setup.PoSBlockReward),
                proofOfStakeTimestampMask: setup.ProofOfStakeTimestampMask
                );

            Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (byte)network.PubKeyAddress };
            Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (byte)network.ScriptAddress };
            Base58Prefixes[(int)Base58Type.SECRET_KEY]     = new byte[] { (239) };
            Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY] = new byte[] { (0x04), (0x35), (0x87), (0xCF) };
            Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY] = new byte[] { (0x04), (0x35), (0x83), (0x94) };
            Base58Prefixes[(int)Base58Type.ASSET_ID]       = new byte[] { 115 };

            Bech32Encoders = new Bech32Encoder[2];
            var encoder = new Bech32Encoder(network.CoinTicker.ToLowerInvariant());

            Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
            Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;

            Checkpoints = network.Checkpoints;
            DNSSeeds    = network.DNS.Select(dns => new DNSSeedData(dns, dns)).ToList();
            SeedNodes   = network.Nodes.Select(node => new NBitcoin.Protocol.NetworkAddress(IPAddress.Parse(node), network.DefaultPort)).ToList();

            StandardScriptsRegistry = new CityStandardScriptsRegistry();

            // 64 below should be changed to TargetSpacingSeconds when we move that field.
            Assert(DefaultBanTimeSeconds <= Consensus.MaxReorgLength * 64 / 2);

            Assert(Consensus.HashGenesisBlock == uint256.Parse(network.HashGenesisBlock));
            Assert(Genesis.Header.HashMerkleRoot == uint256.Parse(network.HashMerkleRoot));

            RegisterRules(Consensus);
            RegisterMempoolRules(Consensus);
        }
    }
Esempio n. 3
0
        public CityMain()
        {
            this.Name  = "CityMain";
            this.Magic = 0x43545901; // .CTY
            this.DefaultMaxOutboundConnections = 16;
            this.DefaultMaxInboundConnections  = 109;
            this.DefaultPort           = 4333;
            this.RPCPort               = 4334;
            this.MaxTipAge             = 2 * 60 * 60;
            this.MinTxFee              = 10000;
            this.FallbackFee           = 10000;
            this.MinRelayTxFee         = 10000;
            this.RootFolderName        = CityRootFolderName;
            this.DefaultConfigFilename = CityDefaultConfigFilename;
            this.MaxTimeOffsetSeconds  = 25 * 60;
            this.CoinTicker            = "CITY";

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            this.GenesisTime    = 1538481600; // 10/02/2018 @ 12:00pm (UTC)
            this.GenesisNonce   = 1626464;
            this.GenesisBits    = 0x1E0FFFFF;
            this.GenesisVersion = 1;
            this.GenesisReward  = Money.Zero;

            // 2018-07-27: "Bitcoin’s roots are in anarcho-capitalism, a movement that aspires to reproduce the mechanisms of the free market without the need for banks or state bodies to enforce rules."
            // https://www.newscientist.com/article/mg23831841-200-how-to-think-about-the-blockchain/
            string pszTimestamp = "July 27, 2018, New Scientiest, Bitcoin’s roots are in anarcho-capitalism";

            Block genesisBlock = CreateCityGenesisBlock(pszTimestamp, consensusFactory, this.GenesisTime, this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward);

            this.Genesis = genesisBlock;

            var consensusOptions = new PosConsensusOptions(
                maxBlockBaseSize: 1_000_000,
                maxStandardVersion: 2,
                maxStandardTxWeight: 100_000,
                maxBlockSigopsCost: 20_000,
                maxStandardTxSigopsCost: 20_000 / 5
                );

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            var bip9Deployments = new CityBIP9Deployments()
            {
                [CityBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters(2,
                                                                                  new DateTime(2018, 12, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                  new DateTime(2019, 12, 1, 0, 0, 0, DateTimeKind.Utc))
            };

            this.Consensus = new Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: 1926,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 210000,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: bip9Deployments,
                bip34Hash: new uint256("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"),
                ruleChangeActivationThreshold: 1916, // 95% of 2016
                minerConfirmationWindow: 2016,       // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: new uint256("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"),
                maxMoney: long.MaxValue,
                coinbaseMaturity: 50,
                premineHeight: 2,
                premineReward: Money.Coins(13736000000),
                proofOfWorkReward: Money.Coins(2),                          // Produced up until last POW block.
                powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
                powAllowMinDifficultyBlocks: false,
                powNoRetargeting: false,
                powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: 2500,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(20)
                );

            this.Base58Prefixes = new byte[12][];
            this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS]             = new byte[] { (28) };  // P2PKH: C, list: https://en.bitcoin.it/wiki/List_of_address_prefixes
            this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS]             = new byte[] { (88) };  // P2SH: c
            this.Base58Prefixes[(int)Base58Type.SECRET_KEY]                 = new byte[] { (237) }; // WIF: c (compressed, 8 uncompressed), initial character for compressed private key in WIF format.
            this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] { 0x01, 0x42 };
            this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC]    = new byte[] { 0x01, 0x43 };
            this.Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY]             = new byte[] { (0x04), (0x88), (0xB2), (0x1E) };
            this.Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY]             = new byte[] { (0x04), (0x88), (0xAD), (0xE4) };
            this.Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE]            = new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 };
            this.Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE]          = new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A };
            this.Base58Prefixes[(int)Base58Type.STEALTH_ADDRESS]            = new byte[] { 0x2a };
            this.Base58Prefixes[(int)Base58Type.ASSET_ID]        = new byte[] { 23 };
            this.Base58Prefixes[(int)Base58Type.COLORED_ADDRESS] = new byte[] { 0x13 };

            this.Checkpoints = new Dictionary <int, CheckpointInfo>
            {
                { 0, new CheckpointInfo(new uint256("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
                { 2, new CheckpointInfo(new uint256("0x072227af2fda8ef6a5f7a19ec3a1c6de54ddc537dd407da938766ed460e77982"), new uint256("0xe93eb6c21c65024ca06ac2f89481bdc832cab1607ed2adfeafb6c679b6a4a1f6")) },
                { 50, new CheckpointInfo(new uint256("0xce58ab37dd5965c3474c5917fcbb59aa342c6754a452e5faf87050bb6015d511"), new uint256("0xb877b17b3d7324ac1a3615a6c245c702282e5be74fd50cf25bb02bc5f2ea7944")) },
                { 100, new CheckpointInfo(new uint256("0x5edbf09aadfbdb0d74d428b002fcda197debb775955a161f2890ed844a5159da"), new uint256("0x354210eecb7ed3f8df3d384b8d615f789fdffdf3f3d4945c23e5966827010b73")) },
                { 200, new CheckpointInfo(new uint256("0x180745aeb0754cde04dac52dbb056dac5b1c665de86ee23806c1c7675dac3ac9"), new uint256("0x7f5dfec171542e5d2b56e874eb4f1e26c949e8a33a64e3fe0b06f1b5783fbd54")) },
                { 1000, new CheckpointInfo(new uint256("0xc848602fe0f33511766b66c6d5a28e11cd54e7c61d69c0898f868f46b5c9d6f7"), new uint256("0x13fad5f4e1dc5120f88e48e3f8d08bbc57b78fa960df8b600819c631f1038327")) },
                { 2000, new CheckpointInfo(new uint256("0xe73ec56e8c4159594bea6e8d73f1a5e0c980246861064451e2f0d2f609ed7d0b"), new uint256("0x569ab17ece910f954d26f3ab8a83ec5ae8952957b3f1c1868fb7b04abd52dd19")) },
                { 10000, new CheckpointInfo(new uint256("0x5fba1895ca1134f3c6fefdd45996039d45aab0177a10e86cac4990226f62ad95"), new uint256("0x47c6db50a945d8d4b17676e65a74ccd64e3b73f696082c3cdb7a9c0b9658e9cb")) },
                { 20000, new CheckpointInfo(new uint256("0xa0f81a7734e621ae2e2cecea7a3b851dee3b5a85ba4732e0867cbf5c496f04ed"), new uint256("0xf044e402b75b4314231e1498fefc8b11da8cc9cb7797e2e59b2acdbcea1b02b3")) },
                { 40000, new CheckpointInfo(new uint256("0xd3fc0976cb034b1e3eccdd6c4ebb76c0933ea37c47d43831371880346b9200b8"), new uint256("0x03a09ede5eadd8dbbc36806ef530c21c5548a7a823cf173c97439576dcb4d26d")) },
            };

            var encoder = new Bech32Encoder("bc");

            this.Bech32Encoders = new Bech32Encoder[2];
            this.Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
            this.Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;

            this.DNSSeeds = new List <DNSSeedData>
            {
                new DNSSeedData("city-chain.org", "seed.city-chain.org"),
                new DNSSeedData("city-coin.org", "seed.city-coin.org"),
                new DNSSeedData("citychain.foundation", "seed.citychain.foundation"),
                new DNSSeedData("liberstad.com", "seed.liberstad.com")
            };

            this.SeedNodes = new List <NetworkAddress>
            {
                new NetworkAddress(IPAddress.Parse("52.175.194.227"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("13.73.143.193"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("40.115.2.6"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("13.66.158.6"), this.DefaultPort),
            };

            Assert(this.Consensus.HashGenesisBlock == uint256.Parse("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"));
            Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("0xb3425d46594a954b141898c7eebe369c6e6a35d2dab393c1f495504d2147883b"));
        }
Esempio n. 4
0
        public CityMain()
        {
            // START MODIFICATIONS OF GENERATED CODE
            var consensusOptions = new CityPosConsensusOptions
            {
                MaxBlockBaseSize        = 1_000_000,
                MaxStandardVersion      = 2,
                MaxStandardTxWeight     = 100_000,
                MaxBlockSigopsCost      = 20_000,
                MaxStandardTxSigopsCost = 20_000 / 5,
                WitnessScaleFactor      = 4
            };

            // END MODIFICATIONS

            CoinSetup    setup   = CitySetup.Instance.Setup;
            NetworkSetup network = CitySetup.Instance.Main;

            NetworkType           = NetworkType.Mainnet;
            DefaultConfigFilename = setup.ConfigFileName; // The default name used for the City configuration file.

            Name           = network.Name;
            CoinTicker     = network.CoinTicker;
            Magic          = ConversionTools.ConvertToUInt32(setup.Magic);
            RootFolderName = network.RootFolderName;
            DefaultPort    = network.DefaultPort;
            DefaultRPCPort = network.DefaultRPCPort;
            DefaultAPIPort = network.DefaultAPIPort;

            DefaultMaxOutboundConnections = 16;
            DefaultMaxInboundConnections  = 109;
            MaxTipAge             = 2 * 60 * 60;
            MinTxFee              = 10000;
            MaxTxFee              = Money.Coins(1).Satoshi;
            FallbackFee           = 10000;
            MinRelayTxFee         = 10000;
            MaxTimeOffsetSeconds  = 25 * 60;
            DefaultBanTimeSeconds = 16000; // 500 (MaxReorg) * 64 (TargetSpacing) / 2 = 4 hours, 26 minutes and 40 seconds

            var consensusFactory = new PosConsensusFactory();

            GenesisTime    = network.GenesisTime;
            GenesisNonce   = network.GenesisNonce;
            GenesisBits    = network.GenesisBits;
            GenesisVersion = network.GenesisVersion;
            GenesisReward  = network.GenesisReward;

            Block genesisBlock = CreateGenesisBlock(consensusFactory,
                                                    GenesisTime,
                                                    GenesisNonce,
                                                    GenesisBits,
                                                    GenesisVersion,
                                                    GenesisReward,
                                                    setup.GenesisText);

            Genesis = genesisBlock;

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            var bip9Deployments = new CityBIP9Deployments()
            {
                [CityBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters("ColdStaking", 2,
                                                                                  new DateTime(2018, 12, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                  new DateTime(2019, 12, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                  BIP9DeploymentsParameters.DefaultMainnetThreshold)
            };

            consensusFactory.Protocol = new ConsensusProtocol()
            {
                ProtocolVersion    = ProtocolVersion.FEEFILTER_VERSION,
                MinProtocolVersion = ProtocolVersion.POS_PROTOCOL_VERSION,
            };

            Consensus = new Blockcore.Consensus.Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: setup.CoinType,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 24333,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: bip9Deployments,
                bip34Hash: null,
                minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: null,
                maxMoney: long.MaxValue,
                coinbaseMaturity: 50,
                premineHeight: 2,
                premineReward: Money.Coins(setup.PremineReward),
                proofOfWorkReward: Money.Coins(setup.PoWBlockReward),
                targetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                targetSpacing: setup.TargetSpacing,
                powAllowMinDifficultyBlocks: false,
                posNoRetargeting: false,
                powNoRetargeting: false,
                powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: setup.LastPowBlock,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(setup.PoSBlockReward),
                proofOfStakeTimestampMask: setup.ProofOfStakeTimestampMask
                );

            Consensus.PosEmptyCoinbase            = CitySetup.Instance.IsPoSv3();
            Consensus.PosUseTimeFieldInKernalHash = CitySetup.Instance.IsPoSv3();

            // TODO: Set your Base58Prefixes
            Base58Prefixes = new byte[12][];
            Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (byte)network.PubKeyAddress };
            Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (byte)network.ScriptAddress };
            Base58Prefixes[(int)Base58Type.SECRET_KEY]     = new byte[] { (byte)network.SecretAddress };

            Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] { 0x01, 0x42 };
            Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC]    = new byte[] { 0x01, 0x43 };
            Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY]             = new byte[] { (0x04), (0x88), (0xB2), (0x1E) };
            Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY]             = new byte[] { (0x04), (0x88), (0xAD), (0xE4) };
            Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE]            = new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 };
            Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE]          = new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A };
            Base58Prefixes[(int)Base58Type.ASSET_ID] = new byte[] { 23 };

            Bech32Encoders = new Bech32Encoder[2];
            var encoder = new Bech32Encoder(network.CoinTicker.ToLowerInvariant());

            Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
            Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;

            Checkpoints = network.Checkpoints;
            DNSSeeds    = network.DNS.Select(dns => new DNSSeedData(dns, dns)).ToList();
            SeedNodes   = network.Nodes.Select(node => new NBitcoin.Protocol.NetworkAddress(IPAddress.Parse(node), network.DefaultPort)).ToList();

            StandardScriptsRegistry = new CityStandardScriptsRegistry();

            // 64 below should be changed to TargetSpacingSeconds when we move that field.
            Assert(DefaultBanTimeSeconds <= Consensus.MaxReorgLength * 64 / 2);

            Assert(Consensus.HashGenesisBlock == uint256.Parse(network.HashGenesisBlock));
            Assert(Genesis.Header.HashMerkleRoot == uint256.Parse(network.HashMerkleRoot));

            RegisterRules(Consensus);
            RegisterMempoolRules(Consensus);
        }
Esempio n. 5
0
        public CityTest()
        {
            this.Name        = "CityTest";
            this.Magic       = 0x43545401; // .CTT
            this.DefaultPort = 24333;
            this.RPCPort     = 24334;
            this.CoinTicker  = "TCITY";

            var powLimit = new Target(new uint256("0000ffff00000000000000000000000000000000000000000000000000000000"));

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            this.GenesisTime    = 1538395200; // 10/01/2018 @ 12:00pm (UTC)
            this.GenesisNonce   = 6967;
            this.GenesisBits    = 0x1F0FFFFF;
            this.GenesisVersion = 1;
            this.GenesisReward  = Money.Zero;

            // 2017-08-18: "Libertarianisme er en politisk tankeretning som legger stor vekt på individuell frihet, og prosjektet er blitt omtalt over hele verden på sentrale nettsider for folk som handler med kryptovalutaer, altså penger og sikre verdipapirer som fungerer helt uten en sentral myndighet."
            // https://morgenbladet.no/aktuelt/2017/08/privatlivets-fred-i-liberstad
            string pszTimestamp = "August 18 2017, Morgenbladet, Money that work without a central authority";

            Block genesisBlock = CreateCityGenesisBlock(pszTimestamp, consensusFactory, this.GenesisTime, this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward);

            //genesisBlock.Header.Time = 1493909211;
            //genesisBlock.Header.Nonce = 2433759;
            //genesisBlock.Header.Bits = powLimit;

            this.Genesis = genesisBlock;

            var consensusOptions = new CityPosConsensusOptions(
                maxBlockBaseSize: 1_000_000,
                maxStandardVersion: 2,
                maxStandardTxWeight: 100_000,
                maxBlockSigopsCost: 20_000,
                maxStandardTxSigopsCost: 20_000 / 5
                );

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            var bip9Deployments = new CityBIP9Deployments();

            this.Consensus = new Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: 1926,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 210000,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: bip9Deployments,
                bip34Hash: new uint256("0x00077765f625cc2cb6266544ff7d5a462f25be14ea1116dc2bd2fec17e40a5e3"),
                ruleChangeActivationThreshold: 1916, // 95% of 2016
                minerConfirmationWindow: 2016,       // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: new uint256("0x00077765f625cc2cb6266544ff7d5a462f25be14ea1116dc2bd2fec17e40a5e3"),
                maxMoney: long.MaxValue,
                coinbaseMaturity: 10,
                premineHeight: 2,
                premineReward: Money.Coins(13736000000),
                proofOfWorkReward: Money.Coins(2),
                powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
                powAllowMinDifficultyBlocks: false,
                powNoRetargeting: false,
                powLimit: powLimit,
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: 125000,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(20)
                );

            this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (66) };
            this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (196) };
            this.Base58Prefixes[(int)Base58Type.SECRET_KEY]     = new byte[] { (66 + 128) };

            this.Checkpoints = new Dictionary <int, CheckpointInfo>
            {
                { 0, new CheckpointInfo(new uint256("0x00077765f625cc2cb6266544ff7d5a462f25be14ea1116dc2bd2fec17e40a5e3"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
                { 2, new CheckpointInfo(new uint256("0xcf917ba726c8d05496a6b144fc433dc06cc574f49ca429e250454a0bbaab926d"), new uint256("0x315e64b6097a15128b0379c501ef278ff4fa70b062b44ce69a95e604464c46f8")) }, // Premine
                { 50, new CheckpointInfo(new uint256("0x464ae37e22cc44d0c8a86478ff95f98a6e1c44ceb3e175181e1a382270d1780c"), new uint256("0x6b5e010988dc9716e010e3ec21f7f60a4850726d5bbc7c212fab4e7b9b3566d7")) },
            };

            this.DNSSeeds = new List <DNSSeedData>
            {
                new DNSSeedData("city-chain.org", "testseed.city-chain.org"),
                new DNSSeedData("city-coin.org", "testseed.city-coin.org"),
                new DNSSeedData("citychain.foundation", "testseed.citychain.foundation")
            };

            this.SeedNodes = new List <NetworkAddress>
            {
                new NetworkAddress(IPAddress.Parse("40.115.2.6"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("13.66.158.6"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("52.175.194.227"), this.DefaultPort)
            };

            Assert(this.Consensus.HashGenesisBlock == uint256.Parse("0x00077765f625cc2cb6266544ff7d5a462f25be14ea1116dc2bd2fec17e40a5e3"));
            Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("0x034aaae9ca8e297078a2fed80cdaaf72ffad8aa1b1988c7b6edd8f01d69312ca"));
        }
Esempio n. 6
0
        public CityMain()
        {
            this.Name        = "CityMain";
            this.NetworkType = NetworkType.Mainnet;
            this.Magic       = 0x43545901; // .CTY
            this.DefaultMaxOutboundConnections = 16;
            this.DefaultMaxInboundConnections  = 109;
            this.DefaultPort           = 4333;
            this.DefaultRPCPort        = 4334;
            this.DefaultAPIPort        = 4335;
            this.DefaultSignalRPort    = 4336;
            this.MaxTipAge             = 2 * 60 * 60;
            this.MinTxFee              = 10000;
            this.FallbackFee           = 10000;
            this.MinRelayTxFee         = 10000;
            this.RootFolderName        = CityRootFolderName;
            this.DefaultConfigFilename = CityDefaultConfigFilename;
            this.MaxTimeOffsetSeconds  = 25 * 60;
            this.CoinTicker            = "CITY";
            this.DefaultBanTimeSeconds = 16000; // 500 (MaxReorg) * 64 (TargetSpacing) / 2 = 4 hours, 26 minutes and 40 seconds

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            this.GenesisTime    = 1538481600; // 10/02/2018 @ 12:00pm (UTC)
            this.GenesisNonce   = 1626464;
            this.GenesisBits    = 0x1E0FFFFF;
            this.GenesisVersion = 1;
            this.GenesisReward  = Money.Zero;

            // 2018-07-27: "Bitcoin’s roots are in anarcho-capitalism, a movement that aspires to reproduce the mechanisms of the free market without the need for banks or state bodies to enforce rules."
            // https://www.newscientist.com/article/mg23831841-200-how-to-think-about-the-blockchain/
            string pszTimestamp = "July 27, 2018, New Scientiest, Bitcoin’s roots are in anarcho-capitalism";

            Block genesisBlock = CreateCityGenesisBlock(pszTimestamp, consensusFactory, this.GenesisTime, this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward);

            this.Genesis = genesisBlock;

            var bip9Deployments = new CityBIP9Deployments()
            {
                [CityBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters("ColdStaking", 2, new DateTime(2018, 12, 1, 0, 0, 0, DateTimeKind.Utc), new DateTime(2019, 12, 1, 0, 0, 0, DateTimeKind.Utc), BIP9DeploymentsParameters.DefaultMainnetThreshold),
                [CityBIP9Deployments.CSV]         = new BIP9DeploymentsParameters("CSV", 0, new DateTime(2021, 5, 18, 0, 0, 0, DateTimeKind.Utc), new DateTime(2021, 8, 1, 0, 0, 0, DateTimeKind.Utc), BIP9DeploymentsParameters.DefaultTestnetThreshold),
                [CityBIP9Deployments.Segwit]      = new BIP9DeploymentsParameters("Segwit", 1, new DateTime(2021, 5, 18, 0, 0, 0, DateTimeKind.Utc), new DateTime(2021, 8, 1, 0, 0, 0, DateTimeKind.Utc), BIP9DeploymentsParameters.DefaultTestnetThreshold),
            };

            var consensusOptions = new CityPosConsensusOptions(
                maxBlockBaseSize: 1_000_000,
                maxStandardVersion: 2,
                maxStandardTxWeight: 100_000,
                maxBlockSigopsCost: 20_000,
                maxStandardTxSigopsCost: 20_000 / 5
                );

            this.Consensus = new Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: 1926,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 210000,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            },
                bip9Deployments: bip9Deployments,
                bip34Hash: new uint256("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"),
                // ruleChangeActivationThreshold: 1916, // 95% of 2016
                minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: new uint256("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"),
                maxMoney: long.MaxValue,
                coinbaseMaturity: 50,
                premineHeight: 2,
                premineReward: Money.Coins(13736000000),
                proofOfWorkReward: Money.Coins(2),                          // Produced up until last POW block.
                powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
                powAllowMinDifficultyBlocks: false,
                posNoRetargeting: false,
                powNoRetargeting: false,
                powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: 2500,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(20)
                );

            this.Base58Prefixes = new byte[12][];
            this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS]             = new byte[] { (28) };  // P2PKH: C, list: https://en.bitcoin.it/wiki/List_of_address_prefixes
            this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS]             = new byte[] { (88) };  // P2SH: c
            this.Base58Prefixes[(int)Base58Type.SECRET_KEY]                 = new byte[] { (237) }; // WIF: c (compressed, 8 uncompressed), initial character for compressed private key in WIF format.
            this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] { 0x01, 0x42 };
            this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC]    = new byte[] { 0x01, 0x43 };
            this.Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY]             = new byte[] { (0x04), (0x88), (0xB2), (0x1E) };
            this.Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY]             = new byte[] { (0x04), (0x88), (0xAD), (0xE4) };
            this.Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE]            = new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 };
            this.Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE]          = new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A };
            this.Base58Prefixes[(int)Base58Type.STEALTH_ADDRESS]            = new byte[] { 0x2a };
            this.Base58Prefixes[(int)Base58Type.ASSET_ID]        = new byte[] { 23 };
            this.Base58Prefixes[(int)Base58Type.COLORED_ADDRESS] = new byte[] { 0x13 };

            this.Checkpoints = new Dictionary <int, CheckpointInfo>
            {
                { 0, new CheckpointInfo(new uint256("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
                { 2, new CheckpointInfo(new uint256("0x072227af2fda8ef6a5f7a19ec3a1c6de54ddc537dd407da938766ed460e77982"), new uint256("0xe93eb6c21c65024ca06ac2f89481bdc832cab1607ed2adfeafb6c679b6a4a1f6")) },
                { 50, new CheckpointInfo(new uint256("0xce58ab37dd5965c3474c5917fcbb59aa342c6754a452e5faf87050bb6015d511"), new uint256("0xb877b17b3d7324ac1a3615a6c245c702282e5be74fd50cf25bb02bc5f2ea7944")) },
                { 100, new CheckpointInfo(new uint256("0x5edbf09aadfbdb0d74d428b002fcda197debb775955a161f2890ed844a5159da"), new uint256("0x354210eecb7ed3f8df3d384b8d615f789fdffdf3f3d4945c23e5966827010b73")) },
                { 200, new CheckpointInfo(new uint256("0x180745aeb0754cde04dac52dbb056dac5b1c665de86ee23806c1c7675dac3ac9"), new uint256("0x7f5dfec171542e5d2b56e874eb4f1e26c949e8a33a64e3fe0b06f1b5783fbd54")) },
                { 1000, new CheckpointInfo(new uint256("0xc848602fe0f33511766b66c6d5a28e11cd54e7c61d69c0898f868f46b5c9d6f7"), new uint256("0x13fad5f4e1dc5120f88e48e3f8d08bbc57b78fa960df8b600819c631f1038327")) },
                { 2000, new CheckpointInfo(new uint256("0xe73ec56e8c4159594bea6e8d73f1a5e0c980246861064451e2f0d2f609ed7d0b"), new uint256("0x569ab17ece910f954d26f3ab8a83ec5ae8952957b3f1c1868fb7b04abd52dd19")) },
                { 10000, new CheckpointInfo(new uint256("0x5fba1895ca1134f3c6fefdd45996039d45aab0177a10e86cac4990226f62ad95"), new uint256("0x47c6db50a945d8d4b17676e65a74ccd64e3b73f696082c3cdb7a9c0b9658e9cb")) },
                { 20000, new CheckpointInfo(new uint256("0xa0f81a7734e621ae2e2cecea7a3b851dee3b5a85ba4732e0867cbf5c496f04ed"), new uint256("0xf044e402b75b4314231e1498fefc8b11da8cc9cb7797e2e59b2acdbcea1b02b3")) },
                { 40000, new CheckpointInfo(new uint256("0xd3fc0976cb034b1e3eccdd6c4ebb76c0933ea37c47d43831371880346b9200b8"), new uint256("0x03a09ede5eadd8dbbc36806ef530c21c5548a7a823cf173c97439576dcb4d26d")) },
                { 100000, new CheckpointInfo(new uint256("0x05ca140afb76f1f1f3ac7f2c85751d90ce85a9c415628e4508c02983682647d9"), new uint256("0xc38b427f8aeab86baaa784e5e0b34ea471d35ebcb43a7651eb2eddbec7f0e73b")) },
                { 150000, new CheckpointInfo(new uint256("0x0be1d4fce6a93989025d405292d12aca12c7417494e50c2c633ad2f7bb7cbb53"), new uint256("0xcaafe0d5594c6b12bd0b819ccc22dba5ae7dcea32721cd97df369dbe868e13e9")) },
                { 300000, new CheckpointInfo(new uint256("0x8e6f02341f5db1af8e8bec7fb4471d789c180b627d853b764bbf9f360140f3dd"), new uint256("0x287f59ae242630024100c633ac452daa46c679c51be09c9f1432edd8de235bba")) },
                { 400000, new CheckpointInfo(new uint256("0x6a3503d4e1c2d3353abc5eff5f9fade16a8c88f7424877178605f52e3809114f"), new uint256("0x8c9fb0439c272bd71390fe95a3991b84c450be17ecc10dffa4b9de189798af17")) },
                { 470000, new CheckpointInfo(new uint256("0xe3bcd65fe121a112019b4bb8cd077536ee195d84e66f3bf1b7d00a0cdfda331d"), new uint256("0xeee34e8c50a761ecf2c73636842c9da4b5c5a6473890608c30f1702ef225f346")) },
                { 595000, new CheckpointInfo(new uint256("0x689594927784e5e47b761f85c0906c29579ceb5c8edf922d113b4cdf9ac2a304"), new uint256("0xccd513fd35197b34d63741bb95923621856766ad0161b86e25493c28e21572a5")) },
                { 800000, new CheckpointInfo(new uint256("0xaf94ebd59507829e82d2e98e75f8777224bf54e2f4ad76ff7bdc2ebebc634cb9"), new uint256("0xbe19a177b90653ee3a654e7fd307e93410db3478dbc28225e24aea9d2087d04b")) },
                { 1125570, new CheckpointInfo(new uint256("0x1295cd37612f19ad8847531f84489f25fa1612a0cb91e95bff44b566a0de2cfa"), new uint256("0xa62070bd16f609f33b724e2de7bd555fcef28161a6146e6270dfcaf784b21d61")) },
                { 1196280, new CheckpointInfo(new uint256("0xa42ba7735f2bf202f218d932008c039f4f97f90710c0a77c27c15b66c1ed48cd"), new uint256("0x3a7ccae05cc65f9b3e325a606ef1fe690820e2fbe0b1bbdadb2a57be97c8cf18")) },
                { 1250000, new CheckpointInfo(new uint256("0xfcbfa827fce703d50f72b5b6f0ee1e5a5d46c7a469bc972c4d4839137998e5a5"), new uint256("0xaa163ed85712405b4623683259c947fa4fc2fe56eb9ee3c7eded2b5492b58dd1")) },
            };

            this.Bech32Encoders = new Bech32Encoder[2];
            // Bech32 is currently unsupported - once supported uncomment lines below
            //var encoder = new Bech32Encoder("bc");
            //this.Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
            //this.Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;
            this.Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = null;
            this.Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = null;

            this.DNSSeeds = new List <DNSSeedData>
            {
                new DNSSeedData("city-chain.org", "seed.city-chain.org"),
                new DNSSeedData("city-coin.org", "seed.city-coin.org"),
                //new DNSSeedData("citychain.foundation", "seed.citychain.foundation"),
                //new DNSSeedData("liberstad.com", "seed.liberstad.com")
            };

            this.SeedNodes = new List <NetworkAddress>
            {
                new NetworkAddress(IPAddress.Parse("23.97.234.230"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("13.73.143.193"), this.DefaultPort),
                // new NetworkAddress(IPAddress.Parse("94.177.215.201"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("89.36.213.152"), this.DefaultPort),
                new NetworkAddress(IPAddress.Parse("89.10.229.203"), this.DefaultPort),
                // new NetworkAddress(IPAddress.Parse("96.126.122.213"), this.DefaultPort),
            };

            this.StandardScriptsRegistry = new CityStandardScriptsRegistry();

            // 64 below should be changed to TargetSpacingSeconds when we move that field.
            Assert(this.DefaultBanTimeSeconds <= this.Consensus.MaxReorgLength * 64 / 2);
            Assert(this.Consensus.HashGenesisBlock == uint256.Parse("0x00000b0517068e602ed5279c20168cfa1e69884ee4e784909652da34c361bff2"));
            Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("0xb3425d46594a954b141898c7eebe369c6e6a35d2dab393c1f495504d2147883b"));

            this.RegisterRules(this.Consensus);
            this.RegisterMempoolRules(this.Consensus);
        }