示例#1
0
        }; //TODO


        public static bool Execute(out Types.Transaction transaction, ContractArgs contractArgs, bool isWitness)
        {
            try
            {
                var fileName     = HttpServerUtility.UrlTokenEncode(contractArgs.ContractHash);
                var contractCode = File.ReadAllText(Path.Combine(_OutputPath, Path.ChangeExtension(fileName, ".fs")));
                var func         = ContractExamples.Execution.compileQuotedContract(contractCode);

                var result = func.Invoke(new Tuple <byte[], byte[], FSharpFunc <Types.Outpoint, FSharpOption <Types.Output> > >(
                                             contractArgs.Message,
                                             contractArgs.ContractHash,
                                             FSharpFunc <Types.Outpoint, FSharpOption <Types.Output> > .FromConverter(t => contractArgs.tryFindUTXOFunc(t))));

                var txSkeleton = result as Tuple <FSharpList <Types.Outpoint>, FSharpList <Types.Output>, byte[]>;

                transaction = txSkeleton == null || txSkeleton.Item2.Count() == 0 ? null :
                              new Types.Transaction(
                    Tests.tx.version,
                    txSkeleton.Item1,
                    ListModule.OfSeq <byte[]>(isWitness ? new byte[][] { contractArgs.Message } : new byte[][] { }),
                    txSkeleton.Item2,
                    FSharpOption <Types.ExtendedContract> .None                           //TODO: get from txSkeleton.Item3
                    );

                return(true);
            }
            catch (Exception e)
            {
                BlockChainTrace.Error("Error executing contract", e);
            }

            transaction = null;

            return(false);
        }
示例#2
0
        public IsTxOrphanResult IsOrphanTx(TransactionContext dbTx, Types.Transaction tx, bool isBlock, out TransactionValidation.PointedTransaction ptx)
        {
            var outputs = new List <Types.Output>();

            ptx = null;

            foreach (Types.Outpoint input in tx.inputs)
            {
                bool valid;
                var  output = GetUTXO(input, dbTx, isBlock, out valid);

                if (!valid)
                {
                    return(IsTxOrphanResult.Invalid);
                }
                if (output != null)
                {
                    outputs.Add(output);
                }
                else
                {
                    return(IsTxOrphanResult.Orphan);
                }
            }

            ptx = TransactionValidation.toPointedTransaction(
                tx,
                ListModule.OfSeq(outputs)
                );

            return(IsTxOrphanResult.NotOrphan);
        }
示例#3
0
        public static Types.Block AddTx(this Types.Block bk, Types.Transaction tx)
        {
            //var nonce = new byte[10];
            //new Random().NextBytes(nonce);
            var nonce = new byte[] { };

            var header = new Types.BlockHeader(
                0,
                new byte[] { },
                bk.header.blockNumber + 1,
                new byte[] { },
                new byte[] { },
                new byte[] { },
                ListModule.OfSeq <byte[]>(new List <byte[]>()),
                DateTime.Now.ToUniversalTime().Ticks,
                0,
                nonce
                );

            var txs = bk.transactions.ToList();

            txs.Add(tx);

            return(new Types.Block(bk.header, ListModule.OfSeq <Types.Transaction>(txs)));
        }
示例#4
0
        public bool IsDoubleSpend(TransactionContext dbTx, Types.Transaction tx, bool isBlock)
        {
            foreach (var input in tx.inputs)
            {
                if (!isBlock)
                {
                    foreach (var item in memPool.TxPool)
                    {
                        foreach (var pInput in item.Value.pInputs)
                        {
                            if (input.Equals(pInput.Item1))
                            {
                                return(true);
                            }
                        }
                    }
                }

                if (BlockStore.TxStore.ContainsKey(dbTx, input.txHash) && BlockStore.TxStore.Get(dbTx, input.txHash).Value.InMainChain&& !UTXOStore.ContainsKey(dbTx, input.txHash, input.index))
                {
                    return(true);
                }
            }
            return(false);
        }
 //demo
 private byte[] GetHash(Types.Transaction transaction)
 {
     //	if (transaction.Transaction != null)
     return(Merkle.transactionHasher.Invoke(transaction));
     //	else
     //		return Merkle.blockHasher.Invoke(transaction.Block);
 }
        public void ShouldAddGenesisWithTx()
        {
            _Key = Key.Create();

            _GenesisTx    = Utils.GetTx().AddOutput(_Key.Address, Consensus.Tests.zhash, 100).Tag("genesis tx");
            _GenesisBlock = _GenesisBlock.AddTx(_GenesisTx);
            Assert.That(HandleBlock(_GenesisBlock), Is.EqualTo(BlockVerificationHelper.BkResultEnum.Accepted));
        }
 public static Types.Transaction AddInput(this Types.Transaction tx, Types.Outpoint outpoint)
 {
     return(new Types.Transaction(tx.version,
                                  FSharpList <Types.Outpoint> .Cons(outpoint, tx.inputs),
                                  tx.witnesses,
                                  tx.outputs,
                                  tx.contract));
 }
 public static Types.Transaction SetContract(this Types.Transaction tx, Types.ExtendedContract extendedContract)
 {
     return(new Types.Transaction(tx.version,
                                  tx.inputs,
                                  tx.witnesses,
                                  tx.outputs,
                                  new Microsoft.FSharp.Core.FSharpOption <Types.ExtendedContract>(extendedContract)));
 }
