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); }