/// <summary>
        /// Creates a new instance of generation transaction.
        /// </summary>
        /// <param name="extraNonce">The extra nonce.</param>
        /// <param name="daemonClient">The daemon client.</param>
        /// <param name="blockTemplate">The block template.</param>
        /// <param name="poolConfig">The associated pool's configuration</param>
        /// <remarks>
        /// Reference implementations:
        /// https://github.com/zone117x/node-stratum-pool/blob/b24151729d77e0439e092fe3a1cdbba71ca5d12e/lib/transactions.js
        /// https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/coinbasetx.py
        /// </remarks>
        public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient,
                                     IBlockTemplate blockTemplate, IPoolConfig poolConfig)
        {
            // TODO: we need a whole refactoring here.
            // we should use DI and it shouldn't really require daemonClient connection to function.

            BlockTemplate = blockTemplate;
            ExtraNonce    = extraNonce;
            PoolConfig    = poolConfig;

            Version   = blockTemplate.Version;
            TxMessage = Serializers.SerializeString(poolConfig.Meta.TxMessage);
            LockTime  = 0;

            // transaction inputs
            Inputs = new List <TxIn>
            {
                new TxIn
                {
                    PreviousOutput = new OutPoint
                    {
                        Hash  = Hash.ZeroHash,
                        Index = (UInt32)Math.Pow(2, 32) - 1
                    },
                    Sequence        = 0x0,
                    SignatureScript =
                        new SignatureScript(
                            blockTemplate.Height,
                            blockTemplate.CoinBaseAux.Flags,
                            TimeHelpers.NowInUnixTimestamp(),
                            (byte)extraNonce.ExtraNoncePlaceholder.Length,
                            "/CoiniumServ/")
                }
            };

            // transaction outputs
            Outputs = new Outputs(daemonClient, poolConfig.Coin);
            double blockReward = BlockTemplate.Coinbasevalue; // the amount rewarded by the block.

            // generate output transactions for recipients (set in config).
            foreach (var pair in poolConfig.Rewards)
            {
                var amount = blockReward * pair.Value / 100; // calculate the amount the recieves based on the percent of his shares.
                blockReward -= amount;
                Outputs.AddRecipient(pair.Key, amount);
            }

            // send the remaining coins to pool's central wallet.
            Outputs.AddPoolWallet(poolConfig.Wallet.Adress, blockReward);

            // Final output is witness
            //https://github.com/slush0/stratum-mining/pull/16/files?diff=unified
            if (!string.IsNullOrEmpty(BlockTemplate.Default_witness_commitment))
            {
                Outputs.AddWitnessOutput(BlockTemplate.Default_witness_commitment.HexToByteArray());
            }
        }
        /// <summary>
        /// Creates a new instance of generation transaction.
        /// </summary>
        /// <param name="extraNonce">The extra nonce.</param>
        /// <param name="daemonClient">The daemon client.</param>
        /// <param name="blockTemplate">The block template.</param>
        /// <param name="poolConfig">The associated pool's configuration</param>
        /// <remarks>
        /// Reference implementations:
        /// https://github.com/zone117x/node-stratum-pool/blob/b24151729d77e0439e092fe3a1cdbba71ca5d12e/lib/transactions.js
        /// https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/coinbasetx.py
        /// </remarks>
        public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, IBlockTemplate blockTemplate, IPoolConfig poolConfig)
        {
            // TODO: we need a whole refactoring here.
            // we should use DI and it shouldn't really require daemonClient connection to function.

            BlockTemplate = blockTemplate;
            ExtraNonce    = extraNonce;
            PoolConfig    = poolConfig;

            Version   = blockTemplate.Version;
            TxMessage = Serializers.SerializeString(poolConfig.Meta.TxMessage);
            LockTime  = 0;

            // transaction signature
            var signature = "/Kosmonavt Stratum/";

            // transaction inputs
            Inputs = new List <TxIn>
            {
                new TxIn
                {
                    PreviousOutput = new OutPoint
                    {
                        Hash  = Hash.ZeroHash,
                        Index = (UInt32)Math.Pow(2, 32) - 1
                    },
                    Sequence        = 0x0,
                    SignatureScript =
                        new SignatureScript(
                            blockTemplate.Height,
                            blockTemplate.CoinBaseAux.Flags,
                            TimeHelpers.NowInUnixTimestamp(),
                            (byte)extraNonce.ExtraNoncePlaceholder.Length,
                            signature)
                }
            };

            // transaction outputs
            Outputs = new Outputs(daemonClient, poolConfig.Coin);

            double blockReward = BlockTemplate.Coinbasevalue; // the amount rewarded by the block.

            // generate output transactions for recipients (set in config).
            foreach (var pair in poolConfig.Rewards)
            {
                var amount = blockReward * pair.Value / 100; // calculate the amount he recieves based on the percent of his shares.
                blockReward -= amount;

                Outputs.AddRecipient(pair.Key, amount);
            }

            // send the remaining coins to pool's central wallet.
            Outputs.AddPoolWallet(poolConfig.Wallet.Adress, blockReward);
        }
        /// <summary>
        /// Creates a new instance of generation transaction.
        /// </summary>
        /// <param name="extraNonce">The extra nonce.</param>
        /// <param name="daemonClient">The daemon client.</param>
        /// <param name="blockTemplate">The block template.</param>
        /// <param name="rewardsConfig"></param>
        /// <param name="supportTxMessages">if set to <c>true</c> [support tx messages].</param>
        /// <remarks>
        /// Reference implementations:
        /// https://github.com/zone117x/node-stratum-pool/blob/b24151729d77e0439e092fe3a1cdbba71ca5d12e/lib/transactions.js
        /// https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/coinbasetx.py
        /// </remarks>
        public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, IBlockTemplate blockTemplate, IWalletConfig walletConfig, IRewardsConfig rewardsConfig, bool supportTxMessages = false)
        {
            DaemonClient = daemonClient;
            BlockTemplate = blockTemplate;
            ExtraNonce = extraNonce;
            SupportTxMessages = supportTxMessages;

            Version = (UInt32)(supportTxMessages ? 2 : 1);
            Message = Serializers.SerializeString("https://github.com/CoiniumServ/CoiniumServ");
            LockTime = 0;

            // transaction inputs
            Inputs = new List<TxIn>
            {
                new TxIn
                {
                    PreviousOutput = new OutPoint
                    {
                        Hash = Hash.ZeroHash,
                        Index = (UInt32) Math.Pow(2, 32) - 1
                    },
                    Sequence = 0x0,
                    SignatureScript =
                        new SignatureScript(
                            blockTemplate.Height,
                            blockTemplate.CoinBaseAux.Flags,
                            TimeHelpers.NowInUnixTime(),
                            (byte) extraNonce.ExtraNoncePlaceholder.Length,
                            "/CoiniumServ/")
                }
            };

            // transaction outputs
            Outputs = new Outputs(daemonClient);

            double blockReward = BlockTemplate.Coinbasevalue; // the amount rewarded by the block.

            // generate output transactions for recipients (set in config).
            foreach (var pair in rewardsConfig)
            {
                var amount = blockReward * pair.Value / 100; // calculate the amount he recieves based on the percent of his shares.
                blockReward -= amount;

                Outputs.AddRecipient(pair.Key, amount);
            }

            // send the remaining coins to pool's central wallet.
            Outputs.AddPoolWallet(walletConfig.Adress, blockReward);
        }