示例#9
0
 public TxDelta(TxStateEnum txState, byte[] txHash, Types.Transaction transaction, AssetDeltas assetDeltas, DateTime time)
 {
     TxState     = txState;
     TxHash      = txHash;
     Transaction = transaction;
     AssetDeltas = assetDeltas;
     Time        = time;
 }
示例#10
0
 protected void RegisterTxEvent(Types.Transaction tx, TxStateEnum txState)
 {
     _TxStateEvents[Merkle.transactionHasher.Invoke(tx)] =
         new Tuple <ManualResetEvent, TxStateEnum>(
             new ManualResetEvent(false),
             txState
             );
 }
示例#11
0
        // remove
        bool IsTransactionValid(Types.Transaction tx, byte[] txHash, out TransactionValidation.PointedTransaction ptx)
        {
            if (_BlockChain.BlockStore.TxStore.ContainsKey(_DbTx, txHash) && _BlockChain.BlockStore.TxStore.Get(_DbTx, txHash).Value.InMainChain)
            {
                BlockChainTrace.Information("Tx already in store", txHash);
                ptx = null;
                return(false);
            }

            switch (_BlockChain.IsOrphanTx(_DbTx, tx, true, out ptx))
            {
            case BlockChain.IsTxOrphanResult.Orphan:
                BlockChainTrace.Information("tx invalid - orphan", tx);
                return(false);

            case BlockChain.IsTxOrphanResult.Invalid:
                BlockChainTrace.Information("tx invalid - reference(s)", tx);
                return(false);
            }

            if (_BlockChain.IsDoubleSpend(_DbTx, tx, true))
            {
                return(false);
            }

            //TODO: coinbase validation + check that witness has blocknumber

            if (!BlockChain.IsValidUserGeneratedTx(_DbTx, ptx))
            {
                BlockChainTrace.Information("tx invalid - structural", ptx);
                return(false);
            }

            byte[] contractHash;
            switch (BlockChain.IsContractGeneratedTx(ptx, out contractHash))
            {
            case BlockChain.IsContractGeneratedTxResult.ContractGenerated:
                if (!_BlockChain.ActiveContractSet.IsActive(_DbTx, contractHash))
                {
                    BlockChainTrace.Information("tx invalid - contract not active", tx);
                    return(false);
                }
                var contractFunction = _BlockChain.ActiveContractSet.GetContractFunction(_DbTx, contractHash);

                if (!BlockChain.IsValidAutoTx(ptx, UtxoLookup, contractHash, contractFunction))
                {
                    BlockChainTrace.Information("auto-tx invalid", ptx);
                    return(false);
                }
                break;

            case BlockChain.IsContractGeneratedTxResult.Invalid:
                BlockChainTrace.Information("tx invalid - input locks", tx);
                return(false);
            }

            return(true);
        }
        internal void OnTransactionBroadcasted(Types.Transaction tx)
        {
            var evt = TransactionBroadcasted;

            if (evt != null)
            {
                evt(tx);
            }
        }
        internal void OnTransactionRejected(Types.Transaction tx, RejectPayload reject)
        {
            var evt = TransactionRejected;

            if (evt != null)
            {
                evt(tx, reject);
            }
        }
示例#14
0
        bool IsCoinbaseTxValid(Types.Transaction tx)
        {
            //TODO: check maturity

            return(tx.witnesses.Count() > 0 && tx.witnesses[0].Length > 0 &&
                   BitConverter.ToUInt32(tx.witnesses[0], 0) == _Bk.header.blockNumber);

            return(true);
        }
