コード例 #1
0
        /// <inheritdoc />
        public void ProcessTransaction(Transaction transaction, int?blockHeight = null, Block block = null)
        {
            this.logger.LogDebug($"transaction received - hash: {transaction.GetHash()}, coin: {this.coinType}");

            // check the outputs
            foreach (var pubKey in this.keysLookup.Keys)
            {
                // check if the outputs contain one of our addresses
                var utxo = transaction.Outputs.SingleOrDefault(o => pubKey == o.ScriptPubKey);
                if (utxo != null)
                {
                    AddTransactionToWallet(transaction.GetHash(), transaction.Time, transaction.Outputs.IndexOf(utxo), utxo.Value, pubKey, blockHeight, block);
                }
            }

            // check the inputs - include those that have a reference to a transaction containing one of our scripts and the same index
            foreach (TxIn input in transaction.Inputs.Where(txIn => this.keysLookup.Values.SelectMany(v => v.Transactions).Any(trackedTx => trackedTx.Id == txIn.PrevOut.Hash && trackedTx.Index == txIn.PrevOut.N)))
            {
                TransactionData tTx = this.keysLookup.Values.SelectMany(v => v.Transactions).Single(trackedTx => trackedTx.Id == input.PrevOut.Hash && trackedTx.Index == input.PrevOut.N);

                // find the script this input references
                var keyToSpend = this.keysLookup.Single(v => v.Value.Transactions.Contains(tTx)).Key;

                // get the details of the outputs paid out.
                // We first include the keys we don't hold and then we include the keys we do hold but that are for receiving addresses (which would mean the user paid itself).
                IEnumerable <TxOut> paidoutto = transaction.Outputs.Where(o => !this.keysLookup.Keys.Contains(o.ScriptPubKey) || (this.keysLookup.ContainsKey(o.ScriptPubKey) && !this.keysLookup[o.ScriptPubKey].IsChangeAddress()));

                AddTransactionToWallet(transaction.GetHash(), transaction.Time, null, -tTx.Amount, keyToSpend, blockHeight, block, tTx.Id, tTx.Index, paidoutto);
            }
        }
コード例 #2
0
        protected virtual Transaction CreateOutputTransaction()
        {
            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = Transaction.Create(network);

            // Check if we need to pay founder fees
            if (coin.HasFounderFee)
            {
                rewardToPool = CreateFounderOutputs(tx, rewardToPool);
            }

            // Check if we need to pay treasury reward
            if (coin.HasTreasuryReward)
            {
                rewardToPool = CreateTreasuryOutputs(tx, rewardToPool);
            }

            tx.Outputs.Add(rewardToPool, poolAddressDestination);

            // CoinbaseDevReward check for Freecash
            if (coin.HasCoinbaseDevReward)
            {
                CreateCoinbaseDevRewardOutputs(tx);
            }

            return(tx);
        }
コード例 #3
0
 protected async Task <uint256> PublishTransactionAsync(NBitcoin.Transaction tx)
 {
     await using (var client = await this.Factory.CreateTransactionManagementClientAsync())
     {
         return(await client.PublishAsync(tx, true));
     }
 }
コード例 #4
0
        protected virtual Transaction CreateMasternodeOutputTransaction()
        {
            var blockReward = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);
            var tx = Transaction.Create(network);

            // outputs
            rewardToPool = CreateMasternodeOutputs(tx, blockReward);

            // Check if we need to pay founder fees
            if (coin.HasFounderFee)
            {
                rewardToPool = CreateFounderOutputs(tx, rewardToPool);
            }

            // Check if we need to pay treasury reward
            if (coin.HasTreasuryReward)
            {
                rewardToPool = CreateTreasuryOutputs(tx, rewardToPool);
            }

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

            return(tx);
        }
コード例 #5
0
        public string DepositBtc(string btcPubKey, string recipient, decimal amount)
        {
            var address = new BitcoinPubKeyAddress(btcPubKey, Network.TestNet);
            //var address = new BitcoinSecret(btcPubKey);
            var txOperations = QClient.GetBalance(dest: address, unspentOnly: true).Result.Operations;

            var coins = new List <Coin>();

            foreach (var op in txOperations)
            {
                op.ReceivedCoins.ForEach(c => coins.Add((Coin)c));
            }

            coins.Sort(delegate(Coin x, Coin y)
            {
                return(-x.Amount.CompareTo(y.Amount));
            });

            var coinSum = 0m;

            for (int i = 0; coinSum < amount; i++)
            {
                coinSum += coins[i].Amount.ToDecimal(MoneyUnit.BTC);
                if (coinSum >= amount)
                {
                    coins.RemoveRange(i + 1, coins.Count - (i + 1));
                }
            }

            var builder     = new TransactionBuilder();
            var destination = new BitcoinPubKeyAddress(recipient, Network.TestNet);

            NBitcoin.Transaction tx = builder
                                      .AddCoins(coins)
                                      //.AddKeys(testAddress)
                                      .Send(destination, Money.Coins(amount))
                                      .SetChange(address)
                                      .SendFees(Money.Coins(0.0001m))
                                      .BuildTransaction(sign: false);

            tx.Outputs.Add(new TxOut
            {
                Value        = Money.Zero,
                ScriptPubKey = TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(recipient))
            });

            foreach (var input in tx.Inputs)
            {
                input.ScriptSig = address.ScriptPubKey;
            }

            var txhash = tx.ToHex();

            if (builder.Verify(tx))
            {
                var broadcastResult = QClient.Broadcast(tx).Result;
            }

            return(tx.ToHex());
        }
コード例 #6
0
        /// <inheritdoc />
        public void ProcessTransaction(CoinType coinType, Transaction transaction, int?blockHeight = null, uint?blockTime = null)
        {
            Console.WriteLine($"transaction notification: tx hash {transaction.GetHash()}, coin type: {coinType}");

            foreach (var pubKey in this.PubKeys)
            {
                // check if the outputs contain one of our addresses
                var utxo = transaction.Outputs.SingleOrDefault(o => pubKey == o.ScriptPubKey);
                if (utxo != null)
                {
                    AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, transaction.Outputs.IndexOf(utxo), utxo.Value, pubKey, blockHeight, blockTime);
                }

                // if the inputs have a reference to a transaction containing one of our scripts
                foreach (TxIn input in transaction.Inputs.Where(txIn => this.TrackedTransactions.Any(trackedTx => trackedTx.Hash == txIn.PrevOut.Hash)))
                {
                    TransactionDetails tTx = this.TrackedTransactions.Single(trackedTx => trackedTx.Hash == input.PrevOut.Hash);

                    // compare the index of the output in its original transaction and the index references in the input
                    if (input.PrevOut.N == tTx.Index)
                    {
                        AddTransactionToWallet(coinType, transaction.GetHash(), transaction.Time, null, -tTx.Amount, pubKey, blockHeight, blockTime, tTx.Hash, tTx.Index);
                    }
                }
            }
        }
コード例 #7
0
        public async Task <ByteString> IssueWithdrawal(IList <OutboundTransaction> transactions)
        {
            HttpClient          client   = new HttpClient();
            BitcoinAddress      address  = storageKey.ScriptPubKey.GetDestinationAddress(this.Network);
            HttpResponseMessage response = await client.GetAsync(new Uri(url, $"addresses/{address.ToString()}/unspents"));

            string body = await response.Content.ReadAsStringAsync();

            JArray outputs = JArray.Parse(body);

            TransactionBuilder builder = new TransactionBuilder();

            builder.AddKeys(storageKey.GetBitcoinSecret(Network));
            foreach (JObject output in outputs)
            {
                string transactionHash = (string)output["transaction_hash"];
                uint   outputIndex     = (uint)output["output_index"];
                long   amount          = (long)output["value"];

                builder.AddCoins(new Coin(uint256.Parse(transactionHash), outputIndex, new Money(amount), storageKey.ScriptPubKey));
            }

            foreach (OutboundTransaction outboundTransaction in transactions)
            {
                builder.Send(BitcoinAddress.Create(outboundTransaction.Target, Network).ScriptPubKey, new Money(outboundTransaction.Amount));
            }

            builder.SendFees(defaultFees);
            builder.SetChange(storageKey.ScriptPubKey, ChangeType.All);

            NBitcoin.Transaction transaction = builder.BuildTransaction(true);

            return(new ByteString(transaction.ToBytes()));
        }