Exemplo n.º 4
0
        public void TestOutputs()
        {
            var outputs = new Outputs(_daemonClient);

            // setup the outputs based on the sample.
            double blockReward = 5000000000; // the amount rewarded by the block.

            // sample recipient
            const string recipient = "mrwhWEDnU6dUtHZJ2oBswTpEdbBHgYiMji";
            var amount = blockReward * 0.01;
            blockReward -= amount;
            outputs.AddRecipient(recipient, amount);

            // sample pool wallet
            const string poolWallet = "mk8JqN1kNWju8o3DXEijiJyn7iqkwktAWq";
            outputs.AddPoolWallet(poolWallet, blockReward);

            // test the recipient rewards
            outputs.List.Last().Value.Should().Equal((UInt64)0x0000000002faf080); // packInt64LE: 80f0fa0200000000
            outputs.List.Last().PublicKeyScriptLenght.Should().Equal(new byte[] { 0x19 });
            outputs.List.Last().PublicKeyScript.ToHexString().Should().Equal("76a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac");

            // test the pool wallet
            outputs.List.First().Value.Should().Equal((UInt64)0x00000001270b0180); // packInt64LE: 80010b2701000000
            outputs.List.First().PublicKeyScriptLenght.Should().Equal(new byte[] { 0x19 });
            outputs.List.First().PublicKeyScript.ToHexString().Should().Equal("76a914329035234168b8da5af106ceb20560401236849888ac");

            // test the outputs buffer.
            outputs.GetBuffer().ToHexString().Should().Equal("0280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac");
        }
        /// <summary>
        /// Creates a new instance of generation transaction.
        /// </summary>
        /// <param name="extraNonce">The extra nonce.</param>
        /// <param name="daemonClient">The daemon client.</param>
        /// <param name="blockTemplate">The block template.</param>
        /// <param name="poolConfig">The associated pool's configuration</param>
        /// <remarks>
        /// Reference implementations:
        /// https://github.com/zone117x/node-stratum-pool/blob/b24151729d77e0439e092fe3a1cdbba71ca5d12e/lib/transactions.js
        /// https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/coinbasetx.py
        /// </remarks>
        public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, IBlockTemplate blockTemplate, IPoolConfig poolConfig)
        {
            // TODO: we need a whole refactoring here.
            // we should use DI and it shouldn't really require daemonClient connection to function.

            BlockTemplate = blockTemplate;
            ExtraNonce = extraNonce;
            PoolConfig = poolConfig;

            Version = blockTemplate.Version;
            TxMessage = Serializers.SerializeString(poolConfig.Meta.TxMessage);
            LockTime = 0;

            // transaction inputs
            Inputs = new List<TxIn>
            {
                new TxIn
                {
                    PreviousOutput = new OutPoint
                    {
                        Hash = Hash.ZeroHash,
                        Index = (UInt32) Math.Pow(2, 32) - 1
                    },
                    Sequence = 0x0,
                    SignatureScript =
                        new SignatureScript(
                            blockTemplate.Height,
                            blockTemplate.CoinBaseAux.Flags,
                            TimeHelpers.NowInUnixTimestamp(),
                            (byte) extraNonce.ExtraNoncePlaceholder.Length,
                            "/CoiniumServ/")
                }
            };

            // transaction outputs
            Outputs = new Outputs(daemonClient, poolConfig.Coin);

            double blockReward = BlockTemplate.Coinbasevalue; // the amount rewarded by the block.

            // generate output transactions for recipients (set in config).
            foreach (var pair in poolConfig.Rewards)
            {
                var amount = blockReward * pair.Value / 100; // calculate the amount he recieves based on the percent of his shares.
                blockReward -= amount;

                Outputs.AddRecipient(pair.Key, amount);
            }

            // send the remaining coins to pool's central wallet.
            Outputs.AddPoolWallet(poolConfig.Wallet.Adress, blockReward);
        }