Ejemplo n.º 1
0
        public static byte[] EncodeTxInput(TxInput txInput)
        {
            var stream = new MemoryStream();

            EncodeTxInput(stream, txInput);
            return(stream.ToArray());
        }
Ejemplo n.º 2
0
        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");
            }
        }
Ejemplo n.º 3
0
 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);
 }
Ejemplo n.º 4
0
 public static byte[] EncodeTxInput(TxInput txInput)
 {
     using (var stream = new MemoryStream())
         using (var writer = new BinaryWriter(stream))
         {
             EncodeTxInput(writer, txInput);
             return(stream.ToArray());
         }
 }
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
        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());
            }
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
 public void UnCoinbaseInput(ChainPosition chainPosition, TxInput txInput)
 {
     this.Add(() =>
     {
         foreach (var visitor in this.visitors)
         {
             visitor.UnCoinbaseInput(chainPosition, txInput);
         }
     });
 }
Ejemplo n.º 10
0
 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);
     }
     //});
 }
Ejemplo n.º 11
0
 public void CoinbaseInput(ChainPosition chainPosition, TxInput txInput)
 {
     //this.Add(() =>
     //{
     foreach (var visitor in this.visitors)
     {
         visitor.CoinbaseInput(chainPosition, txInput);
     }
     //});
 }
Ejemplo n.º 12
0
 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);
            }
        }
Ejemplo n.º 14
0
 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);
     }
 }
Ejemplo n.º 15
0
        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");
            }
            // --
        }
Ejemplo n.º 17
0
        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
        }
Ejemplo n.º 18
0
        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
        }
Ejemplo n.º 19
0
        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);
            }
        }
Ejemplo n.º 20
0
        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));
        }
Ejemplo n.º 21
0
        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));
        }
Ejemplo n.º 22
0
 private static ImmutableArray <byte> GetScriptFromInputPrevOutput(TxInput input, TxOutput prevOutput)
 {
     return(input.ScriptSignature.AddRange(prevOutput.ScriptPublicKey));
 }
Ejemplo n.º 23
0
 private static byte[] GetScriptFromInputPrevOutput(TxInput input, TxOutput prevOutput)
 {
     return(input.ScriptSignature.Concat(prevOutput.ScriptPublicKey).ToArray());
 }
Ejemplo n.º 24
0
 public virtual void UnCoinbaseInput(ChainPosition chainPosition, TxInput txInput)
 {
 }
Ejemplo n.º 25
0
 public virtual void UnspendTxOutput(ChainPosition chainPosition, TxInput txInput, TxOutputKey txOutputKey, TxOutput txOutput, UInt256 outputScriptHash)
 {
 }
Ejemplo n.º 26
0
 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);
     }
     //});
 }
Ejemplo n.º 27
0
        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);
        }