示例#15
0
 public void Put(
     TransactionContext transactionContext,
     byte[] txHash,
     Types.Transaction tx,
     bool inMainChain)
 {
     Put(transactionContext, txHash, new Transaction {
         Tx = tx, InMainChain = inMainChain
     });
 }
示例#16
0
        //void _Builder_NewTransaction(Types.Transaction obj)
        //{
        //	_Transactions.AddOrReplace(obj.GetHash(), obj);
        //	BroadcastCore(obj);
        //}

        void _BlockChain_OnAddedToMempool(Types.Transaction transaction)
        {
            foreach (var other in Nodes)
            {
                if (other != AttachedNode && other.State == NodeState.HandShaked)
                {
                    other.SendMessageAsync(new InvPayload(transaction));
                }
            }
        }
示例#17
0
        protected TxStateEnum?TxState(Types.Transaction tx)
        {
            var key = Merkle.transactionHasher.Invoke(tx);

            if (_TxStates.ContainsKey(key))
            {
                return(_TxStates[key]);
            }
            return(null);
        }
        internal void OnBroadcastTransaction(Types.Transaction transaction)
        {
            var nodes = Nodes
                        .Select(n => n.Key.Behaviors.Find <BroadcastHubBehavior>())
                        .Where(n => n != null)
                        .ToArray();

            foreach (var node in nodes)
            {
                node.BroadcastTransactionCore(transaction);
            }
        }
示例#19
0
        public bool ContainsInputs(Types.Transaction tx)
        {
            foreach (var outpoint in tx.inputs)
            {
                if (ContainsOutpoint(outpoint))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#20
0
        // Note: when contract uses blokchain state as context, need to pass it in.
        public static bool ExecuteContract(
            byte[] contractHash,
            ContractFunction contractFunction,
            byte[] message,
            out Types.Transaction transaction,
            UtxoLookup UtxoLookup,
            bool isWitness)
        {
            var contractFunctionInput = new ContractFunctionInput(
                message,
                contractHash,
                UtxoLookup
                );
            TransactionSkeleton transactionSkeleton = null;

            transaction = null;

            try
            {
                var serializer = new ContractExamples.FStarCompatibility.DataSerializer(Consensus.Serialization.context);
                Consensus.Serialization.context.Serializers.RegisterOverride(serializer);

                var result = contractFunction.Invoke(contractFunctionInput);

                if (result.IsError)
                {
                    BlockChainTrace.Information("Contract resulted in error: " + result.ErrorValue);
                    return(false);
                }

                transactionSkeleton = result.ResultValue;
            }
            catch (Exception e)
            {
                BlockChainTrace.Error("Error executing contract", e);
                return(false);
            }

            if (transactionSkeleton == null)
            {
                return(false);
            }

            transaction = new Types.Transaction(
                Tests.tx.version,
                transactionSkeleton.Item1,
                ListModule.OfSeq(isWitness ? new byte[][] { message } : new byte[][] { }),
                transactionSkeleton.Item2,
                FSharpOption <Types.ExtendedContract> .None //TODO: get from txSkeleton.Item3
                );

            return(true);
        }
示例#21
0
 public bool Parse(byte[] rawTxBytes, out Types.Transaction tx)
 {
     try
     {
         tx = Serialization.context.GetSerializer <Types.Transaction>().UnpackSingleObject(rawTxBytes);
         return(true);
     }
     catch
     {
         tx = null;
         return(false);
     }
 }
 //demo
 private byte[] GetHash(Types.Transaction transaction)
 {
     try
     {
         //	if (transaction.Transaction != null)
         return(Merkle.transactionHasher.Invoke(transaction));
         //	else
         //		return Merkle.blockHasher.Invoke(transaction.Block);
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
         return(null);
     }
 }
示例#23
0
        /// <summary>
        /// Transmits a tx on the network.
        /// </summary>
        public Task <BlockChain.BlockChain.TxResultEnum> Transmit(Types.Transaction tx)
        {
            //TODO: refactor
            //TODO: if tx is known (and validated), just send it.
            return(new HandleTransactionAction {
                Tx = tx
            }.Publish().ContinueWith(t => {
                if (t.Result == BlockChain.BlockChain.TxResultEnum.Accepted && _BroadcastHubBehavior != null)
                {
                    _BroadcastHubBehavior.BroadcastHub.BroadcastTransactionAsync(tx);
                }

                return t.Result;
            }));
        }
        public new void OneTimeSetUp()
        {
            base.OneTimeSetUp();

            block1_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block1_tx");
            block2_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block2_tx");
            block3_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block3_tx");
            block4_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block4_tx");
            block5_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block5_tx");

            block1 = _GenesisBlock.Child().AddTx(block1_tx).Tag("block1");
            block2 = _GenesisBlock.Child().AddTx(block2_tx).Tag("block2");
            block3 = block2.Child().AddTx(block3_tx).Tag("block3");
            block4 = block1.Child().AddTx(block4_tx).Tag("block4");
            block5 = block4.Child().AddTx(block5_tx).Tag("block5");
        }
示例#25
0
        bool AssembleAutoTx(byte[] contractHash, byte[] message, out Types.Transaction transaction, bool isWitness)
        {
            using (TransactionContext dbTx = _DBContext.GetTransactionContext())
            {
                var utxoLookup       = UtxoLookupFactory(dbTx, false);
                var contractFunction = ActiveContractSet.GetContractFunction(dbTx, contractHash);

                if (contractFunction != null)
                {
                    return(ExecuteContract(contractHash, contractFunction, message, out transaction, utxoLookup, isWitness));
                }

                transaction = null;
                return(false);
            }
        }
        internal void BroadcastTransactionCore(Types.Transaction transaction)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }
            var tx = new TransactionBroadcast();

            tx.Transaction = transaction;
            tx.State       = BroadcastState.NotSent;
            var hash = GetHash(transaction);

            if (_HashToTransaction.TryAdd(hash, tx))
            {
                Announce(tx, hash);
            }
        }
        bool CheckUtxsSetContains(Types.Transaction tx)
        {
            var txHash = Merkle.transactionHasher.Invoke(tx);
            var utxos  = new GetUTXOSetAction().Publish().Result;

            if (utxos.Item2.ContainsKey(txHash))
            {
                foreach (var output in tx.outputs)
                {
                    if (utxos.Item1[txHash].Contains(output))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#28
0
        internal void Put(TransactionContext dbTx, byte[] txHash, Types.Transaction tx, AssetDeltas assetDeltas, TxStateEnum txState)
        {
            var txHashRecord = dbTx.Transaction.Select <byte[], ulong>(TX_HASHES_TO_IDENTITY, txHash);

            var identity = txHashRecord.Exists ? txHashRecord.Value : dbTx.Transaction.Count(TX_HASHES_TO_IDENTITY);

            if (!txHashRecord.Exists)
            {
                dbTx.Transaction.Insert <byte[], ulong>(TX_HASHES_TO_IDENTITY, txHash, identity);
            }

            Put(dbTx, identity, new TxData()
            {
                DateTime    = DateTime.Now.ToUniversalTime(),
                TxState     = txState,
                Tx          = tx,
                AssetDeltas = assetDeltas,
                TxHash      = txHash,
            });
        }
示例#29
0
        void CalculateCoinbase()
        {
            var reward = 1000u;

            var outputs = new List <Types.Output>
            {
                new Types.Output(Types.OutputLock.NewPKLock(_Address.Bytes), new Types.Spend(Tests.zhash, reward))
            };

            var witness = new List <byte[]>
            {
                BitConverter.GetBytes(_BlockChain.Tip.Value.header.blockNumber + 1)
            };

            _Coinbase = new Types.Transaction(
                0,
                ListModule.Empty <Types.Outpoint>(),
                ListModule.OfSeq(witness),
                ListModule.OfSeq(outputs),
                FSharpOption <Types.ExtendedContract> .None
                );
        }
示例#30
0
        public void Render()
        {
            if (Value != null)
            {
                return;
            }

            var outputs = new List <Types.Output>();

            for (var i = 0; i < Outputs; i++)
            {
                outputs.Add(Util.GetOutput());
            }

            var inputs = new List <Types.Outpoint>();

            foreach (Point point in Inputs)
            {
                point.RefTransaction.Render();
                inputs.Add(new Types.Outpoint(point.RefTransaction.Value.Key, point.Index));
            }

            var hashes = new List <byte[]>();

            //hack Concensus into giving a different hash per each tx created
            var version = (uint)1;             //_Random.Next(1000);

            Types.Transaction transaction = new Types.Transaction(version,
                                                                  ListModule.OfSeq(inputs),
                                                                  ListModule.OfSeq(hashes),
                                                                  ListModule.OfSeq(outputs),
                                                                  null);

            byte[] key = Merkle.transactionHasher.Invoke(transaction);
            Value = new Keyed <Types.Transaction>(key, transaction);

            TestTrace.Transaction(Tag, key);
        }