public static byte[] EncodeTxInput(TxInput txInput) { var stream = new MemoryStream(); EncodeTxInput(stream, txInput); return(stream.ToArray()); }
protected override void ExecuteCommand(string[] args) { var sender = WalletService.GetActiveKey().Data.Address; var receiver = WalletService.GetAddress(receiverArgument.Value); var currency = Currency.FromSymbol(currencyArgument.Value); var amount = Amount.FromWholeDecimal(Convert.ToDecimal(amountArgument.Value)); var input = new TxInput(sender, currency, amount); var output = new TxOutput(receiver, currency, amount); var declarations = new List <TxDeclaration> { }; var inputs = new List <TxInput> { input }; var outputs = new List <TxOutput> { output }; var fees = WalletService.CreateFeesInput(sender); var transaction = new Transaction(declarations, inputs, outputs, TransactionMessage.Empty, DateTime.UtcNow.AddMinutes(1).ToUnixTimestamp(), fees); if (WalletService.SignAndSubmit(transaction)) { Console.WriteLine($"Successfully sent transaction"); } }
public static void EncodeTxInput(BinaryWriter writer, TxInput txInput) { writer.WriteUInt256(txInput.PrevTxOutputKey.TxHash); writer.WriteUInt32(txInput.PrevTxOutputKey.TxOutputIndex); writer.WriteVarBytes(txInput.ScriptSignature.ToArray()); writer.WriteUInt32(txInput.Sequence); }
public static byte[] EncodeTxInput(TxInput txInput) { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { EncodeTxInput(writer, txInput); return(stream.ToArray()); } }
public TxInputWithPrevOutput(ChainedHeader chainedHeader, Transaction transaction, int txIndex, TxInput txInput, int inputIndex, TxOutput prevTxOutput) { this.chainedHeader = chainedHeader; this.transaction = transaction; this.txIndex = txIndex; this.txInput = txInput; this.inputIndex = inputIndex; this.prevTxOutput = prevTxOutput; }
public byte[] TxSignature(ImmutableArray <byte> scriptPubKey, Transaction tx, int inputIndex, byte hashType) { ///TODO Debug.Assert(inputIndex < tx.Inputs.Length); // Blank out other inputs' signatures var empty = ImmutableArray.Create <byte>(); var newInputs = new TxInput[tx.Inputs.Length]; for (var i = 0; i < tx.Inputs.Length; i++) { var oldInput = tx.Inputs[i]; var newInput = oldInput.With(scriptSignature: i == inputIndex ? scriptPubKey : empty); newInputs[i] = newInput; } //// Blank out some of the outputs //if ((hashType & 0x1F) == (int)ScriptHashType.SIGHASH_NONE) //{ // //TODO // Debug.Assert(false); // // Wildcard payee // // Let the others update at will //} //else if ((hashType & 0x1F) == (int)ScriptHashType.SIGHASH_SINGLE) //{ // //TODO // Debug.Assert(false); // // Only lock-in the txout payee at same index as txin // // Let the others update at will //} //// Blank out other inputs completely, not recommended for open transactions //if ((hashType & 0x80) == (int)ScriptHashType.SIGHASH_ANYONECANPAY) //{ // //TODO // Debug.Assert(false); //} // create simplified transaction var newTx = tx.With(Inputs: newInputs.ToImmutableArray()); // return wire-encoded simplified transaction with the 4-byte hashType tacked onto the end var stream = new MemoryStream(); using (var writer = new BinaryWriter(stream)) { writer.WriteBytes(DataCalculator.EncodeTransaction(newTx)); writer.Write4Bytes(hashType); return(stream.ToArray()); } }
public void TestTxInputEquality() { var randomTxInput = RandomData.RandomTxInput(); var sameTxInput = new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: randomTxInput.PreviousTxOutputKey.TxHash, txOutputIndex: randomTxInput.PreviousTxOutputKey.TxOutputIndex ), scriptSignature: ImmutableArray.Create(randomTxInput.ScriptSignature.ToArray()), sequence: randomTxInput.Sequence ); var differentTxInputPreviousTxOutputKey = new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: ~randomTxInput.PreviousTxOutputKey.TxHash, txOutputIndex: randomTxInput.PreviousTxOutputKey.TxOutputIndex ), scriptSignature: randomTxInput.ScriptSignature, sequence: randomTxInput.Sequence ); var differentTxInputScriptSignature = new TxInput ( previousTxOutputKey: randomTxInput.PreviousTxOutputKey, scriptSignature: randomTxInput.ScriptSignature.Add(0), sequence: randomTxInput.Sequence ); var differentTxInputSequence = new TxInput ( previousTxOutputKey: randomTxInput.PreviousTxOutputKey, scriptSignature: randomTxInput.ScriptSignature, sequence: ~randomTxInput.Sequence ); Assert.IsTrue(randomTxInput.Equals(sameTxInput)); Assert.IsTrue(randomTxInput == sameTxInput); Assert.IsFalse(randomTxInput != sameTxInput); Assert.IsFalse(randomTxInput.Equals(differentTxInputPreviousTxOutputKey)); Assert.IsFalse(randomTxInput == differentTxInputPreviousTxOutputKey); Assert.IsTrue(randomTxInput != differentTxInputPreviousTxOutputKey); Assert.IsFalse(randomTxInput.Equals(differentTxInputScriptSignature)); Assert.IsFalse(randomTxInput == differentTxInputScriptSignature); Assert.IsTrue(randomTxInput != differentTxInputScriptSignature); Assert.IsFalse(randomTxInput.Equals(differentTxInputSequence)); Assert.IsFalse(randomTxInput == differentTxInputSequence); Assert.IsTrue(randomTxInput != differentTxInputSequence); }
public void UnCoinbaseInput(ChainPosition chainPosition, TxInput txInput) { this.Add(() => { foreach (var visitor in this.visitors) { visitor.UnCoinbaseInput(chainPosition, txInput); } }); }
public void UnspendTxOutput(ChainPosition chainPosition, TxInput txInput, TxOutputKey txOutputKey, TxOutput txOutput, UInt256 outputScriptHash) { //this.Add(() => //{ foreach (var visitor in this.visitors) { visitor.UnspendTxOutput(chainPosition, txInput, txOutputKey, txOutput, outputScriptHash); } //}); }
public void CoinbaseInput(ChainPosition chainPosition, TxInput txInput) { //this.Add(() => //{ foreach (var visitor in this.visitors) { visitor.CoinbaseInput(chainPosition, txInput); } //}); }
public static void EncodeTxInput(Stream stream, TxInput txInput) { using (var writer = new BinaryWriter(stream, Encoding.ASCII, leaveOpen: true)) { writer.Write32Bytes(txInput.PreviousTxOutputKey.TxHash); writer.Write4Bytes(txInput.PreviousTxOutputKey.TxOutputIndex); EncodeVarBytes(writer, txInput.ScriptSignature.ToArray()); writer.Write4Bytes(txInput.Sequence); } }
private bool IsExchange(Transaction transaction) { TxInput send = null; // what the machine sends foreach (var input in transaction.Inputs) { if (input.Address.Encoded == Machine.Address.Encoded) { if (input.Currency == Machine.CurrencyOut) { send = input; } else { return(false); // the machine only outputs the specified currency } } } if (send == null) { return(false); } TxOutput receive = null; // what the machine receives foreach (var output in transaction.Outputs) { if (output.Address.Encoded == Machine.Address.Encoded) { if (output.Currency == Machine.CurrencyIn) { receive = output; } } } if (receive == null) { return(false); } // verify it matches try { var maximum = Amount.Multiply(send.Amount, Machine.Rate); return(receive.Amount >= maximum); } catch (OverflowException) { return(false); } }
public void ValidationTransactionScript(Chain newChain, BlockTx tx, TxInput txInput, int txInputIndex, PrevTxOutput prevTxOutput) { if (ValidationTransactionScriptAction == null) { coreRules.ValidationTransactionScript(newChain, tx, txInput, txInputIndex, prevTxOutput); } else { ValidationTransactionScriptAction(newChain, tx, txInput, txInputIndex, prevTxOutput); } }
public void TestDoubleSpend() { // prepare block var fakeHeaders = new FakeHeaders(); var chainedHeader0 = fakeHeaders.GenesisChained(); var chainedHeader1 = fakeHeaders.NextChained(); var chainedHeader2 = fakeHeaders.NextChained(); var chain = Chain.CreateForGenesisBlock(chainedHeader0).ToBuilder(); var emptyCoinbaseTx0 = BlockTx.Create(0, Transaction.Create(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0)); var emptyCoinbaseTx1 = BlockTx.Create(0, Transaction.Create(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0)); // initialize memory utxo builder storage var memoryStorage = new MemoryStorageManager(); var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item; memoryChainStateCursor.BeginTransaction(); // initialize utxo builder var utxoBuilder = new UtxoBuilder(); // prepare an unspent transaction var txHash = new UInt256(100); var unspentTx = new UnspentTx(txHash, chainedHeader1.Height, 0, 0, false, 1, OutputState.Unspent); var txOutputKey = new TxOutputKey(txHash, 0); var txOutput = new TxOutput(0, ImmutableArray <byte> .Empty); // add the unspent transaction memoryChainStateCursor.TryAddUnspentTx(unspentTx); memoryChainStateCursor.TryAddUnspentTxOutput(txOutputKey, txOutput); // create an input to spend the unspent transaction var input = new TxInput(txHash, 0, ImmutableArray.Create <byte>(), 0); var tx = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input), ImmutableArray.Create <TxOutput>(), 0)); // spend the input chain.AddBlock(chainedHeader1); utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx }.ToBufferBlock()).ToEnumerable().ToList(); // verify utxo storage UnspentTx actualUnspentTx; TxOutput actualTxOutput; Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx)); Assert.IsTrue(actualUnspentTx.IsFullySpent); Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutputKey, out actualTxOutput)); Assert.AreEqual(txOutput, actualTxOutput); // attempt to spend the input again, validation exception should be thrown chain.AddBlock(chainedHeader2); AssertMethods.AssertAggregateThrows <ValidationException>(() => utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx }.ToBufferBlock()).ToEnumerable().ToList()); }
protected override void ExecuteCommand(string[] args) { var owner = WalletService.GetActiveKey().Data.Address; var @in = Currency.FromSymbol(currencyInArgument.Value); var @out = Currency.FromSymbol(currencyOutArgument.Value); var rate = Amount.FromWholeDecimal(Decimal.Parse(rateArgument.Value)); var machine = new VendingMachine(owner, @in, @out, rate); // TODO put this in a gobal function var alias = aliasArgument.Value; WalletService.ImportDeclaration(alias, machine); var amount = Amount.FromWholeDecimal(Convert.ToDecimal(amountArgument.Value)); var sender = owner; var receiver = machine.Address; var currency = @out; // TODO put this in a gobal function var input = new TxInput(sender, currency, amount); var output = new TxOutput(receiver, currency, amount); var declarations = new List <TxDeclaration> { machine }; var inputs = new List <TxInput> { input }; var outputs = new List <TxOutput> { output }; var fees = WalletService.CreateFeesInput(sender); var transaction = new Transaction(declarations, inputs, outputs, TransactionMessage.Empty, DateTime.UtcNow.AddMinutes(1).ToUnixTimestamp(), fees); if (WalletService.SignAndSubmit(transaction)) { Console.WriteLine($"Successfully sent transaction"); } // -- }
public void TestDoubleSpend() { // prepare test kernel var kernel = new StandardKernel(new MemoryStorageModule()); // prepare block var fakeHeaders = new FakeHeaders(); var chainedHeader = new ChainedHeader(fakeHeaders.Genesis(), height: 0, totalWork: 0); // prepare an unspent transaction var txHash = new UInt256(100); var unspentTx = new UnspentTx(chainedHeader.Hash, 1, OutputState.Unspent); // mock a parent utxo containing the unspent transaction var unspentTransactions = ImmutableDictionary.Create <UInt256, UnspentTx>().Add(txHash, unspentTx); var mockParentChainStateStorage = new Mock <IChainStateStorage>(); mockParentChainStateStorage.Setup(utxo => utxo.UnspentTransactions()).Returns(unspentTransactions); var parentUtxo = new Utxo(mockParentChainStateStorage.Object); // initialize memory utxo builder storage var memoryChainStateBuilderStorage = new MemoryChainStateBuilderStorage(mockParentChainStateStorage.Object); kernel.Rebind <IChainStateBuilderStorage>().ToConstant(memoryChainStateBuilderStorage); // initialize utxo builder var chainStateBuilder = new ChainStateBuilder(null, parentUtxo, LogManager.CreateNullLogger(), kernel, null, null, null, null, null); // create an input to spend the unspent transaction var input = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create <byte>(), 0); var tx = new Transaction(0, ImmutableArray.Create(input), ImmutableArray.Create <TxOutput>(), 0); // spend the input chainStateBuilder.Spend(0, tx, 0, input, chainedHeader); // verify utxo storage Assert.IsFalse(memoryChainStateBuilderStorage.UnspentTransactionsDictionary.ContainsKey(txHash)); // attempt to spend the input again chainStateBuilder.Spend(0, tx, 0, input, chainedHeader); // validation exception should be thrown }
public void TestDoubleSpend() { // prepare block var fakeHeaders = new FakeHeaders(); var chainedHeader0 = fakeHeaders.GenesisChained(); var chainedHeader1 = fakeHeaders.NextChained(); var chain = new ChainBuilder(); var emptyCoinbaseTx0 = new Transaction(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0); var emptyCoinbaseTx1 = new Transaction(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0); // initialize memory utxo builder storage var memoryStorage = new MemoryStorageManager(); var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item; // initialize utxo builder var utxoBuilder = new UtxoBuilder(memoryChainStateCursor, LogManager.CreateNullLogger()); // prepare an unspent transaction var txHash = new UInt256(100); var unspentTx = new UnspentTx(txHash, chainedHeader0.Height, 0, 1, OutputState.Unspent); // add the unspent transaction memoryChainStateCursor.TryAddUnspentTx(unspentTx); // create an input to spend the unspent transaction var input = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create <byte>(), 0); var tx = new Transaction(0, ImmutableArray.Create(input), ImmutableArray.Create <TxOutput>(), 0); // spend the input chain.AddBlock(chainedHeader0); utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx }).ToList(); // verify utxo storage Assert.IsFalse(memoryChainStateCursor.ContainsUnspentTx(txHash)); // attempt to spend the input again chain.AddBlock(chainedHeader1); utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx }).ToList(); // validation exception should be thrown }
public void ValidationTransactionScript(Chain newChain, BlockTx tx, TxInput txInput, int txInputIndex, PrevTxOutput prevTxOutput) { var chainedHeader = newChain.LastBlock; // BIP16 didn't become active until Apr 1 2012 var nBIP16SwitchTime = DateTimeOffset.FromUnixTimeSeconds(1333238400U); var strictPayToScriptHash = chainedHeader.Time >= nBIP16SwitchTime; var flags = strictPayToScriptHash ? verify_flags_type.verify_flags_p2sh : verify_flags_type.verify_flags_none; // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, // when 75% of the network has upgraded: if (chainedHeader.Version >= 3 && IsSuperMajority(3, newChain, ChainParams.MajorityEnforceBlockUpgrade)) { flags |= verify_flags_type.verify_flags_dersig; } // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 // blocks, when 75% of the network has upgraded: if (chainedHeader.Version >= 4 && IsSuperMajority(4, newChain, ChainParams.MajorityEnforceBlockUpgrade)) { flags |= verify_flags_type.verify_flags_checklocktimeverify; } var result = LibbitcoinConsensus.VerifyScript( tx.TxBytes, prevTxOutput.ScriptPublicKey, txInputIndex, flags); if (!result) { logger.Debug($"Script did not pass in block: {chainedHeader.Hash}, tx: {tx.Index}, {tx.Hash}, input: {txInputIndex}"); throw new ValidationException(chainedHeader.Hash); } }
public void TestSimpleSpend() { // prepare block var fakeHeaders = new FakeHeaders(); var chainedHeader0 = fakeHeaders.GenesisChained(); var chainedHeader1 = fakeHeaders.NextChained(); var chainedHeader2 = fakeHeaders.NextChained(); var chain = new ChainBuilder(); var emptyCoinbaseTx0 = new Transaction(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0); var emptyCoinbaseTx1 = new Transaction(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0); var emptyCoinbaseTx2 = new Transaction(2, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0); // initialize memory utxo builder storage var memoryStorage = new MemoryStorageManager(); var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item; // initialize utxo builder var utxoBuilder = new UtxoBuilder(memoryChainStateCursor, LogManager.CreateNullLogger()); // prepare an unspent transaction var txHash = new UInt256(100); var unspentTx = new UnspentTx(txHash, chainedHeader0.Height, 0, 3, OutputState.Unspent); // prepare unspent output var unspentTransactions = ImmutableDictionary.Create <UInt256, UnspentTx>().Add(txHash, unspentTx); // add the unspent transaction memoryChainStateCursor.TryAddUnspentTx(unspentTx); // create an input to spend the unspent transaction's first output var input0 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create <byte>(), 0); var tx0 = new Transaction(0, ImmutableArray.Create(input0), ImmutableArray.Create <TxOutput>(), 0); // spend the input chain.AddBlock(chainedHeader0); utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx0 }).ToList(); // verify utxo storage UnspentTx actualUnspentTx; Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx)); Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3); Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent); Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Unspent); Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent); // create an input to spend the unspent transaction's second output var input1 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 1), ImmutableArray.Create <byte>(), 0); var tx1 = new Transaction(0, ImmutableArray.Create(input1), ImmutableArray.Create <TxOutput>(), 0); // spend the input chain.AddBlock(chainedHeader1); utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx1 }).ToList(); // verify utxo storage Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx)); Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3); Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent); Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Spent); Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent); // create an input to spend the unspent transaction's third output var input2 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 2), ImmutableArray.Create <byte>(), 0); var tx2 = new Transaction(0, ImmutableArray.Create(input2), ImmutableArray.Create <TxOutput>(), 0); // spend the input chain.AddBlock(chainedHeader2); utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx2, tx2 }).ToList(); // verify utxo storage Assert.IsFalse(memoryChainStateCursor.ContainsUnspentTx(txHash)); }
public void TestSimpleSpend() { // prepare test kernel var kernel = new StandardKernel(new MemoryStorageModule()); // prepare block var fakeHeaders = new FakeHeaders(); var chainedHeader = new ChainedHeader(fakeHeaders.Genesis(), height: 0, totalWork: 0); // prepare an unspent transaction var txHash = new UInt256(100); var unspentTx = new UnspentTx(chainedHeader.Hash, 3, OutputState.Unspent); // prepare unspent output var unspentTransactions = ImmutableDictionary.Create <UInt256, UnspentTx>().Add(txHash, unspentTx); var unspentOutputs = ImmutableDictionary.Create <TxOutputKey, TxOutput>() .Add(new TxOutputKey(txHash, 0), new TxOutput(0, ImmutableArray.Create <byte>())) .Add(new TxOutputKey(txHash, 1), new TxOutput(0, ImmutableArray.Create <byte>())) .Add(new TxOutputKey(txHash, 2), new TxOutput(0, ImmutableArray.Create <byte>())); // mock a parent utxo containing the unspent transaction var mockParentChainStateStorage = new Mock <IChainStateStorage>(); mockParentChainStateStorage.Setup(utxo => utxo.UnspentTransactions()).Returns(unspentTransactions); mockParentChainStateStorage.Setup(utxo => utxo.UnspentOutputs()).Returns(unspentOutputs); var parentUtxo = new Utxo(mockParentChainStateStorage.Object); // initialize memory utxo builder storage var memoryChainStateBuilderStorage = new MemoryChainStateBuilderStorage(mockParentChainStateStorage.Object); kernel.Rebind <IChainStateBuilderStorage>().ToConstant(memoryChainStateBuilderStorage); // initialize utxo builder var chainStateBuilder = new ChainStateBuilder(null, parentUtxo, LogManager.CreateNullLogger(), kernel, null, null, null, null, null); // create an input to spend the unspent transaction's first output var input0 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create <byte>(), 0); var tx0 = new Transaction(0, ImmutableArray.Create(input0), ImmutableArray.Create <TxOutput>(), 0); // spend the input chainStateBuilder.Spend(0, tx0, 0, input0, chainedHeader); // verify utxo storage Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary.ContainsKey(txHash)); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates.Length == 3); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates[0] == OutputState.Spent); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates[1] == OutputState.Unspent); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates[2] == OutputState.Unspent); // create an input to spend the unspent transaction's second output var input1 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 1), ImmutableArray.Create <byte>(), 0); var tx1 = new Transaction(0, ImmutableArray.Create(input1), ImmutableArray.Create <TxOutput>(), 0); // spend the input chainStateBuilder.Spend(1, tx1, 1, input1, chainedHeader); // verify utxo storage Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary.ContainsKey(txHash)); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates.Length == 3); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates[0] == OutputState.Spent); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates[1] == OutputState.Spent); Assert.IsTrue(memoryChainStateBuilderStorage.UnspentTransactionsDictionary[txHash].OutputStates[2] == OutputState.Unspent); // create an input to spend the unspent transaction's third output var input2 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 2), ImmutableArray.Create <byte>(), 0); var tx2 = new Transaction(0, ImmutableArray.Create(input2), ImmutableArray.Create <TxOutput>(), 0); // spend the input chainStateBuilder.Spend(2, tx2, 2, input2, chainedHeader); // verify utxo storage Assert.IsFalse(memoryChainStateBuilderStorage.UnspentTransactionsDictionary.ContainsKey(txHash)); }
private static ImmutableArray <byte> GetScriptFromInputPrevOutput(TxInput input, TxOutput prevOutput) { return(input.ScriptSignature.AddRange(prevOutput.ScriptPublicKey)); }
private static byte[] GetScriptFromInputPrevOutput(TxInput input, TxOutput prevOutput) { return(input.ScriptSignature.Concat(prevOutput.ScriptPublicKey).ToArray()); }
public virtual void UnCoinbaseInput(ChainPosition chainPosition, TxInput txInput) { }
public virtual void UnspendTxOutput(ChainPosition chainPosition, TxInput txInput, TxOutputKey txOutputKey, TxOutput txOutput, UInt256 outputScriptHash) { }
public void SpendTxOutput(ChainPosition chainPosition, ChainedHeader chainedHeader, Transaction tx, TxInput txInput, TxOutputKey txOutputKey, TxOutput txOutput, UInt256 outputScriptHash) { //this.Add(() => //{ foreach (var visitor in this.visitors) { visitor.SpendTxOutput(chainPosition, chainedHeader, tx, txInput, txOutputKey, txOutput, outputScriptHash); } //}); }
public void TestTransactionValidation_Transfer() { using (var context = CreateContext()) { var sender = CreateAccount(); var receiver = CreateAccount(); // transaction cannot have duplicated signature var transaction = Transfer(sender, receiver, Currency.BTC, 10); transaction.Signatures.Add(transaction.Signatures.First()); context.SendTransaction(transaction, ResultCode.CannotReadSignedTransaction); // transaction doesn't have required signature transaction = Transfer(sender, receiver, Currency.BTC, 10); transaction.Signatures.Clear(); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // wrong signature receiver.SignTransaction(transaction, Network); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // transaction have no inputs but have an output transaction = Transfer(sender, receiver, Currency.BTC, 10); transaction.Transaction.Inputs.Clear(); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // transaction have no outputs but have an input transaction = Transfer(sender, receiver, Currency.BTC, 10); transaction.Transaction.Outputs.Clear(); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // transaction have no inputs and outputs transaction = Transfer(sender, receiver, Currency.BTC, 10); transaction.Transaction.Inputs.Clear(); transaction.Transaction.Outputs.Clear(); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // amount in output more than amount in input transaction = Transfer(sender, receiver, Currency.BTC, 10); var output = transaction.Transaction.Outputs.First(); var modified = new TxOutput(output.Address, output.Currency, Amount.FromWholeDecimal(99999)); transaction.Transaction.Outputs.Clear(); transaction.Transaction.Outputs.Add(modified); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // amount in input is negative transaction = Transfer(sender, receiver, Currency.BTC, 10); var input = transaction.Transaction.Inputs.First(); var modifiedInput = new TxInput(input.Address, input.Currency, Amount.FromWholeDecimal(-10)); transaction.Transaction.Inputs.Clear(); transaction.Transaction.Inputs.Add(modifiedInput); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); // fees are negative transaction = Transfer(sender, receiver, Currency.BTC, 10); var tx = transaction.Transaction; transaction = new SignedTransaction(new Transaction(tx.Declarations, tx.Inputs, tx.Outputs, tx.Message, tx.Expire, new TxInput(sender.Address, Currency.BTC, -1)), transaction.Signatures); context.SendTransaction(transaction, ResultCode.TransactionValidationFailed); } // context.SendTransaction(signedInvalid, ResultCode.CannotReadSignedTransaction); }