Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }