public static Transaction CreateFakeTx(NetworkParameters @params, ulong nanocoins, Address to) { var t = new Transaction(@params); var o1 = new TransactionOutput(@params, t, nanocoins, to); t.AddOutput(o1); // Make a previous tx simply to send us sufficient coins. This prev tx is not really valid but it doesn't // matter for our purposes. var prevTx = new Transaction(@params); var prevOut = new TransactionOutput(@params, prevTx, nanocoins, to); prevTx.AddOutput(prevOut); // Connect it. t.AddInput(prevOut); return t; }
public void Transactions() { // This test covers a _bug in which Transaction.getValueSentFromMe was calculating incorrectly. var tx = TestUtils.CreateFakeTx(Params, Utils.ToNanoCoins(1, 0), _myAddress); // Now add another output (ie, change) that goes to some other address. var someOtherGuy = new EcKey().ToAddress(Params); var output = new TransactionOutput(Params, tx, Utils.ToNanoCoins(0, 5), someOtherGuy); tx.AddOutput(output); // Note that tx is no longer valid: it spends more than it imports. However checking transactions balance // correctly isn't possible in SPV mode because value is a property of outputs not inputs. Without all // transactions you can't check they add up. _defaultWallet.Receive(tx, null, BlockChain.NewBlockType.BestChain); // Now the other guy creates a transaction which spends that change. var tx2 = new Transaction(Params); tx2.AddInput(output); tx2.AddOutput(new TransactionOutput(Params, tx2, Utils.ToNanoCoins(0, 5), _myAddress)); // tx2 doesn't send any coins from us, even though the output is in the wallet. Assert.AreEqual(Utils.ToNanoCoins(0, 0), tx2.GetValueSentFromMe(_defaultWallet)); }
/// <summary> /// Creates an UNSIGNED input that links to the given output /// </summary> internal TransactionInput(NetworkParameters networkParameters, Transaction parentTransaction, TransactionOutput output) : base(networkParameters) { var outputIndex = output.Index; Outpoint = new TransactionOutPoint(networkParameters, outputIndex, output.ParentTransaction); ScriptBytes = EmptyArray; _sequence = uint.MaxValue; ParentTransaction = parentTransaction; }
/// <exception cref="ProtocolException"/> protected override void Parse() { _version = ReadUint32(); // First come the inputs. var numInputs = ReadVarInt(); _transactionInputs = new List<TransactionInput>((int) numInputs); for (var i = 0UL; i < numInputs; i++) { var input = new TransactionInput(this.NetworkParameters, this, Bytes, Cursor); _transactionInputs.Add(input); Cursor += input.MessageSize; } // Now the outputs var numOutputs = ReadVarInt(); _transactionOutputs = new List<TransactionOutput>((int) numOutputs); for (var i = 0UL; i < numOutputs; i++) { var output = new TransactionOutput(this.NetworkParameters, this, Bytes, Cursor); _transactionOutputs.Add(output); Cursor += output.MessageSize; } _lockTime = ReadUint32(); }
/// <summary> /// Adds the given output to this transaction. The output must be completely initialized. /// </summary> // TODO: Rename to public void AddOutput(TransactionOutput to) { to.ParentTransaction = this; _transactionOutputs.Add(to); }
/// <summary> /// Adds an input to this transaction that imports value from the given output. Note that this input is NOT /// complete and after every input is added with addInput() and every output is added with addOutput(), /// signInputs() must be called to finalize the transaction and finish the inputs off. Otherwise it won't be /// accepted by the network. /// </summary> // TODO: Rename from public void AddInput(TransactionOutput from) { AddInput(new TransactionInput(this.NetworkParameters, this, from)); }