コード例 #8
0
        public async Task <IBlockchainTransaction> GetTransactionAsync(
            string txId,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Info.Blockchain.API.Models.Transaction tx;

            try
            {
                tx = await _explorer
                     .GetTransactionByHashAsync(txId)
                     .ConfigureAwait(false);
            }
            catch (ServerApiException e)
            {
                Log.Warning("Server api exception while get transaction by id {@txId}: {@message}",
                            txId,
                            ResolveExceptionMessage(e));

                return(null);
            }

            return(new BitcoinBasedTransaction(
                       currency: _currency,
                       tx: Transaction.Parse(await GetTxHexAsync(txId).ConfigureAwait(false), _currency.Network),
                       blockInfo: new BlockInfo
            {
                Fees = await GetTxFeeAsync(txId).ConfigureAwait(false),
                Confirmations = (int)(await GetBlockCountAsync().ConfigureAwait(false) - tx.BlockHeight + 1),
                BlockHeight = tx.BlockHeight,
                FirstSeen = tx.Time,
                BlockTime = tx.Time
            }));
        }
コード例 #9
0
        private string GetScriptString(NBitcoin.Transaction transaction)
        {
            var output = transaction.Outputs.FirstOrDefault(c => c.Value.Equals(Money.Zero));

            if (output == null)
            {
                transaction.ToString(); //TODO: UnCOmment exception
            }
            //throw new Exception("Transaction without integration output:  " + transaction.GetHash().ToString());
            else
            {
                try
                {
                    var coin   = new NBitcoin.Coin(transaction, output);
                    var script = coin.GetScriptCode().ToString();
                    script = script.Replace("OP_RETURN ", "");
                    return(HexToString(script));
                }
                catch (Exception e)
                {
                    throw new Exception("Failed to process transaction output", e);
                }
            }

            return("");
        }
コード例 #10
0
        public static void Run(string[] args)
        {
            /*
             *                  query of transactions
             *     - https://www.blockchain.com/btc/tx/930a2114cdaa86e1fac46d15c74e81c09eee1d4150ff9d48e76cb0697d8e1d72
             *     - http://api.qbit.ninja/transactions/930a2114cdaa86e1fac46d15c74e81c09eee1d4150ff9d48e76cb0697d8e1d72
             *
             *     - https://bitcoinsays.com/930a2114cdaa86e1fac46d15c74e81c09eee1d4150ff9d48e76cb0697d8e1d72
             */


            // Create a client
            QBitNinjaClient client = new QBitNinjaClient(Network.Main);

            // Parse transaction id to NBitcoin.uint256 so the client can eat it
            uint256 transactionId = uint256.Parse("930a2114cdaa86e1fac46d15c74e81c09eee1d4150ff9d48e76cb0697d8e1d72");

            // Query the transaction
            GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result;

            NBitcoin.Transaction transaction = transactionResponse.Transaction;

            Console.WriteLine(transactionResponse.TransactionId); // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94
            Console.WriteLine(transaction.GetHash());             // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94

            printAddressesAsAcii(transactionResponse.ReceivedCoins);
        }
コード例 #11
0
        public static void Run(string[] args)
        {
            /*
             * String hex = "6a4dd7035765277265206e6f20737472616e6765727320746f206c6f76650a596f75206b6e6f77207468652072756c657320616e6420736f20646f20490a412066756c6c20636f6d6d69746d656e74277320776861742049276d207468696e6b696e67206f660a596f7520776f756c646e27742067657420746869732066726f6d20616e79206f74686572206775790a49206a7573742077616e6e612074656c6c20796f7520686f772049276d206665656c696e670a476f747461206d616b6520796f7520756e6465727374616e640a0a43484f5255530a4e6576657220676f6e6e61206769766520796f752075702c0a4e6576657220676f6e6e61206c657420796f7520646f776e0a4e6576657220676f6e6e612072756e2061726f756e6420616e642064657365727420796f750a4e6576657220676f6e6e61206d616b6520796f75206372792c0a4e6576657220676f6e6e612073617920676f6f646279650a4e6576657220676f6e6e612074656c6c2061206c696520616e64206875727420796f750a0a5765277665206b6e6f776e2065616368206f7468657220666f7220736f206c6f6e670a596f75722068656172742773206265656e20616368696e672062757420796f7527726520746f6f2073687920746f207361792069740a496e7369646520776520626f7468206b6e6f7720776861742773206265656e20676f696e67206f6e0a5765206b6e6f77207468652067616d6520616e6420776527726520676f6e6e6120706c61792069740a416e6420696620796f752061736b206d6520686f772049276d206665656c696e670a446f6e27742074656c6c206d6520796f7527726520746f6f20626c696e6420746f20736565202843484f525553290a0a43484f52555343484f5255530a284f6f68206769766520796f75207570290a284f6f68206769766520796f75207570290a284f6f6829206e6576657220676f6e6e6120676976652c206e6576657220676f6e6e6120676976650a286769766520796f75207570290a284f6f6829206e6576657220676f6e6e6120676976652c206e6576657220676f6e6e6120676976650a286769766520796f75207570290a0a5765277665206b6e6f776e2065616368206f7468657220666f7220736f206c6f6e670a596f75722068656172742773206265656e20616368696e672062757420796f7527726520746f6f2073687920746f207361792069740a496e7369646520776520626f7468206b6e6f7720776861742773206265656e20676f696e67206f6e0a5765206b6e6f77207468652067616d6520616e6420776527726520676f6e6e6120706c61792069742028544f2046524f4e54290a0a";
             * byte[] ascii = Encoders.Hex.DecodeData(hex);
             * String str = System.Text.Encoding.Default.GetString(ascii);
             *
             * Console.WriteLine(str);
             */
            /*
             *                  query of transactions
             *     - https://www.blockchain.com/btc/tx/d29c9c0e8e4d2a9790922af73f0b8d51f0bd4bb19940d9cf910ead8fbe85bc9b
             *     - http://api.qbit.ninja/transactions/d29c9c0e8e4d2a9790922af73f0b8d51f0bd4bb19940d9cf910ead8fbe85bc9b
             *
             *     - https://bitcoinsays.com/d29c9c0e8e4d2a9790922af73f0b8d51f0bd4bb19940d9cf910ead8fbe85bc9b
             */


            // Create a client
            QBitNinjaClient client = new QBitNinjaClient(Network.Main);

            // Parse transaction id to NBitcoin.uint256 so the client can eat it
            uint256 transactionId = uint256.Parse("d29c9c0e8e4d2a9790922af73f0b8d51f0bd4bb19940d9cf910ead8fbe85bc9b");

            // Query the transaction
            GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result;

            NBitcoin.Transaction transaction = transactionResponse.Transaction;

            printScriptsAsAcii(transactionResponse.ReceivedCoins);
        }
コード例 #12
0
        public TransactionVerboseModel(NBitcoin.Transaction trx, Network network, NBitcoin.ChainedBlock block = null, ChainedBlock tip = null) : base(trx)
        {
            if (trx != null)
            {
                this.txid     = trx.GetHash().ToString();
                this.size     = trx.GetSerializedSize();
                this.version  = trx.Version;
                this.locktime = trx.LockTime;

                this.vin = trx.Inputs.Select(txin => new Vin(txin.PrevOut, txin.Sequence, txin.ScriptSig)).ToList();

                int n = 0;
                this.vout = trx.Outputs.Select(txout => new Vout(n++, txout, network)).ToList();

                if (block != null)
                {
                    blockhash = block.HashBlock.ToString();
                    time      = blocktime = Utils.DateTimeToUnixTime(block.Header.BlockTime);
                    if (tip != null)
                    {
                        confirmations = tip.Height - block.Height + 1;
                    }
                }
            }
        }
