protected override void OnDeserialized() { base.OnDeserialized(); if (AssetType == AssetType.GoverningToken && !Hash.Equals(BlockchainBase.GetStaticAttr().GoverningToken.Hash)) { throw new FormatException(); } if (AssetType == AssetType.UtilityToken && !Hash.Equals(BlockchainBase.GetStaticAttr().UtilityToken.Hash)) { throw new FormatException(); } }
/// <summary> /// 反序列化进行完毕时触发 /// </summary> protected override void OnDeserialized() { base.OnDeserialized(); if (Inputs.Length != 0) { throw new FormatException(); } if (Outputs.Any(p => p.AssetId != BlockchainBase.GetStaticAttr().UtilityToken.Hash)) { throw new FormatException(); } }
private bool VerifyAccountState(UInt256 ChainHash) { switch (Field) { case "Votes": BlockchainBase chain = BlockchainBase.GetBlockchain(ChainHash); if (chain == null) { return(false); } ECPoint[] pubkeys; try { pubkeys = Value.AsSerializableArray <ECPoint>((int)BlockchainBase.MaxValidators); } catch (FormatException) { return(false); } UInt160 hash = new UInt160(Key); AccountState account = chain.GetAccountState(hash); if (account?.IsFrozen != false) { return(false); } if (pubkeys.Length > 0) { if (account.GetBalance(BlockchainBase.GetStaticAttr().GoverningToken.Hash).Equals(Fixed8.Zero)) { return(false); } HashSet <ECPoint> sv = new HashSet <ECPoint>(chain.StandbyValidators); DataCache <ECPoint, ValidatorState> validators = chain.GetStates <ECPoint, ValidatorState>(); foreach (ECPoint pubkey in pubkeys) { if (!sv.Contains(pubkey) && validators.TryGet(pubkey)?.Registered != true) { return(false); } } } return(true); default: return(false); } }
/// <summary> /// 验证交易 /// </summary> /// <returns>返回验证的结果</returns> public virtual bool Verify(IEnumerable <Transaction> mempool) { for (int i = 1; i < Inputs.Length; i++) { for (int j = 0; j < i; j++) { if (Inputs[i].PrevHash == Inputs[j].PrevHash && Inputs[i].PrevIndex == Inputs[j].PrevIndex) { return(false); } } } if (mempool.Where(p => p != this).SelectMany(p => p.Inputs).Intersect(Inputs).Count() > 0) { return(false); } if (Chain.IsDoubleSpend(this)) { return(false); } foreach (var group in Outputs.GroupBy(p => p.AssetId)) { AssetState asset = Chain.GetAssetState(group.Key); if (asset == null) { return(false); } if (asset.Expiration <= Chain.Height + 1 && asset.AssetType != AssetType.GoverningToken && asset.AssetType != AssetType.UtilityToken) { return(false); } foreach (TransactionOutput output in group) { if (output.Value.GetData() % (long)Math.Pow(10, 8 - asset.Precision) != 0) { return(false); } } } TransactionResult[] results = GetTransactionResults()?.ToArray(); if (results == null) { return(false); } TransactionResult[] results_destroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray(); if (results_destroy.Length > 1) { return(false); } if (results_destroy.Length == 1 && results_destroy[0].AssetId != BlockchainBase.GetStaticAttr().UtilityToken.Hash) { return(false); } if (SystemFee > Fixed8.Zero && (results_destroy.Length == 0 || results_destroy[0].Amount < SystemFee)) { return(false); } TransactionResult[] results_issue = results.Where(p => p.Amount < Fixed8.Zero).ToArray(); switch (Type) { case TransactionType.MinerTransaction: case TransactionType.ClaimTransaction: if (results_issue.Any(p => p.AssetId != BlockchainBase.GetStaticAttr().UtilityToken.Hash)) { return(false); } break; case TransactionType.IssueTransaction: if (results_issue.Any(p => p.AssetId == BlockchainBase.GetStaticAttr().UtilityToken.Hash)) { return(false); } break; default: if (results_issue.Length > 0) { return(false); } break; } if (Attributes.Count(p => p.Usage == TransactionAttributeUsage.ECDH02 || p.Usage == TransactionAttributeUsage.ECDH03) > 1) { return(false); } return(this.VerifyScripts()); }
/// <summary> /// 验证交易 /// </summary> /// <returns>返回验证结果</returns> public override bool Verify(IEnumerable <Transaction> mempool) { if (!base.Verify(mempool)) { return(false); } if (Claims.Length != Claims.Distinct().Count()) { return(false); } if (mempool.OfType <ClaimTransaction>().Where(p => p != this).SelectMany(p => p.Claims).Intersect(Claims).Count() > 0) { return(false); } TransactionResult result = GetTransactionResults().FirstOrDefault(p => p.AssetId == BlockchainBase.GetStaticAttr().UtilityToken.Hash); if (result == null || result.Amount > Fixed8.Zero) { return(false); } try { return(Chain.CalculateBonus(Claims, false) == -result.Amount); } catch (ArgumentException) { return(false); } catch (NotSupportedException) { return(false); } }
public static Fixed8 CalculateNetFee(IEnumerable <Transaction> transactions) { Transaction[] ts = transactions.Where(p => p.Type != TransactionType.MinerTransaction && p.Type != TransactionType.ClaimTransaction).ToArray(); Fixed8 amount_in = ts.SelectMany(p => p.References.Values.Where(o => o.AssetId == BlockchainBase.GetStaticAttr().UtilityToken.Hash)).Sum(p => p.Value); Fixed8 amount_out = ts.SelectMany(p => p.Outputs.Where(o => o.AssetId == BlockchainBase.GetStaticAttr().UtilityToken.Hash)).Sum(p => p.Value); Fixed8 amount_sysfee = ts.Sum(p => p.SystemFee); return(amount_in - amount_out - amount_sysfee); }