コード例 #1
0
ファイル: Transaction.cs プロジェクト: n1rvana/NBitcoin
        /// <summary>
        /// Sign a specific coin with the given secret
        /// </summary>
        /// <param name="key">Private keys</param>
        /// <param name="coins">Coins to sign</param>
        public void Sign(Key[] keys, params ICoin[] coins)
        {
            TransactionBuilder builder = new TransactionBuilder();

            builder.AddKeys(keys);
            builder.AddCoins(coins);
            builder.SignTransactionInPlace(this);
        }
コード例 #2
0
        /// <summary>
        /// Sign the transaction with a private key
        /// <para>ScriptSigs should be filled with either previous scriptPubKeys or redeem script (for P2SH)</para>
        /// <para>For more complex scenario, use TransactionBuilder</para>
        /// </summary>
        /// <param name="secret"></param>
        public void Sign(Key key, bool assumeP2SH)
        {
            TransactionBuilder builder = new TransactionBuilder();

            builder.AddKeys(key);
            for (int i = 0; i < Inputs.Count; i++)
            {
                var txin = Inputs[i];
                if (Script.IsNullOrEmpty(txin.ScriptSig))
                {
                    throw new InvalidOperationException("ScriptSigs should be filled with either previous scriptPubKeys or redeem script (for P2SH)");
                }
                if (assumeP2SH)
                {
                    var p2shSig = PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(txin.ScriptSig);
                    if (p2shSig == null)
                    {
                        builder.AddCoins(new ScriptCoin(txin.PrevOut, new TxOut()
                        {
                            ScriptPubKey = txin.ScriptSig.PaymentScript,
                        }, txin.ScriptSig));
                    }
                    else
                    {
                        builder.AddCoins(new ScriptCoin(txin.PrevOut, new TxOut()
                        {
                            ScriptPubKey = p2shSig.RedeemScript.PaymentScript
                        }, p2shSig.RedeemScript));
                    }
                }
                else
                {
                    builder.AddCoins(new Coin(txin.PrevOut, new TxOut()
                    {
                        ScriptPubKey = txin.ScriptSig
                    }));
                }
            }
            builder.SignTransactionInPlace(this);
        }
コード例 #3
0
        static void Main(string[] args)
        {
            BitcoinSecret secret = new BitcoinSecret("cTfANynUR2MCPC8uBpfo2yUfAzX5PucDNuXaJ8jXT8CpQDgvfUNr", Network);
            BitcoinAddress address = new BitcoinAddress("n2upyU7axtvHHhAPTMvdaRSkP5Mjufoffx", Network);

            BlockrTransactionRepository blockr = new BlockrTransactionRepository(Network);
            List<Coin> unspentCoins = blockr.GetUnspentAsync(secret.GetAddress().ToString(), true).Result;

            TransactionBuilder builder = new TransactionBuilder();
            builder.AddKeys(secret);
            builder.AddCoins(unspentCoins);
            builder.Send(address, Money.Coins(0.005m));
            builder.SendFees(Money.Coins(0.00001m));
            builder.SetChange(secret.ScriptPubKey);

            Transaction tx = builder.BuildTransaction(true);

            if (builder.Verify(tx))
                SendTransaction(tx);
        }