コード例 #13
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);

            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);
        }
コード例 #14
0
ファイル: StealthPayment.cs プロジェクト: nikropht/NBitcoin
        public static StealthPayment[] GetPayments(Transaction transaction, PubKey[] spendKeys, BitField bitField, Key scan)
        {
            List<StealthPayment> result = new List<StealthPayment>();
            for(int i = 0 ; i < transaction.Outputs.Count ; i++)
            {
                var metadata = StealthMetadata.TryParse(transaction.Outputs[i].ScriptPubKey);
                if(metadata != null && bitField.Match(metadata.BitField))
                {
                    var payment = new StealthPayment(transaction.Outputs[i + 1].ScriptPubKey, metadata);
                    if(scan != null && spendKeys != null)
                    {
                        if(payment.StealthKeys.Length != spendKeys.Length)
                            continue;

                        var expectedStealth = spendKeys.Select(s => s.UncoverReceiver(scan, metadata.EphemKey)).ToList();
                        foreach(var stealth in payment.StealthKeys)
                        {
                            var match = expectedStealth.FirstOrDefault(expected => expected.ID == stealth.ID);
                            if(match != null)
                                expectedStealth.Remove(match);
                        }
                        if(expectedStealth.Count != 0)
                            continue;
                    }
                    result.Add(payment);
                }
            }
            return result.ToArray();
        }
コード例 #15
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();
            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);
        }
コード例 #16
0
        protected virtual void CreatePayloadOutputs(Transaction tx, Money reward)
        {
            if (coinbasepayloadParameters.CoinbasePayload != null)
            {
                CoinbasePayload[] coinbasepayloads;
                if (coinbasepayloadParameters.CoinbasePayload.Type == JTokenType.Array)
                {
                    coinbasepayloads = coinbasepayloadParameters.CoinbasePayload.ToObject <CoinbasePayload[]>();
                }
                else
                {
                    coinbasepayloads = new[] { coinbasepayloadParameters.CoinbasePayload.ToObject <CoinbasePayload>() }
                };

                foreach (var CoinbasePayee in coinbasepayloads)
                {
                    if (!string.IsNullOrEmpty(CoinbasePayee.Payee))
                    {
                        var payeeAddress = BitcoinUtils.CashAddrToDestination(CoinbasePayee.Payee, network, true);
                        var payeeReward  = CoinbasePayee.Amount;

                        tx.Outputs.Add(payeeReward, payeeAddress);
                    }
                }
            }
        }
コード例 #17
0
        public static bool IsConsolidationTxn(Transaction transaction, ConsolidationTxParameters consolidationParameters, PrevOut[] prevOuts)
        {
            // The consolidation factor zero disables free consolidation txns
            if (consolidationParameters.MinConsolidationFactor == 0)
            {
                return(false);
            }

            if (transaction.IsCoinBase)
            {
                return(false);
            }

            // The transaction does not decrease #UTXO enough
            if (transaction.Inputs.Count < consolidationParameters.MinConsolidationFactor * transaction.Outputs.Count)
            {
                return(false);
            }

            long sumScriptPubKeySizesTxInputs = 0;

            // combine input with corresponding output it is spending
            var pairsInOut = transaction.Inputs.Zip(prevOuts,
                                                    (i, o) =>
                                                    new
            {
                input  = i,
                output = o
            });

            foreach (var item in pairsInOut)
            {
                // Transaction has less than minConsInputMaturity confirmations
                if (item.output.Confirmations < consolidationParameters.MinConsolidationInputMaturity)
                {
                    return(false);
                }
                // Spam detection
                if (item.input.ScriptSig.Length > consolidationParameters.MaxConsolidationInputScriptSize)
                {
                    return(false);
                }
                if (!consolidationParameters.AcceptNonStdConsolidationInput && !item.output.IsStandard)
                {
                    return(false);
                }
                sumScriptPubKeySizesTxInputs += item.output.ScriptPubKeyLength;
            }

            long sumScriptPubKeySizesTxOutputs = transaction.Outputs.Sum(x => x.ScriptPubKey.Length);

            // Size in utxo db does not decrease enough for cons. transaction to be profitable
            if (sumScriptPubKeySizesTxInputs < consolidationParameters.MinConsolidationFactor * sumScriptPubKeySizesTxOutputs)
            {
                return(false);
            }

            return(true);
        }
コード例 #18
0
		public bool Check(PubKey pubKey, Script scriptPubKey, Transaction tx, uint nIndex, ScriptVerify verify = ScriptVerify.Standard)
		{
			return new ScriptEvaluationContext()
			{
				ScriptVerify = verify,
				SigHash = SigHash
			}.CheckSig(this, pubKey, scriptPubKey, tx, nIndex);
		}
コード例 #19
0
 public void AddFromTransaction(Transaction transaction)
 {
     var hash = transaction.GetHash();
     for(int i = 0 ; i < transaction.Outputs.Count; i++)
     {
         AddTxOut(new OutPoint(hash, i), transaction.Outputs[i]);
     }
 }
コード例 #20
0
        protected virtual Money CreateMasternodeOutputs(Transaction tx, Money reward)
        {
            if (masterNodeParameters.Masternode != null)
            {
                Masternode[] masternodes;

                // Dash v13 Multi-Master-Nodes
                if (masterNodeParameters.Masternode.Type == JTokenType.Array)
                {
                    masternodes = masterNodeParameters.Masternode.ToObject <Masternode[]>();
                }
                else
                {
                    masternodes = new[] { masterNodeParameters.Masternode.ToObject <Masternode>() }
                };

                foreach (var masterNode in masternodes)
                {
                    if (!string.IsNullOrEmpty(masterNode.Payee))
                    {
                        var payeeAddress = BitcoinUtils.AddressToDestination(masterNode.Payee, network);
                        var payeeReward  = masterNode.Amount;

                        reward       -= payeeReward;
                        rewardToPool -= payeeReward;

                        tx.Outputs.Add(payeeReward, payeeAddress);
                    }
                }
            }

            if (masterNodeParameters.SuperBlocks != null && masterNodeParameters.SuperBlocks.Length > 0)
            {
                foreach (var superBlock in masterNodeParameters.SuperBlocks)
                {
                    var payeeAddress = BitcoinUtils.AddressToDestination(superBlock.Payee, network);
                    var payeeReward  = superBlock.Amount;

                    reward       -= payeeReward;
                    rewardToPool -= payeeReward;

                    tx.Outputs.Add(payeeReward, payeeAddress);
                }
            }

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

                reward       -= payeeReward;
                rewardToPool -= payeeReward;

                tx.Outputs.Add(payeeReward, payeeAddress);
            }

            return(reward);
        }
コード例 #21
0
    public static void Spend(this Transaction txn, Action <string> a)
    {
        var txnReportRequest = new HTTPRequest(
            new Uri(TxnBroadcastEndpoint), HTTPMethods.Post,
            (txnR, txnResponse) =>
        {
            try
            {
                var response = JsonConvert.DeserializeAnonymousType(txnResponse.DataAsText,
                                                                    new { Success = false, R = "", Message = "" });
                if (!response.Success)
                {
                    Debug.LogError("Spend response was unsuccessful - " + response.Message);
                    Debug.LogError(txnResponse.DataAsText);
                    throw new SpendUTXOException(response.Message);
                }

                var hashRegex = new Regex(@"^([A-Fa-f0-9]{64})$");
                if (hashRegex.IsMatch(response.R))
                {
                    a(response.R);
                }
                else
                {
                    Debug.LogError("Failed spending utxo, return hash wasn't an hash");
                    Debug.LogError(txnResponse.DataAsText);
                    throw new SpendUTXOException(txnResponse.DataAsText);
                }
            }
            catch (Exception e)
            {
                if (txnResponse != null)
                {
                    Debug.LogError("Fatal error: " + txnResponse.DataAsText);
                }
                else
                {
                    Debug.LogError("Failed to spend transaction");
                    Debug.LogError(txnR.Exception.Message);
                }

                Debug.LogError($"{e.GetType()}: {e.Message}");

                ModalDialog.Instance.CallbackYes.AddListener(() => { SceneManager.LoadScene("Main"); });
                ModalDialog.Instance.Show("Failed to spend UTXO",
                                          $"{e.GetType()}: {e.Message}",
                                          "Ok");

                //Debug.LogError(JsonConvert.SerializeObject(txn));
                //Debug.LogError($"{{\"tx\":\"{txn.ToHex()}\"}}");
            }
        });

        txnReportRequest.AddHeader("Content-Type", "application/json");
        txnReportRequest.RawData = Encoding.UTF8.GetBytes($"{{\"tx\":\"{txn.ToHex()}\"}}");
        txnReportRequest.Send();
    }
