Пример #1
0
        public bool Verify(Block block)
        {
            var task = _blockRepository.GetBlockHeader(block.PreviousBlockHash);

            task.Wait();

            var prevHeader = task.Result;

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

            if (prevHeader.Index + 1 != block.Index)
            {
                return(false);
            }

            if (prevHeader.Timestamp >= block.Timestamp)
            {
                return(false);
            }

            if (!_witnessOperationsManager.Verify(block.Witness))
            {
                return(false);
            }

            return(true);
        }
        public bool Verify(Transaction transaction)
        {
            if (transaction.Attributes.Any(p =>
                                           p.Usage == TransactionAttributeUsage.ECDH02 || p.Usage == TransactionAttributeUsage.ECDH03))
            {
                return(false);
            }

            for (var i = 1; i < transaction.Inputs.Length; i++)
            {
                for (var j = 0; j < i; j++)
                {
                    if (transaction.Inputs[i].PrevHash == transaction.Inputs[j].PrevHash &&
                        transaction.Inputs[i].PrevIndex == transaction.Inputs[j].PrevIndex)
                    {
                        return(false);
                    }
                }
            }

            if (this._transactionModel.IsDoubleSpend(transaction))
            {
                return(false);
            }

            foreach (var group in transaction.Outputs.GroupBy(p => p.AssetId))
            {
                var asset = this._assetModel.GetAsset(group.Key).Result;

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

                // TODO: Should we check for `asset.Expiration <= _blockchain.Height + 1` ??
                if (asset.AssetType != AssetType.GoverningToken &&
                    asset.AssetType != AssetType.UtilityToken)
                {
                    return(false);
                }

                var tenPoweredToEightMinusAssetPrecision = (long)Math.Pow(10, 8 - asset.Precision);

                if (group.Any(output => output.Value.Value % tenPoweredToEightMinusAssetPrecision != 0))
                {
                    return(false);
                }
            }

            var results = this.GetTransactionResults(transaction)?.ToArray();

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

            var resultsDestroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray();

            if (resultsDestroy.Length > 1)
            {
                return(false);
            }

            if (resultsDestroy.Length == 1 &&
                resultsDestroy[0].AssetId != this._transactionContext.UtilityTokenHash)
            {
                return(false);
            }

            if (this._transactionContext.GetSystemFee(transaction) > Fixed8.Zero &&
                (resultsDestroy.Length == 0 ||
                 resultsDestroy[0].Amount < this._transactionContext.GetSystemFee(transaction)))
            {
                return(false);
            }

            var resultsIssue = results.Where(p => p.Amount < Fixed8.Zero).ToArray();

            if (resultsIssue.Any(p => p.AssetId != this._transactionContext.UtilityTokenHash) &&
                (transaction.Type == TransactionType.ClaimTransaction ||
                 transaction.Type == TransactionType.IssueTransaction))
            {
                return(false);
            }

            if (transaction.Type != TransactionType.MinerTransaction &&
                resultsIssue.Length > 0)
            {
                return(false);
            }

            // TODO: Verify Receiving Scripts?

            if (transaction.Witness.Any(witness => !_witnessOperationsManager.Verify(witness)))
            {
                return(false);
            }

            return(true);
        }