public static NBitcoin.Block CreateGenesis(ConsensusFactory consensusFactory, uint genesisTime, uint nonce, uint bits, int version, Money reward)
        {
            string timeStamp           = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
            var    genesisOutputScript = new Script(Op.GetPushOp(Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")), OpcodeType.OP_CHECKSIG);

            NBitcoin.Transaction genesisTransaction = consensusFactory.CreateTransaction();
            genesisTransaction.Version = 1;
            genesisTransaction.AddInput(new TxIn()
            {
                ScriptSig = new Script(Op.GetPushOp(486604799), new Op()
                {
                    Code     = (OpcodeType)0x1,
                    PushData = new[] { (byte)4 }
                }, Op.GetPushOp(Encoders.ASCII.DecodeData(timeStamp)))
            });

            genesisTransaction.AddOutput(new TxOut()
            {
                Value        = reward,
                ScriptPubKey = genesisOutputScript
            });

            NBitcoin.Block genesis = consensusFactory.CreateBlock();
            genesis.Header.BlockTime = Utils.UnixTimeToDateTime(genesisTime);
            genesis.Header.Bits      = bits;
            genesis.Header.Nonce     = nonce;
            genesis.Header.Version   = version;
            genesis.Transactions.Add(genesisTransaction);
            genesis.Header.HashPrevBlock = uint256.Zero;
            genesis.UpdateMerkleRoot();

            ((ISmartContractBlockHeader)genesis.Header).HashStateRoot = SmartContractBlockDefinition.StateRootEmptyTrie;

            return(genesis);
        }
        protected virtual Transaction CreateOutputTransaction()
        {
            var blockReward = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = new Transaction();

            // Distribute funds to configured reward recipients
            var rewardRecipients = new List <RewardRecipient>(poolConfig.RewardRecipients);

            foreach (var recipient in rewardRecipients.Where(x => x.Type != RewardRecipientType.Dev && x.Percentage > 0))
            {
                var recipientAddress = BitcoinUtils.AddressToScript(recipient.Address);
                var recipientReward  = new Money((long)Math.Floor(recipient.Percentage / 100.0m * blockReward.Satoshi));

                rewardToPool -= recipientReward;

                tx.AddOutput(recipientReward, recipientAddress);
            }

            // Finally distribute remaining funds to pool
            tx.Outputs.Insert(0, new TxOut(rewardToPool, poolAddressDestination)
            {
                Value = rewardToPool
            });

            // validate it
            //var checkResult = tx.Check();
            //Debug.Assert(checkResult == TransactionCheckResult.Success);

            return(tx);
        }
Beispiel #3
0
        protected virtual Money CreateMasternodeOutputs(Transaction tx, Money reward)
        {
            if (masterNodeParameters.Masternode != null && masterNodeParameters.SuperBlocks != null)
            {
                if (!string.IsNullOrEmpty(masterNodeParameters.Masternode.Payee))
                {
                    var payeeAddress = BitcoinUtils.AddressToDestination(masterNodeParameters.Masternode.Payee);
                    var payeeReward  = masterNodeParameters.Masternode.Amount;

                    reward       -= payeeReward;
                    rewardToPool -= payeeReward;

                    tx.AddOutput(payeeReward, payeeAddress);
                }

                else if (masterNodeParameters.SuperBlocks.Length > 0)
                {
                    foreach (var superBlock in masterNodeParameters.SuperBlocks)
                    {
                        var payeeAddress = BitcoinUtils.AddressToDestination(superBlock.Payee);
                        var payeeReward  = superBlock.Amount;

                        reward       -= payeeReward;
                        rewardToPool -= payeeReward;

                        tx.AddOutput(payeeReward, payeeAddress);
                    }
                }
            }

            if (!string.IsNullOrEmpty(masterNodeParameters.Payee))
            {
                var payeeAddress = BitcoinUtils.AddressToDestination(masterNodeParameters.Payee);
                var payeeReward  = masterNodeParameters.PayeeAmount ?? (reward / 5);

                reward       -= payeeReward;
                rewardToPool -= payeeReward;

                tx.AddOutput(payeeReward, payeeAddress);
            }

            return(reward);
        }
Beispiel #4
0
        protected override Transaction CreateOutputTransaction()
        {
            rewardToPool = new Money(BlockTemplate.CoinbaseValue * blockRewardMultiplier, MoneyUnit.Satoshi);

            var tx = new Transaction();

            // pool reward (t-addr)
            tx.AddOutput(rewardToPool, poolAddressDestination);

            return(tx);
        }
Beispiel #5
0
        protected override Transaction CreateOutputTransaction()
        {
            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = new Transaction();

            // pool reward (t-addr)
            var amount = new Money(blockReward + rewardFees, MoneyUnit.Satoshi);

            tx.AddOutput(amount, poolAddressDestination);

            return(tx);
        }
Beispiel #6
0
        protected virtual Transaction CreateOutputTransaction()
        {
            var blockReward = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = new Transaction();

            // Distribute funds to configured reward recipients
            var rewardRecipients = new List <RewardRecipient>(poolConfig.RewardRecipients);

            // Tiny donation to MiningCore developer(s)
            if (!clusterConfig.DisableDevDonation &&
                networkType == BitcoinNetworkType.Main &&
                KnownAddresses.DevFeeAddresses.ContainsKey(poolConfig.Coin.Type))
            {
                rewardRecipients.Add(new RewardRecipient
                {
                    Address    = KnownAddresses.DevFeeAddresses[poolConfig.Coin.Type],
                    Percentage = 0.2m
                });
            }

            foreach (var recipient in rewardRecipients.Where(x => x.Percentage > 0))
            {
                var recipientAddress = BitcoinUtils.AddressToScript(recipient.Address);
                var recipientReward  = new Money((long)Math.Floor(recipient.Percentage / 100.0m * blockReward.Satoshi));

                rewardToPool -= recipientReward;

                tx.AddOutput(recipientReward, recipientAddress);
            }

            // Finally distribute remaining funds to pool
            tx.Outputs.Insert(0, new TxOut(rewardToPool, poolAddressDestination)
            {
                Value = rewardToPool
            });

            // validate it
            //var checkResult = tx.Check();
            //Debug.Assert(checkResult == TransactionCheckResult.Success);

            return(tx);
        }
Beispiel #7
0
        public static NBitcoin.Block CreateGenesis(ConsensusFactory consensusFactory, uint genesisTime, uint nonce, uint bits, int version, Money reward)
        {
            string timeStamp           = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
            var    genesisOutputScript = new Script(Op.GetPushOp(Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")), OpcodeType.OP_CHECKSIG);

            NBitcoin.Transaction genesisTransaction = consensusFactory.CreateTransaction();

            // TODO: Similar potential problem to Cirrus genesis definition
            if (genesisTransaction is IPosTransactionWithTime posTx)
            {
                posTx.Time = genesisTime;
            }

            genesisTransaction.Version = 1;
            genesisTransaction.AddInput(new TxIn()
            {
                ScriptSig = new Script(Op.GetPushOp(486604799), new Op()
                {
                    Code     = (OpcodeType)0x1,
                    PushData = new[] { (byte)4 }
                }, Op.GetPushOp(Encoders.ASCII.DecodeData(timeStamp)))
            });

            genesisTransaction.AddOutput(new TxOut()
            {
                Value        = reward,
                ScriptPubKey = genesisOutputScript
            });

            NBitcoin.Block genesis = consensusFactory.CreateBlock();
            genesis.Header.BlockTime = Utils.UnixTimeToDateTime(genesisTime);
            genesis.Header.Bits      = bits;
            genesis.Header.Nonce     = nonce;
            genesis.Header.Version   = version;
            genesis.Transactions.Add(genesisTransaction);
            genesis.Header.HashPrevBlock = uint256.Zero;
            genesis.UpdateMerkleRoot();

            ((SmartContractBlockHeader)genesis.Header).HashStateRoot = new uint256("21B463E3B52F6201C0AD6C991BE0485B6EF8C092E64583FFA655CC1B171FE856");

            return(genesis);
        }
        /// <summary>
        /// Mines a new genesis block, to use with a new network.
        /// Typically, 3 such genesis blocks need to be created when bootstrapping a new coin: for Main, Test and Reg networks.
        /// </summary>
        /// <param name="consensusFactory">
        /// The consensus factory used to create transactions and blocks.
        /// Use <see cref="PosConsensusFactory"/> for proof-of-stake based networks.
        /// </param>
        /// <param name="coinbaseText">
        /// Traditionally a news headline from the day of the launch, but could be any string or link.
        /// This will be inserted in the input coinbase transaction script.
        /// It should be shorter than 92 characters.
        /// </param>
        /// <param name="target">
        /// The difficulty target under which the hash of the block need to be.
        /// Some more details: As an example, the target for the Stratis Main network is 00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
        /// To make it harder to mine the genesis block, have more zeros at the beginning (keeping the length the same). This will make the target smaller, so finding a number under it will be more difficult.
        /// To make it easier to mine the genesis block ,do the opposite. Example of an easy one: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
        /// Make the Test and Reg targets ones easier to find than the Main one so that you don't wait too long to mine the genesis block.
        /// </param>
        /// <param name="genesisReward">
        /// Specify how many coins to put in the genesis transaction's output. These coins are unspendable.
        /// </param>
        /// <param name="version">
        /// The version of the transaction and the block header set in the genesis block.
        /// </param>
        /// <example>
        /// The following example shows the creation of a genesis block.
        /// <code>
        /// Block genesis = MineGenesisBlock(new PosConsensusFactory(), "Some topical headline.", new Target(new uint256("000fffff00000000000000000000000000000000000000000000000000000000")), Money.Coins(50m));
        /// BlockHeader header = genesis.Header;
        /// Console.WriteLine("Make a note of the following values:");
        /// Console.WriteLine("bits: " + header.Bits);
        /// Console.WriteLine("nonce: " + header.Nonce);
        /// Console.WriteLine("time: " + header.Time);
        /// Console.WriteLine("version: " + header.Version);
        /// Console.WriteLine("hash: " + header.GetHash());
        /// Console.WriteLine("merkleroot: " + header.HashMerkleRoot);
        /// </code>
        /// </example>
        /// <returns>A genesis block.</returns>
        public static Block MineGenesisBlock(ConsensusFactory consensusFactory, string coinbaseText, Target target, Money genesisReward, int version = 1)
        {
            if (target == null)
            {
                throw new ArgumentException($"Parameter '{nameof(target)}' cannot be null. Example use: new Target(new uint256(\"0000ffff00000000000000000000000000000000000000000000000000000000\"))");
            }

            if (consensusFactory == null)
            {
                throw new ArgumentException($"Parameter '{nameof(consensusFactory)}' cannot be null. Use 'new ConsensusFactory()' for Bitcoin-like proof-of-work blockchains" +
                                            "and 'new PosConsensusFactory()' for Stratis-like proof-of-stake blockchains.");
            }

            if (string.IsNullOrEmpty(coinbaseText))
            {
                throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' cannot be null. Use a news headline or any other appropriate string.");
            }

            if (coinbaseText.Length >= 92)
            {
                throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' should be shorter than 92 characters.");
            }

            if (genesisReward == null)
            {
                throw new ArgumentException($"Parameter '{nameof(genesisReward)}' cannot be null. Example use: 'Money.Coins(50m)'.");
            }

            DateTimeOffset time     = DateTimeOffset.Now;
            uint           unixTime = Utils.DateTimeToUnixTime(time);

            Transaction txNew = consensusFactory.CreateTransaction();

            txNew.Version = (uint)version;
            txNew.Time    = unixTime;
            txNew.AddInput(new TxIn()
            {
                ScriptSig = new Script(
                    Op.GetPushOp(0),
                    new Op()
                {
                    Code     = (OpcodeType)0x1,
                    PushData = new[] { (byte)42 }
                },
                    Op.GetPushOp(Encoders.ASCII.DecodeData(coinbaseText)))
            });

            txNew.AddOutput(new TxOut()
            {
                Value = genesisReward,
            });

            Block genesis = consensusFactory.CreateBlock();

            genesis.Header.BlockTime = time;
            genesis.Header.Bits      = target;
            genesis.Header.Nonce     = 0;
            genesis.Header.Version   = version;
            genesis.Transactions.Add(txNew);
            genesis.Header.HashPrevBlock = uint256.Zero;
            genesis.UpdateMerkleRoot();

            // Iterate over the nonce until the proof-of-work is valid.
            // This will mean the block header hash is under the target.
            while (!genesis.CheckProofOfWork())
            {
                genesis.Header.Nonce++;
                if (genesis.Header.Nonce == 0)
                {
                    genesis.Header.Time++;
                }
            }

            return(genesis);
        }
Beispiel #9
0
 public Transaction CreateSend(BitcoinAddress bitcoinAddress, Money value)
 {
     if(bitcoinAddress.Network != Network)
         throw new InvalidOperationException("This bitcoin address does not belong to the network");
     Transaction tx = new Transaction();
     tx.AddOutput(value, bitcoinAddress);
     this.CompleteTx(tx);
     return tx;
 }
Beispiel #10
0
        public bool CompleteTx(Transaction tx, Money fees, Account pool = null)
        {
            pool = pool ?? Accounts.Available;
            var entries = pool.GetEntriesToCover(tx.TotalOut + fees, false);
            if(entries == null)
                return false;

            foreach(var entry in entries)
            {
                tx.AddInput(new TxIn(entry.OutPoint));
            }
            var surplus = entries.Sum(i => i.TxOut.Value) - fees - tx.TotalOut;
            if(surplus != Money.Zero)
                tx.AddOutput(surplus, GetKey().PubKey.ID);

            for(int i = 0 ; i < entries.Length ; i++)
            {
                var entry = entries[i];
                var vin = tx.Inputs[i];
                var key = GetKey(entry.TxOut.ScriptPubKey.GetDestination());
                tx.Inputs[i].ScriptSig = new PayToPubkeyHashTemplate().GenerateScriptPubKey(key.PubKey);
                var hash = tx.Inputs[i].ScriptSig.SignatureHash(tx, i, SigHash.All);
                var sig = key.Sign(hash);
                tx.Inputs[i].ScriptSig = new PayToPubkeyHashTemplate().GenerateScriptSig(new TransactionSignature(sig, SigHash.All), key.PubKey);
            }
            return true;
        }