Esempio n. 1
0
        private void CallContractInternal(UInt160 contractHash, string method, Array args, CallFlags flags, ReturnTypeConvention convention)
        {
            if (method.StartsWith('_'))
            {
                throw new ArgumentException($"Invalid Method Name: {method}");
            }

            ContractState contract = NativeContract.Management.GetContract(Snapshot, contractHash);

            if (contract is null)
            {
                throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}");
            }
            ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method);

            if (md is null)
            {
                throw new InvalidOperationException($"Method {method} Does Not Exist In Contract {contractHash}");
            }

            if (md.Safe)
            {
                flags &= ~CallFlags.WriteStates;
            }
            else
            {
                ContractState currentContract = NativeContract.Management.GetContract(Snapshot, CurrentScriptHash);
                if (currentContract?.CanCall(contract, method) == false)
                {
                    throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contractHash} From Contract {CurrentScriptHash}");
                }
            }

            CallContractInternal(contract, md, args, flags, convention);
        }
Esempio n. 2
0
        private void CallContractInternal(UInt160 contractHash, string method, CallFlags flags, bool hasReturnValue, StackItem[] args)
        {
            ContractState contract = NativeContract.ContractManagement.GetContract(Snapshot, contractHash);

            if (contract is null)
            {
                throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}");
            }
            ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method);

            if (md is null)
            {
                throw new InvalidOperationException($"Method {method} Does Not Exist In Contract {contractHash}");
            }

            if (md.Safe)
            {
                flags &= ~CallFlags.WriteStates;
            }
            else
            {
                ContractState currentContract = NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash);
                if (currentContract?.CanCall(contract, method) == false)
                {
                    throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contractHash} From Contract {CurrentScriptHash}");
                }
            }

            CallContractInternal(contract, md, flags, hasReturnValue, args);
        }
Esempio n. 3
0
        private ExecutionContext CallContractInternal(ContractState contract, ContractMethodDescriptor method, CallFlags flags, bool hasReturnValue, IReadOnlyList <StackItem> args)
        {
            if (method.Safe)
            {
                flags &= ~CallFlags.WriteStates;
            }
            else
            {
                ContractState currentContract = NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash);
                if (currentContract?.CanCall(contract, method.Name) == false)
                {
                    throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contract.Hash} From Contract {CurrentScriptHash}");
                }
            }

            if (invocationCounter.TryGetValue(contract.Hash, out var counter))
            {
                invocationCounter[contract.Hash] = counter + 1;
            }
            else
            {
                invocationCounter[contract.Hash] = 1;
            }

            ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>();
            UInt160   callingScriptHash = state.ScriptHash;
            CallFlags callingFlags      = state.CallFlags;

            if (args.Count != method.Parameters.Length)
            {
                throw new InvalidOperationException($"Method {method} Expects {method.Parameters.Length} Arguments But Receives {args.Count} Arguments");
            }
            if (hasReturnValue ^ (method.ReturnType != ContractParameterType.Void))
            {
                throw new InvalidOperationException("The return value type does not match.");
            }
            ExecutionContext context_new = LoadContract(contract, method, flags & callingFlags);

            state = context_new.GetState <ExecutionContextState>();
            state.CallingScriptHash = callingScriptHash;

            for (int i = args.Count - 1; i >= 0; i--)
            {
                context_new.EvaluationStack.Push(args[i]);
            }
            if (NativeContract.IsNative(contract.Hash))
            {
                context_new.EvaluationStack.Push(method.Name);
            }

            return(context_new);
        }