コード例 #22
0
        /// <inheritdoc />
        public void ProcessTransaction(Transaction transaction, int?blockHeight = null, Block block = null)
        {
            Guard.NotNull(transaction, nameof(transaction));

            var hash = transaction.GetHash();

            this.logger.LogTrace($"transaction received - hash: {hash}, coin: {this.coinType}");

            // load the keys for lookup if they are not loaded yet.
            if (this.keysLookup == null)
            {
                this.LoadKeysLookup();
            }

            // check the outputs
            foreach (TxOut utxo in transaction.Outputs)
            {
                // check if the outputs contain one of our addresses
                if (this.keysLookup.TryGetValue(utxo.ScriptPubKey, out HdAddress pubKey))
                {
                    this.AddTransactionToWallet(transaction.ToHex(), hash, transaction.Time, transaction.Outputs.IndexOf(utxo), utxo.Value, utxo.ScriptPubKey, blockHeight, block);
                }
            }

            // check the inputs - include those that have a reference to a transaction containing one of our scripts and the same index
            foreach (TxIn input in transaction.Inputs.Where(txIn => this.keysLookup.Values.Distinct().SelectMany(v => v.Transactions).Any(trackedTx => trackedTx.Id == txIn.PrevOut.Hash && trackedTx.Index == txIn.PrevOut.N)))
            {
                TransactionData tTx = this.keysLookup.Values.Distinct().SelectMany(v => v.Transactions).Single(trackedTx => trackedTx.Id == input.PrevOut.Hash && trackedTx.Index == input.PrevOut.N);

                // find the script this input references
                var keyToSpend = this.keysLookup.First(v => v.Value.Transactions.Contains(tTx)).Key;

                // get the details of the outputs paid out.
                IEnumerable <TxOut> paidoutto = transaction.Outputs.Where(o =>
                {
                    // if script is empty ignore it
                    if (o.IsEmpty)
                    {
                        return(false);
                    }

                    var found = this.keysLookup.TryGetValue(o.ScriptPubKey, out HdAddress addr);

                    // include the keys we don't hold
                    if (!found)
                    {
                        return(true);
                    }

                    // include the keys we do hold but that are for receiving
                    // addresses (which would mean the user paid itself).
                    return(!addr.IsChangeAddress());
                });

                this.AddSpendingTransactionToWallet(transaction.ToHex(), hash, transaction.Time, paidoutto, tTx.Id, tTx.Index, blockHeight, block);
            }
        }
コード例 #23
0
        protected virtual Transaction CreateOutputTransaction()
        {
            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = Transaction.Create(network);

            tx.Outputs.Add(rewardToPool, poolAddressDestination);

            return(tx);
        }
コード例 #24
0
ファイル: BlockRepository.cs プロジェクト: firoorg/zsharp
        Transaction ToEntity(NBitcoin.Transaction tx)
        {
            var entity = new Transaction(
                tx.GetHash(),
                tx.GetTransactionType(),
                (short)Convert.ToUInt16(tx.Version),
                tx.LockTime);

            // Outputs.
            for (int i = 0; i < tx.Outputs.Count; i++)
            {
                var output = new Output(entity.Hash, i, tx.Outputs[i].ScriptPubKey, tx.Outputs[i].Value);
                entity.Outputs.Add(output);
            }

            // Inputs.
            for (int i = 0; i < tx.Inputs.Count; i++)
            {
                var input = new Input(
                    entity.Hash,
                    i,
                    tx.Inputs[i].PrevOut.Hash,
                    (int)tx.Inputs[i].PrevOut.N,
                    tx.Inputs[i].ScriptSig,
                    (int)tx.Inputs[i].Sequence.Value);

                entity.Inputs.Add(input);
            }

            // Extra payload.
            var extra = tx.GetExtraPayload();

            if (extra.Length != 0)
            {
                entity.ExtraPayload = extra;
            }

            // Elysium.
            var elysium = tx.GetElysiumTransaction();

            if (elysium != null)
            {
                var serialized = new ArrayBufferWriter <byte>();

                this.elysiumSerializer.Serialize(serialized, elysium);

                entity.Elysium = new ElysiumTransaction(
                    entity.Hash,
                    elysium.Sender?.ToString(),
                    elysium.Receiver?.ToString(),
                    serialized.WrittenSpan.ToArray());
            }

            return(entity);
        }
コード例 #25
0
		public static void Put(this ITransactionRepository repo, uint256 txId, Transaction tx)
		{
			try
			{
				repo.PutAsync(txId, tx).Wait();
			}
			catch(AggregateException aex)
			{
				ExceptionDispatchInfo.Capture(aex.InnerException).Throw();
			}
		}
コード例 #26
0
ファイル: TransactionBTC.cs プロジェクト: Plaznum/BlockLogic
        public void TestTransactionInfo()
        {
            QBitNinjaClient client        = new QBitNinjaClient(Network.Main);
            var             transactionId = uint256.Parse("f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94");

            GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result;

            NBitcoin.Transaction transaction = transactionResponse.Transaction;

            Console.WriteLine(transactionResponse.TransactionId);
            Console.WriteLine(transaction.GetHash());
            Console.WriteLine();
            //Received Coins
            Console.WriteLine("Outputs:");
            var outputs = transaction.Outputs;

            foreach (TxOut output in outputs)
            {
                Money amount = output.Value;

                Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC));
                var paymentScript = output.ScriptPubKey;
                Console.WriteLine("ScriptPubKey: " + paymentScript);  // It's the ScriptPubKey
                var address = paymentScript.GetDestinationAddress(Network.Main);
                Console.WriteLine("address: " + address);
                Console.WriteLine();
            }
            //Spent Coins
            Console.WriteLine("Inputs:");
            Money receivedAmount = Money.Zero;
            var   inputs         = transaction.Inputs;

            foreach (TxIn input in inputs)
            {
                OutPoint previousOutpoint = input.PrevOut;
                Console.WriteLine("Prev Outpoint Hash: " + previousOutpoint.Hash); // hash of prev tx
                Console.WriteLine("Prev Outpoint Index: " + previousOutpoint.N);   // idx of out from prev tx, that has been spent in the current tx
                Console.WriteLine();
            }
            Console.WriteLine("Amount of inputs: " + transaction.Inputs.Count);

            var spentCoins = transactionResponse.SpentCoins;

            foreach (var spentCoin in spentCoins)
            {
                receivedAmount = (Money)spentCoin.Amount.Add(receivedAmount);
            }
            Console.WriteLine("Bitcoin Received: " + receivedAmount.ToDecimal(MoneyUnit.BTC));

            var fee = transaction.GetFee(spentCoins.ToArray());

            Console.Write("Fees (in Satoshis): ");
            Console.WriteLine(fee);
        }
コード例 #27
0
ファイル: Coins.cs プロジェクト: royosherove/NBitcoin
 public Coins(Transaction tx, Func<TxOut, bool> belongsToCoins, int height)
 {
     if(belongsToCoins == null)
         belongsToCoins = o => !o.ScriptPubKey.IsUnspendable;
     fCoinBase = tx.IsCoinBase;
     vout = tx.Outputs.ToList();
     nVersion = tx.Version;
     nHeight = (uint)height;
     ClearUnused(belongsToCoins);
     UpdateValue();
 }
コード例 #28
0
ファイル: Transaction.cs プロジェクト: jsolja/BitcoinWallet
 public Transaction(BitcoinSecret[] bitcoinSecrets, decimal fee, decimal amount, string destination)
 {
     this.bitcoinSecrets     = bitcoinSecrets;
     this.fee                = fee;
     this.amount             = amount / 1000;
     this.destination        = BitcoinAddress.Create(destination, Network.TestNet);
     this.transaction        = new NBitcoin.Transaction();
     this.currentAmount      = 0.0M;
     this.transactionBuilder = new TransactionBuilder();
     this.unspentCoins       = new List <Coin>();
 }
コード例 #29
0
        //send signed tx hex to bitcoin network
        public static string BroadcastTx(string SignedTxHex, bool testnet)
        {
            CheckNullOrEmpty(new object[] { SignedTxHex, BTChost }, new string[] { "SignedTxHex", "BTChost" });

            NBitcoin.Transaction tx = NBitcoin.Transaction.Parse(SignedTxHex);
            Network ntwk            = testnet ? Network.TestNet : Network.Main;
            string  err             = "";

            var nd = Node.Connect(ntwk, BTChost + ":" + BTCport);             //DACC bitcoin server (BitcoinD)

            //bitcoin node sends responses asynchronously
            nd.MessageReceived += (node, message) =>
            {
                NBitcoin.Protocol.IncomingMessage msgx = message;
                if (msgx.Message.Payload is RejectPayload)                         //error message
                {
                    RejectPayload py = (RejectPayload)msgx.Message.Payload;
                    Console.WriteLine("Rejected:" + py.Message + " " + py.Reason);
                    err += py.Message + " " + py.Reason;
                }
            };
            nd.VersionHandshake();             //must send node version first
            Thread.Sleep(1000);
            nd.SendMessage(new InvPayload(tx));
            Thread.Sleep(1000);
            nd.SendMessage(new TxPayload(tx));
            Thread.Sleep(5000);             //wait for any error msgs
            string msg = tx.GetHash().ToString();

            try
            {
                bool broadcasted = false;
                //search mempool for transaction
                foreach (var txid in nd.GetMempool())                 //throws error for some servers
                {
                    if (txid.Equals(tx.GetHash()))
                    {
                        broadcasted = true;
                    }
                }
                nd.Disconnect();
                //return json message
                if (!broadcasted)
                {
                    msg = "Broadcast Failed (tx hash = " + tx.GetHash().ToString() + ")" + err + "\"}";
                }
                else
                {
                    msg = tx.GetHash().ToString();
                }
            }
            catch (Exception ex) { msg = "Error (BroadcastTx): " + ex.Message; }
            return(msg);
        }
コード例 #30
0
        protected virtual Transaction CreatePayloadOutputTransaction()
        {
            var blockReward = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);
            var tx          = Transaction.Create(network);

            // Firstly pay coins to pool addr
            tx.Outputs.Insert(0, new TxOut(blockReward, poolAddressDestination));
            // then create payloads incase there is any coinbase_payload in gbt
            CreatePayloadOutputs(tx, rewardToPool);
            return(tx);
        }
コード例 #31
0
        protected override Transaction CreateOutputTransaction()
        {
            rewardToPool = new Money(BlockTemplate.CoinbaseValue * blockRewardMultiplier, MoneyUnit.Satoshi);

            var tx = Transaction.Create(NBitcoinNetworkType);

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

            return(tx);
        }
コード例 #32
0
		public Task PutAsync(uint256 txId, Transaction tx)
		{
			using(@lock.LockWrite())
			{
				if(!_Transactions.ContainsKey(txId))
					_Transactions.AddOrReplace(txId, tx);
				else
					_Transactions[txId] = tx;
			}
			return _Inner.PutAsync(txId, tx);
		}
コード例 #33
0
 public static void SendTransaction(Transaction tx)
 {
     AddressManager nodeParams = new AddressManager();
     IPEndPoint endPoint = TranslateHostNameToIP("http://btcnode.placefullcloud.com", 8333);
     nodeParams.Add(new NetworkAddress(endPoint), endPoint.Address);
     using (var node = Node.Connect(Network, nodeParams))
     {
         node.VersionHandshake();
         node.SendMessage(new InvPayload(InventoryType.MSG_TX, tx.GetHash()));
         node.SendMessage(new TxPayload(tx));
     }
 }
コード例 #34
0
 public static LockType GetLockType(this NBitcoin.Transaction tx)
 {
     if (tx.LockTime.IsHeightLock)
     {
         return(LockType.Height);
     }
     if (tx.LockTime.IsTimeLock)
     {
         return(LockType.Time);
     }
     return(LockType.None);
 }
コード例 #35
0
		internal void OnBroadcastTransaction(Transaction transaction)
		{
			var hash = transaction.GetHash();
			var nodes = Nodes
						.Select(n => n.Key.Behaviors.Find<BroadcastHubBehavior>())
						.Where(n => n != null)
						.ToArray();
			foreach(var node in nodes)
			{
				node.BroadcastTransactionCore(transaction);
			}
		}
コード例 #36
0
        protected virtual void BuildCoinbase()
        {
            var sigScriptInitial      = GenerateScriptSigInitial();
            var sigScriptInitialBytes = sigScriptInitial.ToBytes();

            var sigScriptLength = (uint)(
                sigScriptInitial.Length +
                extraNoncePlaceHolderLength +
                scriptSigFinalBytes.Length);

            txOut = CreateOutputTransaction();

            using (var stream = new MemoryStream())
            {
                var bs = new BitcoinStream(stream, true);

                bs.ReadWrite(ref txVersion);

                if (isPoS)
                {
                    var timestamp = BlockTemplate.CurTime;
                    bs.ReadWrite(ref timestamp);
                }

                bs.ReadWriteAsVarInt(ref txInputCount);
                bs.ReadWrite(ref sha256Empty);
                bs.ReadWrite(ref txInPrevOutIndex);

                bs.ReadWriteAsVarInt(ref sigScriptLength);
                bs.ReadWrite(ref sigScriptInitialBytes);

                coinbaseInitial    = stream.ToArray();
                coinbaseInitialHex = coinbaseInitial.ToHexString();
            }

            using (var stream = new MemoryStream())
            {
                var bs = new BitcoinStream(stream, true);

                bs.ReadWrite(ref scriptSigFinalBytes);

                bs.ReadWrite(ref txInSequence);

                var txOutBytes = SerializeOutputTransaction(txOut);
                bs.ReadWrite(ref txOutBytes);

                bs.ReadWrite(ref txLockTime);

                coinbaseFinal    = stream.ToArray();
                coinbaseFinalHex = coinbaseFinal.ToHexString();
            }
        }
コード例 #37
0
ファイル: Program.cs プロジェクト: LykkeCity/Prototypes
 static Coin CreateTransactionFeeCoin(PubKey destination, NoSqlTransactionRepository txRepo)
 {
     var bitcoinProviderTransaction = new Transaction()
     {
         Outputs =
         {
             new TxOut("0.0001" , destination)
         }
     };
     txRepo.Put(bitcoinProviderTransaction.GetHash(), bitcoinProviderTransaction);
     return new Coin(new OutPoint(bitcoinProviderTransaction, 0),
         bitcoinProviderTransaction.Outputs[0]);
 }
コード例 #38
0
        protected virtual Transaction CreateOutputTransaction()
        {
            rewardToPool = new Money(BlockTemplate.CoinbaseValue * blockRewardMultiplier, MoneyUnit.Satoshi);

            var tx = new Transaction();

            tx.Outputs.Insert(0, new TxOut(rewardToPool, poolAddressDestination)
            {
                Value = rewardToPool
            });

            return(tx);
        }
コード例 #39
0
    protected override Transaction CreateOutputTransaction()
    {
        rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

        var tx = Transaction.Create(network);

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

        tx.Inputs.Add(TxIn.CreateCoinbase((int)BlockTemplate.Height));

        return(tx);
    }
コード例 #40
0
ファイル: StandardScripts.cs プロジェクト: nikropht/NBitcoin
        //
        // Check transaction inputs, and make sure any
        // pay-to-script-hash transactions are evaluating IsStandard scripts
        //
        // Why bother? To avoid denial-of-service attacks; an attacker
        // can submit a standard HASH... OP_EQUAL transaction,
        // which will get accepted into blocks. The redemption
        // script can be anything; an attacker could use a very
        // expensive-to-check-upon-redemption script like:
        //   DUP CHECKSIG DROP ... repeated 100 times... OP_1
        //
        public static bool AreInputsStandard(Transaction tx, CoinsView coinsView)
        {
            if(tx.IsCoinBase)
                return true; // Coinbases don't use vin normally

            for(int i = 0 ; i < tx.Inputs.Count ; i++)
            {
                TxOut prev = coinsView.GetOutputFor(tx.Inputs[i]);
                if(prev == null)
                    return false;
                if(!IsStandardScriptSig(tx.Inputs[i].ScriptSig, prev.ScriptPubKey))
                    return false;
            }

            return true;
        }
コード例 #41
0
 public TrustedInput GetTrustedInput(Transaction transaction, int outputIndex)
 {
     using(Transport.Lock())
     {
         if(outputIndex >= transaction.Outputs.Count)
             throw new ArgumentOutOfRangeException("outputIndex is bigger than the number of outputs in the transaction", "outputIndex");
         MemoryStream data = new MemoryStream();
         // Header
         BufferUtils.WriteUint32BE(data, outputIndex);
         BufferUtils.WriteBuffer(data, transaction.Version);
         VarintUtils.write(data, transaction.Inputs.Count);
         ExchangeApdu(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x00, (byte)0x00, data.ToArray(), OK);
         // Each input
         foreach(var input in transaction.Inputs)
         {
             data = new MemoryStream();
             BufferUtils.WriteBuffer(data, input.PrevOut);
             VarintUtils.write(data, input.ScriptSig.Length);
             ExchangeApdu(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray(), OK);
             data = new MemoryStream();
             BufferUtils.WriteBuffer(data, input.ScriptSig.ToBytes());
             ExchangeApduSplit2(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray(), Utils.ToBytes(input.Sequence, true), OK);
         }
         // Number of outputs
         data = new MemoryStream();
         VarintUtils.write(data, transaction.Outputs.Count);
         ExchangeApdu(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray(), OK);
         // Each output
         foreach(var output in transaction.Outputs)
         {
             data = new MemoryStream();
             BufferUtils.WriteBuffer(data, Utils.ToBytes((ulong)output.Value.Satoshi, true));
             VarintUtils.write(data, output.ScriptPubKey.Length);
             ExchangeApdu(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray(), OK);
             data = new MemoryStream();
             BufferUtils.WriteBuffer(data, output.ScriptPubKey.ToBytes());
             ExchangeApduSplit(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray(), OK);
         }
         // Locktime
         byte[] response = ExchangeApdu(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, transaction.LockTime.ToBytes(), OK);
         return new TrustedInput(response);
     }
 }
コード例 #42
0
		public Task PutAsync(uint256 txId, Transaction tx)
		{
			if(WriteThrough)
			{
				using(@lock.LockWrite())
				{

					if(!_Transactions.ContainsKey(txId))
					{

						_Transactions.AddOrReplace(txId, tx);
						EvictIfNecessary(txId);
					}
					else
						_Transactions[txId] = tx;
				}
			}
			return _Inner.PutAsync(txId, tx);
		}
コード例 #43
0
        public static void Submit(Transaction tx)
        {
            //SOME TEST NET NODES
            //54.149.133.4:18333
            //52.69.206.155:18333
            //93.114.160.222:18333
            string url = "93.114.160.222:18333";
            using(var node = NBitcoin.Protocol.Node.Connect(NBitcoin.Network.TestNet, url))
            {
                node.VersionHandshake();
                //System.Threading.Thread.Sleep(1000);

                NBitcoin.Transaction[] transactions = new Transaction[1];
                transactions[0] = tx;

                node.SendMessage(new NBitcoin.Protocol.InvPayload(transactions));
                node.SendMessage(new NBitcoin.Protocol.TxPayload(tx));
            }
        }
コード例 #44
0
		public async Task<Transaction> GetAsync(uint256 txId)
		{
			while(true)
			{
				using(HttpClient client = new HttpClient())
				{
					var response = await client.GetAsync(BlockrAddress + "tx/raw/" + txId).ConfigureAwait(false);
					if(response.StatusCode == HttpStatusCode.NotFound)
						return null;
					var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
					var json = JObject.Parse(result);
					var status = json["status"];
					var code = json["code"];
					if(status != null && status.ToString() == "error")
					{
						throw new BlockrException(json);
					}
					var tx = new Transaction(json["data"]["tx"]["hex"].ToString());
					return tx;
				}
			}
		}
コード例 #45
0
        public static string GetHexSignedTransaction(TransactionToSign txToSign)
        {
            var walletPrivateKey = ConfigurationManager.AppSettings[METACO_ENV_WALLET_PRIVATE_KEY_HEX_NAME];

            var key = new Key(Encoders.Hex.DecodeData(walletPrivateKey));

            var scriptPubKey = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(key.PubKey);
            var tx = new Transaction(Encoders.Hex.DecodeData(txToSign.Raw));

            foreach(var inputsToSign in txToSign.InputsToSign)
            {
                var sigHash = tx.GetSignatureHash(scriptPubKey, inputsToSign.Index);
                var sig = key.Sign(sigHash);

                var txSign = new TransactionSignature(sig, SigHash.All);
                var inputScript = PayToPubkeyHashTemplate.Instance.GenerateScriptSig(txSign, key.PubKey);

                tx.Inputs[inputsToSign.Index].ScriptSig = inputScript;
                Assert.True(Script.VerifyScript(scriptPubKey, tx, inputsToSign.Index));
            }

            return tx.ToHex();
        }
コード例 #46
0
ファイル: ValidationState.cs プロジェクト: xcrash/NBitcoin
		private int GetLegacySigOpCount(Transaction tx)
		{
			uint nSigOps = 0;
			foreach(var txin in tx.Inputs)
			{
				nSigOps += txin.ScriptSig.GetSigOpCount(false);
			}
			foreach(var txout in tx.Outputs)
			{
				nSigOps += txout.ScriptPubKey.GetSigOpCount(false);
			}
			return (int)nSigOps;
		}
コード例 #47
0
ファイル: ValidationState.cs プロジェクト: xcrash/NBitcoin
		//struct GetRejectReason()  { return strRejectReason; }

		public bool CheckTransaction(Transaction tx)
		{
			// Basic checks that don't depend on any context
			if(tx.Inputs.Count == 0)
				return DoS(10, Utils.error("CheckTransaction() : vin empty"),
								 RejectCode.INVALID, "bad-txns-vin-empty");
			if(tx.Outputs.Count == 0)
				return DoS(10, Utils.error("CheckTransaction() : vout empty"),
								 RejectCode.INVALID, "bad-txns-vout-empty");
			// Size limits
			if(tx.ToBytes().Length > MAX_BLOCK_SIZE)
				return DoS(100, Utils.error("CheckTransaction() : size limits failed"),
								 RejectCode.INVALID, "bad-txns-oversize");

			// Check for negative or overflow output values
			long nValueOut = 0;
			foreach(var txout in tx.Outputs)
			{
				if(txout.Value < 0)
					return DoS(100, Utils.error("CheckTransaction() : txout.nValue negative"),
									 RejectCode.INVALID, "bad-txns-vout-negative");
				if(txout.Value > MAX_MONEY)
					return DoS(100, Utils.error("CheckTransaction() : txout.nValue too high"),
									 RejectCode.INVALID, "bad-txns-vout-toolarge");
				nValueOut += (long)txout.Value;
				if(!((nValueOut >= 0 && nValueOut <= (long)MAX_MONEY)))
					return DoS(100, Utils.error("CheckTransaction() : txout total out of range"),
									 RejectCode.INVALID, "bad-txns-txouttotal-toolarge");
			}

			// Check for duplicate inputs
			HashSet<OutPoint> vInOutPoints = new HashSet<OutPoint>();
			foreach(var txin in tx.Inputs)
			{
				if(vInOutPoints.Contains(txin.PrevOut))
					return DoS(100, Utils.error("CheckTransaction() : duplicate inputs"),
									 RejectCode.INVALID, "bad-txns-inputs-duplicate");
				vInOutPoints.Add(txin.PrevOut);
			}

			if(tx.IsCoinBase)
			{
				if(tx.Inputs[0].ScriptSig.Length < 2 || tx.Inputs[0].ScriptSig.Length > 100)
					return DoS(100, Utils.error("CheckTransaction() : coinbase script size"),
									 RejectCode.INVALID, "bad-cb-length");
			}
			else
			{
				foreach(var txin in tx.Inputs)
					if(txin.PrevOut.IsNull)
						return DoS(10, Utils.error("CheckTransaction() : prevout is null"),
										 RejectCode.INVALID, "bad-txns-prevout-null");
			}

			return true;
		}
