private async ContractTask <bool> Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo) { if (!engine.CheckWitnessInternal(account)) { return(false); } VauthAccountState state_account = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable <VauthAccountState>(); if (state_account is null) { return(false); } CandidateState validator_new = null; if (voteTo != null) { validator_new = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(voteTo))?.GetInteroperable <CandidateState>(); if (validator_new is null) { return(false); } if (!validator_new.Registered) { return(false); } } if (state_account.VoteTo is null ^ voteTo is null) { StorageItem item = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount)); if (state_account.VoteTo is null) { item.Add(state_account.Balance); } else { item.Add(-state_account.Balance); } } await DistributeValt(engine, account, state_account); if (state_account.VoteTo != null) { StorageKey key = CreateStorageKey(Prefix_Candidate).Add(state_account.VoteTo); StorageItem storage_validator = engine.Snapshot.GetAndChange(key); CandidateState state_validator = storage_validator.GetInteroperable <CandidateState>(); state_validator.Votes -= state_account.Balance; CheckCandidate(engine.Snapshot, state_account.VoteTo, state_validator); } state_account.VoteTo = voteTo; if (validator_new != null) { validator_new.Votes += state_account.Balance; } return(true); }
public BigInteger UnclaimedValt(DataCache snapshot, UInt160 account, uint end) { StorageItem storage = snapshot.TryGet(CreateStorageKey(Prefix_Account).Add(account)); if (storage is null) { return(BigInteger.Zero); } VauthAccountState state = storage.GetInteroperable <VauthAccountState>(); return(CalculateBonus(snapshot, state.VoteTo, state.Balance, state.BalanceHeight, end)); }
private async ContractTask DistributeValt(ApplicationEngine engine, UInt160 account, VauthAccountState state) { // PersistingBlock is null when running under the debugger if (engine.PersistingBlock is null) { return; } BigInteger valt = CalculateBonus(engine.Snapshot, state.VoteTo, state.Balance, state.BalanceHeight, engine.PersistingBlock.Index); state.BalanceHeight = engine.PersistingBlock.Index; await VALT.Mint(engine, account, valt, true); }
internal override async ContractTask OnBalanceChanging(ApplicationEngine engine, UInt160 account, VauthAccountState state, BigInteger amount) { await DistributeValt(engine, account, state); if (amount.IsZero) { return; } if (state.VoteTo is null) { return; } engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount); StorageKey key = CreateStorageKey(Prefix_Candidate).Add(state.VoteTo); CandidateState candidate = engine.Snapshot.GetAndChange(key).GetInteroperable <CandidateState>(); candidate.Votes += amount; CheckCandidate(engine.Snapshot, state.VoteTo, candidate); }