예제 #1
0
 private static bool CheckAdmin(ApplicationEngine engine, NameState state)
 {
     if (engine.CheckWitnessInternal(state.Owner))
     {
         return(true);
     }
     if (state.Admin is null)
     {
         return(false);
     }
     return(engine.CheckWitnessInternal(state.Admin));
 }
예제 #2
0
        private protected async ContractTask <bool> Transfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount, StackItem data)
        {
            if (amount.Sign < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount));
            }
            if (!from.Equals(engine.CallingScriptHash) && !engine.CheckWitnessInternal(from))
            {
                return(false);
            }
            StorageKey  key_from     = CreateStorageKey(Prefix_Account).Add(from);
            StorageItem storage_from = engine.Snapshot.GetAndChange(key_from);

            if (amount.IsZero)
            {
                if (storage_from != null)
                {
                    TState state_from = storage_from.GetInteroperable <TState>();
                    await OnBalanceChanging(engine, from, state_from, amount);
                }
            }
            else
            {
                if (storage_from is null)
                {
                    return(false);
                }
                TState state_from = storage_from.GetInteroperable <TState>();
                if (state_from.Balance < amount)
                {
                    return(false);
                }
                if (from.Equals(to))
                {
                    await OnBalanceChanging(engine, from, state_from, BigInteger.Zero);
                }
                else
                {
                    await OnBalanceChanging(engine, from, state_from, -amount);

                    if (state_from.Balance == amount)
                    {
                        engine.Snapshot.Delete(key_from);
                    }
                    else
                    {
                        state_from.Balance -= amount;
                    }
                    StorageKey  key_to     = CreateStorageKey(Prefix_Account).Add(to);
                    StorageItem storage_to = engine.Snapshot.GetAndChange(key_to, () => new StorageItem(new TState()));
                    TState      state_to   = storage_to.GetInteroperable <TState>();
                    await OnBalanceChanging(engine, to, state_to, amount);

                    state_to.Balance += amount;
                }
            }
            await PostTransfer(engine, from, to, amount, data, true);

            return(true);
        }
예제 #3
0
        protected bool Transfer(ApplicationEngine engine, UInt160 to, byte[] tokenId)
        {
            if (to is null)
            {
                throw new ArgumentNullException(nameof(to));
            }
            StorageKey key_token = CreateStorageKey(Prefix_Token).Add(GetKey(tokenId));
            TokenState token     = engine.Snapshot.TryGet(key_token)?.GetInteroperable <TokenState>();
            UInt160    from      = token.Owner;

            if (!from.Equals(engine.CallingScriptHash) && !engine.CheckWitnessInternal(from))
            {
                return(false);
            }
            if (!from.Equals(to))
            {
                token = engine.Snapshot.GetAndChange(key_token).GetInteroperable <TokenState>();
                StorageKey      key_from = CreateStorageKey(Prefix_Account).Add(from);
                NFTAccountState account  = engine.Snapshot.GetAndChange(key_from).GetInteroperable <NFTAccountState>();
                account.Remove(tokenId);
                if (account.Balance.IsZero)
                {
                    engine.Snapshot.Delete(key_from);
                }
                token.Owner = to;
                StorageKey key_to = CreateStorageKey(Prefix_Account).Add(to);
                account = engine.Snapshot.GetAndChange(key_to, () => new StorageItem(new NFTAccountState())).GetInteroperable <NFTAccountState>();
                account.Add(tokenId);
                OnTransferred(engine, from, token);
            }
            PostTransfer(engine, from, to, tokenId);
            return(true);
        }
예제 #4
0
파일: NeoToken.cs 프로젝트: jscoop2k/neo
        private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey)
        {
            if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
            {
                return(false);
            }
            StorageKey key = CreateStorageKey(Prefix_Candidate).Add(pubkey);

            if (engine.Snapshot.Storages.TryGet(key) is null)
            {
                return(true);
            }
            StorageItem    item  = engine.Snapshot.Storages.GetAndChange(key);
            CandidateState state = item.GetInteroperable <CandidateState>();

            if (state.Votes.IsZero)
            {
                engine.Snapshot.Storages.Delete(key);
            }
            else
            {
                state.Registered = false;
            }
            return(true);
        }
예제 #5
0
파일: GasToken.cs 프로젝트: superboyiii/neo
 private async ContractTask Refuel(ApplicationEngine engine, UInt160 account, long amount)
 {
     if (amount < 0) throw new ArgumentOutOfRangeException(nameof(amount));
     if (!engine.CheckWitnessInternal(account)) throw new InvalidOperationException();
     await Burn(engine, account, amount);
     engine.Refuel(amount);
 }
예제 #6
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) && !engine.CheckWitnessInternal(from))
            {
                return(false);
            }
            StorageKey  key_from     = CreateStorageKey(Prefix_Account).Add(from);
            StorageItem storage_from = engine.Snapshot.Storages.GetAndChange(key_from);

            if (amount.IsZero)
            {
                if (storage_from != null)
                {
                    TState state_from = storage_from.GetInteroperable <TState>();
                    OnBalanceChanging(engine, from, state_from, amount);
                }
            }
            else
            {
                if (storage_from is null)
                {
                    return(false);
                }
                TState state_from = storage_from.GetInteroperable <TState>();
                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;
                    }
                    StorageKey  key_to     = CreateStorageKey(Prefix_Account).Add(to);
                    StorageItem storage_to = engine.Snapshot.Storages.GetAndChange(key_to, () => new StorageItem(new TState()));
                    TState      state_to   = storage_to.GetInteroperable <TState>();
                    OnBalanceChanging(engine, to, state_to, amount);
                    state_to.Balance += amount;
                }
            }
            engine.SendNotification(Hash, "Transfer", new Array {
                from.ToArray(), to.ToArray(), amount
            });
            return(true);
        }