コード例 #48
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, out ScriptError error)
		{
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, ScriptVerify.Standard, SigHash.Undefined, out error);
		}
コード例 #49
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptSig, Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
		{
			var eval = new ScriptEvaluationContext
			{
				SigHash = sigHash,
				ScriptVerify = scriptVerify
			};
			var result = eval.VerifyScript(scriptSig, scriptPubKey, tx, i);
			error = eval.Error;
			return result;
		}
コード例 #50
0
ファイル: StandardScripts.cs プロジェクト: xcrash/NBitcoin
		public static bool IsStandardTransaction(Transaction tx)
		{
			if(tx.Version > Transaction.CURRENT_VERSION || tx.Version < 1)
			{
				return false;
			}

			//// Treat non-final transactions as non-standard to prevent a specific type
			//// of double-spend attack, as well as DoS attacks. (if the transaction
			//// can't be mined, the attacker isn't expending resources broadcasting it)
			//// Basically we don't want to propagate transactions that can't included in
			//// the next block.
			////
			//// However, IsFinalTx() is confusing... Without arguments, it uses
			//// chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
			//// is set to the value of nHeight in the block. However, when IsFinalTx()
			//// is called within CBlock::AcceptBlock(), the height of the block *being*
			//// evaluated is what is used. Thus if we want to know if a transaction can
			//// be part of the *next* block, we need to call IsFinalTx() with one more
			//// than chainActive.Height().
			////
			//// Timestamps on the other hand don't get any special treatment, because we
			//// can't know what timestamp the next block will have, and there aren't
			//// timestamp applications where it matters.
			//if (!IsFinalTx(tx, chainActive.Height() + 1)) {
			//	reason = "non-final";
			//	return false;
			//}

			// Extremely large transactions with lots of inputs can cost the network
			// almost as much to process as they cost the sender in fees, because
			// computing signature hashes is O(ninputs*txsize). Limiting transactions
			// to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
			int sz = tx.GetSerializedSize();
			if(sz >= Transaction.MAX_STANDARD_TX_SIZE)
				return false;


			foreach(TxIn txin in tx.Inputs)
			{
				// Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
				// keys. (remember the 520 byte limit on redeemScript size) That works
				// out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
				// bytes of scriptSig, which we round off to 1650 bytes for some minor
				// future-proofing. That's also enough to spend a 20-of-20
				// CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
				// considered standard)
				if (txin.ScriptSig.Length > 1650)
				{
					return false;
				}
				if(!txin.ScriptSig.IsPushOnly)
				{
					return false;
				}
				if(!txin.ScriptSig.HasCanonicalPushes)
				{
					return false;
				}
			}

			uint nDataOut = 0;
			foreach(TxOut txout in tx.Outputs)
			{
				var template = StandardScripts.GetTemplateFromScriptPubKey(txout.ScriptPubKey);
				if(template == null)
					return false;

				if(template.Type == TxOutType.TX_NULL_DATA)
					nDataOut++;
				else if(txout.IsDust)
					return false;
			}
			// only one OP_RETURN txout is permitted
			if(nDataOut > 1)
			{
				return false;
			}

			return true;
		}
コード例 #51
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		private static Script CombineMultisig(Script scriptPubKey, Transaction transaction, int n, byte[][] sigs1, byte[][] sigs2)
		{
			// Combine all the signatures we've got:
			List<TransactionSignature> allsigs = new List<TransactionSignature>();
			foreach(var v in sigs1)
			{
				if(TransactionSignature.IsValid(v))
				{
					allsigs.Add(new TransactionSignature(v));
				}
			}


			foreach(var v in sigs2)
			{
				if(TransactionSignature.IsValid(v))
				{
					allsigs.Add(new TransactionSignature(v));
				}
			}

			var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);
			if(multiSigParams == null)
				throw new InvalidOperationException("The scriptPubKey is not a valid multi sig");

			Dictionary<PubKey, TransactionSignature> sigs = new Dictionary<PubKey, TransactionSignature>();

			foreach(var sig in allsigs)
			{
				foreach(var pubkey in multiSigParams.PubKeys)
				{
					if(sigs.ContainsKey(pubkey))
						continue; // Already got a sig for this pubkey

					ScriptEvaluationContext eval = new ScriptEvaluationContext();
					if(eval.CheckSig(sig.ToBytes(), pubkey.ToBytes(), scriptPubKey, transaction, n))
					{
						sigs.AddOrReplace(pubkey, sig);
					}
				}
			}


			// Now build a merged CScript:
			int nSigsHave = 0;
			Script result = new Script(OpcodeType.OP_0); // pop-one-too-many workaround
			foreach(var pubkey in multiSigParams.PubKeys)
			{
				if(sigs.ContainsKey(pubkey))
				{
					result += Op.GetPushOp(sigs[pubkey].ToBytes());
					nSigsHave++;
				}
				if(nSigsHave >= multiSigParams.SignatureCount)
					break;
			}

			// Fill any missing with OP_0:
			for(int i = nSigsHave ; i < multiSigParams.SignatureCount ; i++)
				result += OpcodeType.OP_0;

			return result;
		}
コード例 #52
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		private static Script CombineSignatures(Script scriptPubKey, Transaction transaction, int n, byte[][] sigs1, byte[][] sigs2)
		{
			var template = StandardScripts.GetTemplateFromScriptPubKey(scriptPubKey);
			if(template == null || template is TxNullDataTemplate)
				return PushAll(Max(sigs1, sigs2));

			if(template is PayToPubkeyTemplate || template is PayToPubkeyHashTemplate)
				if(sigs1.Length == 0 || sigs1[0].Length == 0)
					return PushAll(sigs2);
				else
					return PushAll(sigs1);

			if(template is PayToScriptHashTemplate)
			{
				if(sigs1.Length == 0 || sigs1[sigs1.Length - 1].Length == 0)
					return PushAll(sigs2);

				if(sigs2.Length == 0 || sigs2[sigs2.Length - 1].Length == 0)
					return PushAll(sigs1);

				var redeemBytes = sigs1[sigs1.Length - 1];
				var redeem = new Script(redeemBytes);
				sigs1 = sigs1.Take(sigs1.Length - 1).ToArray();
				sigs2 = sigs2.Take(sigs2.Length - 1).ToArray();
				Script result = CombineSignatures(redeem, transaction, n, sigs1, sigs2);
				result += Op.GetPushOp(redeemBytes);
				return result;
			}

			if(template is PayToMultiSigTemplate)
			{
				return CombineMultisig(scriptPubKey, transaction, n, sigs1, sigs2);
			}

			throw new NotSupportedException("An impossible thing happen !");
		}
コード例 #53
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static Script CombineSignatures(Script scriptPubKey, Transaction transaction, int n, Script scriptSig1, Script scriptSig2)
		{
			if(scriptPubKey == null)
				scriptPubKey = new Script();
			var context = new ScriptEvaluationContext();
			context.ScriptVerify = ScriptVerify.StrictEnc;
			context.EvalScript(scriptSig1, transaction, n);

			var stack1 = context.Stack.AsInternalArray();
			context = new ScriptEvaluationContext();
			context.ScriptVerify = ScriptVerify.StrictEnc;
			context.EvalScript(scriptSig2, transaction, n);

			var stack2 = context.Stack.AsInternalArray();

			return CombineSignatures(scriptPubKey, transaction, n, stack1, stack2);
		}
コード例 #54
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScriptConsensus(Script scriptPubKey, Transaction tx, uint nIn, ScriptVerify flags)
		{
			var scriptPubKeyBytes = scriptPubKey.ToBytes();
			var txToBytes = tx.ToBytes();

			var err = BitcoinConsensusError.ERR_OK;
			var valid = VerifyScriptConsensus(scriptPubKeyBytes, (uint)scriptPubKeyBytes.Length, txToBytes, (uint)txToBytes.Length, nIn, flags, ref err);
			return valid == 1;
		}
コード例 #55
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined)
		{
			ScriptError unused;
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, scriptVerify, sigHash, out unused);
		}
コード例 #56
0
ファイル: StandardScripts.cs プロジェクト: xcrash/NBitcoin
		public static bool AreOutputsStandard(Transaction tx)
		{
			return tx.Outputs.All(vout => IsStandardScriptPubKey(vout.ScriptPubKey));
		}
コード例 #57
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		public static bool VerifyScript(Script scriptPubKey, Transaction tx, int i, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error)
		{
			var scriptSig = tx.Inputs[i].ScriptSig;
			return VerifyScript(scriptSig, scriptPubKey, tx, i, scriptVerify, sigHash, out error);
		}
コード例 #58
0
ファイル: Script.cs プロジェクト: woutersmit/NBitcoin
		//https://en.bitcoin.it/wiki/OP_CHECKSIG
		public uint256 SignatureHash(Transaction txTo, int nIn, SigHash nHashType)
		{
			if(nIn >= txTo.Inputs.Count)
			{
				Utils.log("ERROR: SignatureHash() : nIn=" + nIn + " out of range\n");
				return uint256.One;
			}

			// Check for invalid use of SIGHASH_SINGLE
			if(nHashType == SigHash.Single)
			{
				if(nIn >= txTo.Outputs.Count)
				{
					Utils.log("ERROR: SignatureHash() : nOut=" + nIn + " out of range\n");
					return uint256.One;
				}
			}

			var scriptCopy = new Script(_Script);
			scriptCopy.FindAndDelete(OpcodeType.OP_CODESEPARATOR);

			var txCopy = new Transaction(txTo.ToBytes());

			//Set all TxIn script to empty string
			foreach(var txin in txCopy.Inputs)
			{
				txin.ScriptSig = new Script();
			}
			//Copy subscript into the txin script you are checking
			txCopy.Inputs[nIn].ScriptSig = scriptCopy;

			var hashType = nHashType & (SigHash)31;
			if(hashType == SigHash.None)
			{
				//The output of txCopy is set to a vector of zero size.
				txCopy.Outputs.Clear();

				//All other inputs aside from the current input in txCopy have their nSequence index set to zero
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}
			else if(hashType == SigHash.Single)
			{
				//The output of txCopy is resized to the size of the current input index+1.
				txCopy.Outputs.RemoveRange(nIn + 1, txCopy.Outputs.Count - (nIn + 1));
				//All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
				for(var i = 0 ; i < txCopy.Outputs.Count ; i++)
				{
					if(i == nIn)
						continue;
					txCopy.Outputs[i] = new TxOut();
				}
				//All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
				foreach(var input in txCopy.Inputs.Where((x, i) => i != nIn))
					input.Sequence = 0;
			}


			if((nHashType & SigHash.AnyoneCanPay) != 0)
			{
				//The txCopy input vector is resized to a length of one.
				var script = txCopy.Inputs[nIn];
				txCopy.Inputs.Clear();
				txCopy.Inputs.Add(script);
				//The subScript (lead in by its length as a var-integer encoded!) is set as the first and only member of this vector.
				txCopy.Inputs[0].ScriptSig = scriptCopy;
			}


			//Serialize TxCopy, append 4 byte hashtypecode
			var ms = new MemoryStream();
			var bitcoinStream = new BitcoinStream(ms, true);
			txCopy.ReadWrite(bitcoinStream);
			bitcoinStream.ReadWrite((uint)nHashType);

			var hashed = ms.ToArray();
			return Hashes.Hash256(hashed);
		}
コード例 #59
-2
        public void CanSignTransactionStandardMode()
        {
            var ledger = GetLedger();

            var walletPubKey = ledger.GetWalletPubKey(new KeyPath("1'/0"));
            var address = (BitcoinAddress)walletPubKey.Address;

            Transaction funding = new Transaction();
            funding.AddInput(Network.Main.GetGenesis().Transactions[0].Inputs[0]);
            funding.Outputs.Add(new TxOut(Money.Coins(1.1m), address));
            funding.Outputs.Add(new TxOut(Money.Coins(1.0m), address));
            funding.Outputs.Add(new TxOut(Money.Coins(1.2m), address));

            var coins = funding.Outputs.AsCoins();

            var spending = new Transaction();
            spending.LockTime = 1;
            spending.Inputs.AddRange(coins.Select(o => new TxIn(o.Outpoint, o.ScriptPubKey)));
            spending.Outputs.Add(new TxOut(Money.Coins(0.5m), BitcoinAddress.Create("15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe")));
            spending.Outputs.Add(new TxOut(Money.Coins(0.8m), address));
            spending.Outputs.Add(new TxOut(Money.Zero, TxNullDataTemplate.Instance.GenerateScriptPubKey(new byte[] { 1, 2 })));

            var signed = ledger.SignTransaction(
              new KeyPath("1'/0"),
              new Coin[]
            {
                new Coin(funding, 0),
                new Coin(funding, 1),
                new Coin(funding, 2),
            }, new Transaction[]
            {
                funding
            }, spending);
        }
コード例 #60
-9
        public static void Pay(BitcoinSecret secret, BitcoinAddress toAddress, Money amount, Transaction fundingTransaction)
        {
            var fee = Money.Coins(0.0001m);

            Transaction payment = new Transaction();
            payment.Inputs.Add(new TxIn()
                {
                    PrevOut = new OutPoint(fundingTransaction.GetHash(), 1)
                });

            payment.Outputs.Add(new TxOut()
                {
                    Value = amount,
                    ScriptPubKey = toAddress.ScriptPubKey
                });

            var output = fundingTransaction.Outputs[0];
            var change = output.Value - amount - fee;
            if (change < 0)
            {
                Console.WriteLine("There is not enough BTC in the funding transaction ({0}) to make this payment ({1})", output.Value, amount);
                Console.WriteLine("No payment being sent");
                return;
            }

            payment.Outputs.Add(new TxOut()
                {
                    Value = output.Value - amount - fee,
                    ScriptPubKey = output.ScriptPubKey
                });

            //Feedback !
            var message = "Thanks ! :)";
            var bytes = Encoding.UTF8.GetBytes(message);
            payment.Outputs.Add(new TxOut()
                {
                    Value = Money.Zero,
                    ScriptPubKey = TxNullDataTemplate.Instance.GenerateScriptPubKey(bytes)
                });

            Console.WriteLine(payment);

            payment.Inputs[0].ScriptSig = fundingTransaction.Outputs[1].ScriptPubKey;
            payment.Sign(secret, false);

            using (var node = Node.Connect(Network.Main))
            {
                Console.WriteLine("Doing version handshake");
                node.VersionHandshake();
                Console.WriteLine("Sending message");
                node.SendMessage(new InvPayload(InventoryType.MSG_TX, payment.GetHash()));
                node.SendMessage(new TxPayload(payment));
                Thread.Sleep(500);
            }
        }