private bool CheckValidators(ApplicationEngine engine) { UInt256 prev_hash = engine.Snapshot.PersistingBlock.PrevHash; TrimmedBlock prev_block = engine.Snapshot.Blocks[prev_hash]; return(InteropService.CheckWitness(engine, prev_block.NextConsensus)); }
private StackItem Vote(ApplicationEngine engine, VMArray args) { UInt160 account = new UInt160(args[0].GetByteArray()); ECPoint[] pubkeys = ((VMArray)args[1]).Select(p => p.GetByteArray().AsSerializable <ECPoint>()).ToArray(); if (!InteropService.CheckWitness(engine, account)) { return(false); } StorageKey key_account = CreateAccountKey(account); if (engine.Snapshot.Storages.TryGet(key_account) is null) { return(false); } StorageItem storage_account = engine.Snapshot.Storages.GetAndChange(key_account); AccountState state_account = new AccountState(storage_account.Value); foreach (ECPoint pubkey in state_account.Votes) { StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Validator, pubkey.ToArray())); ValidatorState state_validator = ValidatorState.FromByteArray(storage_validator.Value); state_validator.Votes -= state_account.Balance; storage_validator.Value = state_validator.ToByteArray(); } pubkeys = pubkeys.Distinct().Where(p => engine.Snapshot.Storages.TryGet(CreateStorageKey(Prefix_Validator, p.ToArray())) != null).ToArray(); if (pubkeys.Length != state_account.Votes.Length) { StorageItem storage_count = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_ValidatorsCount), () => new StorageItem { Value = new ValidatorsCountState().ToByteArray() }); ValidatorsCountState state_count = ValidatorsCountState.FromByteArray(storage_count.Value); if (state_account.Votes.Length > 0) { state_count.Votes[state_account.Votes.Length - 1] -= state_account.Balance; } if (pubkeys.Length > 0) { state_count.Votes[pubkeys.Length - 1] += state_account.Balance; } storage_count.Value = state_count.ToByteArray(); } state_account.Votes = pubkeys; storage_account.Value = state_account.ToByteArray(); foreach (ECPoint pubkey in state_account.Votes) { StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Validator, pubkey.ToArray())); ValidatorState state_validator = ValidatorState.FromByteArray(storage_validator.Value); state_validator.Votes += state_account.Balance; storage_validator.Value = state_validator.ToByteArray(); } return(true); }
protected virtual bool Transfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount) { if (amount.Sign < 0) { throw new ArgumentOutOfRangeException(nameof(amount)); } if (!from.Equals(engine.CallingScriptHash) && !InteropService.CheckWitness(engine, from)) { return(false); } ContractState contract_to = engine.Snapshot.Contracts.TryGet(to); if (contract_to?.Payable == false) { return(false); } StorageKey key_from = CreateAccountKey(from); StorageItem storage_from = engine.Snapshot.Storages.TryGet(key_from); if (amount.IsZero) { if (storage_from != null) { TState state_from = new TState(); state_from.FromByteArray(storage_from.Value); OnBalanceChanging(engine, from, state_from, amount); } } else { if (storage_from is null) { return(false); } TState state_from = new TState(); state_from.FromByteArray(storage_from.Value); if (state_from.Balance < amount) { return(false); } if (from.Equals(to)) { OnBalanceChanging(engine, from, state_from, BigInteger.Zero); } else { OnBalanceChanging(engine, from, state_from, -amount); if (state_from.Balance == amount) { engine.Snapshot.Storages.Delete(key_from); } else { state_from.Balance -= amount; storage_from = engine.Snapshot.Storages.GetAndChange(key_from); storage_from.Value = state_from.ToByteArray(); } StorageKey key_to = CreateAccountKey(to); StorageItem storage_to = engine.Snapshot.Storages.GetAndChange(key_to, () => new StorageItem { Value = new TState().ToByteArray() }); TState state_to = new TState(); state_to.FromByteArray(storage_to.Value); OnBalanceChanging(engine, to, state_to, amount); state_to.Balance += amount; storage_to.Value = state_to.ToByteArray(); } } engine.SendNotification(Hash, new Array(engine.ReferenceCounter, new StackItem[] { "Transfer", from.ToArray(), to.ToArray(), amount })); return(true); }