예제 #7
0
파일: NeoToken.cs 프로젝트: jscoop2k/neo
 private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo)
 {
     if (!engine.CheckWitnessInternal(account))
     {
         return(false);
     }
     return(VoteInternal(engine.Snapshot, account, voteTo));
 }
예제 #8
0
파일: NeoToken.cs 프로젝트: jscoop2k/neo
 private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey)
 {
     if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
     {
         return(false);
     }
     RegisterCandidateInternal(engine.Snapshot, pubkey);
     return(true);
 }
예제 #9
0
        private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo)
        {
            if (!engine.CheckWitnessInternal(account))
            {
                return(false);
            }
            NeoAccountState state_account = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable <NeoAccountState>();

            if (state_account is null)
            {
                return(false);
            }
            CandidateState validator_new = null;

            if (voteTo != null)
            {
                validator_new = engine.Snapshot.Storages.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.Storages.GetAndChange(CreateStorageKey(Prefix_VotersCount));
                if (state_account.VoteTo is null)
                {
                    item.Add(state_account.Balance);
                }
                else
                {
                    item.Add(-state_account.Balance);
                }
            }
            if (state_account.VoteTo != null)
            {
                StorageKey     key = CreateStorageKey(Prefix_Candidate).Add(state_account.VoteTo);
                StorageItem    storage_validator = engine.Snapshot.Storages.GetAndChange(key);
                CandidateState state_validator   = storage_validator.GetInteroperable <CandidateState>();
                state_validator.Votes -= state_account.Balance;
                if (!state_validator.Registered && state_validator.Votes.IsZero)
                {
                    engine.Snapshot.Storages.Delete(key);
                }
            }
            state_account.VoteTo = voteTo;
            if (validator_new != null)
            {
                validator_new.Votes += state_account.Balance;
            }
            return(true);
        }
예제 #10
0
        private StackItem UnregisterCandidate(ApplicationEngine engine, Array args)
        {
            ECPoint pubkey = args[0].GetSpan().AsSerializable <ECPoint>();

            if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
            {
                return(false);
            }
            return(UnregisterCandidate(engine.Snapshot, pubkey));
        }
예제 #11
0
        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);
        }
예제 #12
0
        private StackItem Vote(ApplicationEngine engine, Array args)
        {
            UInt160 account = new UInt160(args[0].GetSpan());
            ECPoint voteTo  = args[1].IsNull ? null : args[1].GetSpan().AsSerializable <ECPoint>();

            if (!engine.CheckWitnessInternal(account))
            {
                return(false);
            }
            return(Vote(engine.Snapshot, account, voteTo));
        }
예제 #13
0
        private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey)
        {
            if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
            {
                return(false);
            }
            StorageKey     key   = CreateStorageKey(Prefix_Candidate).Add(pubkey);
            StorageItem    item  = engine.Snapshot.Storages.GetAndChange(key, () => new StorageItem(new CandidateState()));
            CandidateState state = item.GetInteroperable <CandidateState>();

            state.Registered = true;
            return(true);
        }
예제 #14
0
        private void SetAdmin(ApplicationEngine engine, string name, UInt160 admin)
        {
            if (!nameRegex.IsMatch(name))
            {
                throw new ArgumentException(null, nameof(name));
            }
            string[] names = name.Split('.');
            if (names.Length != 2)
            {
                throw new ArgumentException(null, nameof(name));
            }
            if (admin != null && !engine.CheckWitnessInternal(admin))
            {
                throw new InvalidOperationException();
            }
            NameState state = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Token).Add(GetKey(Utility.StrictUTF8.GetBytes(name)))).GetInteroperable <NameState>();

            if (!engine.CheckWitnessInternal(state.Owner))
            {
                throw new InvalidOperationException();
            }
            state.Admin = admin;
        }
예제 #15
0
        private bool Register(ApplicationEngine engine, string name, UInt160 owner)
        {
            if (!nameRegex.IsMatch(name))
            {
                throw new ArgumentException(null, nameof(name));
            }
            string[] names = name.Split('.');
            if (names.Length != 2)
            {
                throw new ArgumentException(null, nameof(name));
            }
            if (!engine.CheckWitnessInternal(owner))
            {
                throw new InvalidOperationException();
            }
            byte[] hash = GetKey(Utility.StrictUTF8.GetBytes(name));
            if (engine.Snapshot.TryGet(CreateStorageKey(Prefix_Token).Add(hash)) is not null)
            {
                return(false);
            }
            StringList roots = engine.Snapshot[CreateStorageKey(Prefix_Roots)].GetInteroperable <StringList>();

            if (roots.BinarySearch(names[1]) < 0)
            {
                throw new InvalidOperationException();
            }
            engine.AddGas(GetPrice(engine.Snapshot));
            NameState state = new NameState
            {
                Owner       = owner,
                Name        = name,
                Description = "",
                Expiration  = (uint)(engine.PersistingBlock.Timestamp / 1000) + OneYear
            };

            Mint(engine, state);
            engine.Snapshot.Add(CreateStorageKey(Prefix_Expiration).AddBigEndian(state.Expiration).Add(hash), new StorageItem(new byte[] { 0 }));
            return(true);
        }
예제 #16
0
        protected bool CheckCommittee(ApplicationEngine engine)
        {
            UInt160 committeeMultiSigAddr = NEO.GetCommitteeAddress(engine.Snapshot);

            return(engine.CheckWitnessInternal(committeeMultiSigAddr));
        }