コード例 #4
0
        public bool TryFinalizeInput(out IList <PSBTError> errors)
        {
            errors = null;
            if (IsFinalized())
            {
                return(true);
            }
            var isSane = this.CheckSanity();

            if (isSane.Count != 0)
            {
                errors = isSane;
                return(false);
            }
            if (witness_utxo == null && non_witness_utxo == null)
            {
                errors = new List <PSBTError>()
                {
                    new PSBTError(Index, "Neither witness_utxo nor non_witness_output is set")
                };
                return(false);
            }
            var coin = this.GetSignableCoin(out var getSignableCoinError) ?? this.GetCoin();             // GetCoin can't be null at this stage.
            TransactionBuilder transactionBuilder = Parent.CreateTransactionBuilder();

            transactionBuilder.AddCoins(coin);
            foreach (var sig in PartialSigs)
            {
                transactionBuilder.AddKnownSignature(sig.Key, sig.Value, coin.Outpoint);
            }
            Transaction signed = null;

            try
            {
                var signedTx = Parent.Settings.IsSmart ? Parent.GetOriginalTransaction() : Transaction.Clone();
                signed = transactionBuilder.SignTransaction(signedTx, SigHash.All);
            }
            catch (Exception ex)
            {
                errors = new List <PSBTError>()
                {
                    new PSBTError(Index, $"Error while finalizing the input \"{getSignableCoinError ?? ex.Message}\"")
                };
                return(false);
            }
            var indexedInput = signed.Inputs.FindIndexedInput(coin.Outpoint);

            if (!indexedInput.VerifyScript(coin, out var error))
            {
                errors = new List <PSBTError>()
                {
                    new PSBTError(Index, $"The finalized input script does not properly validate \"{error}\"")
                };
                return(false);
            }

            FinalScriptSig     = indexedInput.ScriptSig is Script oo && oo != Script.Empty ? oo : null;
            FinalScriptWitness = indexedInput.WitScript is WitScript o && o != WitScript.Empty ? o : null;
            if (transactionBuilder.FindSignableCoin(indexedInput) is ScriptCoin scriptCoin)
            {
                if (scriptCoin.IsP2SH)
                {
                    RedeemScript = scriptCoin.GetP2SHRedeem();
                }
                if (scriptCoin.RedeemType == RedeemType.WitnessV0)
                {
                    WitnessScript = scriptCoin.Redeem;
                }
            }
            ClearForFinalize();
            errors = null;
            return(true);
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: LykkeCity/Prototypes
        static void Main(string[] args)
        {
            var goldGuy = new BitcoinSecret("KyuzoVnpsqW529yzozkzP629wUDBsPmm4QEkh9iKnvw3Dy5JJiNg");
            var silverGuy = new BitcoinSecret("L4KvjpqDtdGEn7Lw6HdDQjbg74MwWRrFZMQTgJozeHAKJw5rQ2Kn");

            var firstPerson = new BitcoinSecret("5Jnw9Td7PaG6PWBrU7ZCfxyVXsHSsNxdZ9sg5dnZstcr12DLVbJ");
            var secondPerson = new BitcoinSecret("5Jn4zJkzS2BWNu7AMRTdSJ6mS7JYfJg27oXKAichaRBbp97ZKks");
            var exchangeEntity = new BitcoinSecret("5KA7FeABKmMKerWmkJzYM9FdoqScZEMVcS9u6wvT3EhgF5ZUWv5");

            var bitcoinProviderEntity = new BitcoinSecret("5Jcz2A17aAt4bcQP5GEn6itt72JsLwrksNRVKqazy7n284b1bKj");

            var issuanceCoinsTransaction = new Transaction()
            {
                Outputs =
                {
                    new TxOut("1.0", goldGuy.PubKey),
                    new TxOut("1.0", silverGuy.PubKey),
                    new TxOut("1.0", firstPerson.PubKey),
                    new TxOut("1.0", secondPerson.PubKey),
                }
            };

            IssuanceCoin[] issuanceCoins = issuanceCoinsTransaction
                        .Outputs
                        .Take(2)
                        .Select((o, i) => new Coin(new OutPoint(issuanceCoinsTransaction.GetHash(), i), o))
                        .Select(c => new IssuanceCoin(c))
                        .ToArray();

            var goldIssuanceCoin = issuanceCoins[0];
            var silverIssuanceCoin = issuanceCoins[1];
            var firstPersonInitialCoin = new Coin(new OutPoint(issuanceCoinsTransaction, 2), issuanceCoinsTransaction.Outputs[2]);
            var secondPersonInitialCoin = new Coin(new OutPoint(issuanceCoinsTransaction, 3), issuanceCoinsTransaction.Outputs[3]);

            var goldId = goldIssuanceCoin.AssetId;
            var silverId = silverIssuanceCoin.AssetId;

            var txRepo = new NoSqlTransactionRepository();
            txRepo.Put(issuanceCoinsTransaction.GetHash(), issuanceCoinsTransaction);

            var ctxRepo = new NoSqlColoredTransactionRepository(txRepo);

            TransactionBuilder txBuilder = new TransactionBuilder();

            // Issuing gold to first person
            // This happens in gold issuer client
            Transaction tx = txBuilder
                .AddKeys(goldGuy.PrivateKey)
                .AddCoins(goldIssuanceCoin)
                .IssueAsset(firstPerson.GetAddress(), new AssetMoney(goldId, 20))
                .SetChange(goldGuy.GetAddress())
                .BuildTransaction(true);

            txRepo.Put(tx.GetHash(), tx);
            var ctx = tx.GetColoredTransaction(ctxRepo);
            var coloredCoins = ColoredCoin.Find(tx, ctx).ToArray();
            ColoredCoin firstPersonGoldCoin = coloredCoins[0];

            // Issuing silver to second person
            // This happens in silver issuer client
            txBuilder = new TransactionBuilder();
            tx = txBuilder
                .AddKeys(silverGuy.PrivateKey)
                .AddCoins(silverIssuanceCoin)
                .IssueAsset(secondPerson.GetAddress(), new AssetMoney(silverId, 30))
                .SetChange(silverGuy.GetAddress())
                .BuildTransaction(true);

            txRepo.Put(tx.GetHash(), tx);
            ctx = tx.GetColoredTransaction(ctxRepo);
            coloredCoins = ColoredCoin.Find(tx, ctx).ToArray();
            ColoredCoin secondPersonSilverCoin = coloredCoins[0];

            // Sending first person gold to exchange
            // This happens in first user client
            var bitcoinProviderCoin = CreateTransactionFeeCoin(bitcoinProviderEntity.PubKey, txRepo);
            txBuilder = new TransactionBuilder();
            tx = txBuilder
                .AddCoins(bitcoinProviderCoin)
                .AddKeys(bitcoinProviderEntity.PrivateKey)
                .AddCoins(firstPersonGoldCoin)
                .AddKeys(firstPerson.PrivateKey)
                .SendAssetToExchange(exchangeEntity.GetAddress(), new AssetMoney(goldId, 5))
                .SetChange(firstPerson.PubKey)
                .BuildTransaction(true);
            txRepo.Put(tx.GetHash(), tx);
            ctx = tx.GetColoredTransaction(ctxRepo);
            coloredCoins = ColoredCoin.Find(tx, ctx).ToArray();
            ColoredCoin firstPersonColoredCoinInExchange = coloredCoins[1];

            // Creating the time-locked transaction which the first user can post to the
            // network to claim his/her coin from exchange (it works if the exchange does not touch the coins
            // This happens in exchange and the transaction is delivered to first user client
            bitcoinProviderCoin = CreateTransactionFeeCoin(bitcoinProviderEntity.PubKey, txRepo);
            txBuilder = new TransactionBuilder();
            tx = txBuilder
                .AddCoins(bitcoinProviderCoin)
                .AddKeys(bitcoinProviderEntity.PrivateKey)
                .AddCoins(firstPersonColoredCoinInExchange)
                .AddKeys(firstPerson.PrivateKey)
                .SendAsset(firstPerson.PubKey, new AssetMoney(firstPersonColoredCoinInExchange.Amount.Id,
                    firstPersonColoredCoinInExchange.Amount.Quantity))
                .SetChange(exchangeEntity.PubKey)
                .SetLockTime(new LockTime(1000000))
                .BuildTransaction(true);
            string reclaimTransactionForFirstUser = tx.ToHex();

            // Create first person exchange request
            // This happens in first person client
            JObject firstPersonRequestToExchange = CreateExchangeRequest("ExactMatch", goldId.ToString(),
                silverId.ToString(), 5, 2);
            var firstRequestSignature = firstPerson.PrivateKey.SignMessage(firstPersonRequestToExchange.ToString(Formatting.None));

            // Sending second person silver to exchange
            // This happens in second person client
            bitcoinProviderCoin = CreateTransactionFeeCoin(bitcoinProviderEntity.PubKey, txRepo);
            txBuilder = new TransactionBuilder();
            tx = txBuilder
                .AddCoins(bitcoinProviderCoin)
                .AddKeys(bitcoinProviderEntity.PrivateKey)
                .AddCoins(secondPersonSilverCoin)
                .AddKeys(secondPerson.PrivateKey)
                .SendAssetToExchange(exchangeEntity.GetAddress(), new AssetMoney(silverId, 12))
                .SetChange(secondPerson.PubKey)
                .BuildTransaction(true);
            txRepo.Put(tx.GetHash(), tx);
            ctx = tx.GetColoredTransaction(ctxRepo);
            coloredCoins = ColoredCoin.Find(tx, ctx).ToArray();
            ColoredCoin secondPersonColoredCoinInExchange = coloredCoins[1];

            // Create second person exchange request
            // This happens in second person client
            JObject secondPersonRequestToExchange = CreateExchangeRequest("ExactMatch", silverId.ToString(),
                goldId.ToString(), 30, 0.5f);
            var secondRequestSignature = secondPerson.PrivateKey.SignMessage(secondPersonRequestToExchange.ToString(Formatting.None));

            // Creating exchange reason
            // This happens in exchange
            var exchangeReason = CreateExchangeMatch(firstPersonRequestToExchange, firstRequestSignature,
                secondPersonRequestToExchange, secondRequestSignature, exchangeEntity.PrivateKey);

            // Performing the exchange operation
            // This happens in exchange
            bitcoinProviderCoin = CreateTransactionFeeCoin(bitcoinProviderEntity.PubKey, txRepo);
            txBuilder = new TransactionBuilder();
            tx = txBuilder
                .AddCoins(bitcoinProviderCoin)
                .AddKeys(bitcoinProviderEntity.PrivateKey)
                .AddCoins(firstPersonColoredCoinInExchange)
                .AddKeys(exchangeEntity.PrivateKey)
                .AddCoins(secondPersonColoredCoinInExchange)
                .AddKeys(exchangeEntity.PrivateKey)
                .PerformExchangeOperation(firstPerson.GetAddress(), new AssetMoney(silverId, 10),
                secondPerson.GetAddress(), new AssetMoney(goldId, 5), exchangeReason.ToString(Formatting.None))
                .SetChange(exchangeEntity.GetAddress())
                .BuildTransaction(true);
            txRepo.Put(tx.GetHash(), tx);
            ctx = tx.GetColoredTransaction(ctxRepo);
            coloredCoins = ColoredCoin.Find(tx, ctx).ToArray();

            txRepo.Put(tx.GetHash(), tx);
        }
コード例 #6
0
        /// <summary>
        /// Records a database anchor.
        /// </summary>
        /// <param name="anchor">The anchor to be recorded.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task RecordAnchor(LedgerAnchor anchor)
        {
            byte[] anchorPayload =
                anchorMarker
                .Concat(BitConverter.GetBytes((ulong)anchor.TransactionCount).Reverse())
                .Concat(anchor.FullStoreHash.ToByteArray())
                .ToArray();

            using (HttpClient client = new HttpClient())
            {
                BitcoinAddress address = this.publishingAddress.ScriptPubKey.GetDestinationAddress(this.network);
                HttpResponseMessage response = await client.GetAsync(new Uri(url, $"addresses/{address.ToString()}/unspents"));

                response.EnsureSuccessStatusCode();

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

                JArray outputs = JArray.Parse(body);

                TransactionBuilder builder = new TransactionBuilder();
                builder.AddKeys(publishingAddress.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), publishingAddress.ScriptPubKey));
                }

                Script opReturn = new Script(OpcodeType.OP_RETURN, Op.GetPushOp(anchorPayload));
                builder.Send(opReturn, 0);
                builder.SendFees(satoshiFees);
                builder.SetChange(this.publishingAddress.ScriptPubKey, ChangeType.All);

                ByteString seriazliedTransaction = new ByteString(builder.BuildTransaction(true).ToBytes());

                await SubmitTransaction(seriazliedTransaction);
            }
        }
コード例 #7
0
ファイル: BitcoinClient.cs プロジェクト: openchain/sidechain
        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());
        }