/// <summary> /// The implementation of System.Contract.NativePostPersist. /// Calls to the <see cref="NativeContract.PostPersist"/> of all native contracts. /// </summary> protected internal async void NativePostPersist() { try { if (Trigger != TriggerType.PostPersist) { throw new InvalidOperationException(); } foreach (NativeContract contract in NativeContract.Contracts) { uint[] updates = ProtocolSettings.NativeUpdateHistory[contract.Name]; if (updates.Length == 0) { continue; } if (updates[0] <= PersistingBlock.Index) { await contract.PostPersist(this); } } } catch (Exception ex) { Throw(ex); } }
public override void LoadContext(ApplicationEngine engine, Array args) { for (int i = args.Count - 1; i >= 0; i--) { engine.Push(args[i]); } }
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); }
protected virtual StackItem Main(ApplicationEngine engine, string operation, VMArray args) { if (operation == "supportedStandards") { return(SupportedStandards.Select(p => (StackItem)p).ToList()); } throw new NotSupportedException(); }
protected StackItem Transfer(ApplicationEngine engine, VMArray args) { UInt160 from = new UInt160(args[0].GetByteArray()); UInt160 to = new UInt160(args[1].GetByteArray()); BigInteger amount = args[2].GetBigInteger(); return(Transfer(engine, from, to, amount)); }
public NotificationRecord(UInt160 scriptHash, string eventName, Neo.VM.Types.Array state, InventoryType inventoryType, UInt256 inventoryHash) { ScriptHash = scriptHash; EventName = eventName; State = state; InventoryType = inventoryType; InventoryHash = inventoryHash; }
protected internal void CallContractEx(UInt160 contractHash, string method, Array args, CallFlags callFlags) { if ((callFlags & ~CallFlags.All) != 0) { throw new ArgumentOutOfRangeException(nameof(callFlags)); } CallContractInternal(contractHash, method, args, callFlags, ReturnTypeConvention.EnsureNotEmpty); }
protected StackItem OnPersist(ApplicationEngine engine, VMArray args) { if (engine.Trigger != TriggerType.System) { return(false); } return(OnPersist(engine)); }
protected internal void SendNotification(UInt160 hash, string eventName, Array state) { NotifyEventArgs notification = new NotifyEventArgs(ScriptContainer, hash, eventName, (Array)state.DeepCopy()); Notify?.Invoke(this, notification); notifications ??= new List <NotifyEventArgs>(); notifications.Add(notification); }
/// <summary> /// The implementation of System.Contract.CreateMultisigAccount. /// Calculates corresponding multisig account scripthash for the given public keys. /// </summary> /// <param name="m">The minimum number of correct signatures that need to be provided in order for the verification to pass.</param> /// <param name="pubKeys">The public keys of the account.</param> /// <returns>The hash of the account.</returns> internal protected UInt160 CreateMultisigAccount(int m, ECPoint[] pubKeys) { long fee = IsHardforkEnabled(Hardfork.HF_Aspidochelone) ? CheckSigPrice * pubKeys.Length : 1 << 8; AddGas(fee * ExecFeeFactor); return(Contract.CreateMultiSigRedeemScript(m, pubKeys).ToScriptHash()); }
protected internal void RuntimeLog(byte[] state) { if (state.Length > MaxNotificationSize) { throw new ArgumentException(); } string message = Utility.StrictUTF8.GetString(state); SendLog(ScriptContainer, CurrentScriptHash, message, CurrentContext.InstructionPointer); }
protected internal void RuntimeLog(byte[] state) { if (state.Length > MaxNotificationSize) { throw new ArgumentException(); } string message = Utility.StrictUTF8.GetString(state); Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash, message)); }
protected internal bool CheckWitness(byte[] hashOrPubkey) { UInt160 hash = hashOrPubkey.Length switch { 20 => new UInt160(hashOrPubkey), 33 => Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(hashOrPubkey, ECCurve.Secp256r1)).ToScriptHash(), _ => throw new ArgumentException() }; return(CheckWitnessInternal(hash)); }
private StackItem SetMaxTransactionsPerBlock(ApplicationEngine engine, VMArray args) { if (!CheckValidators(engine)) { return(false); } uint value = (uint)args[0].GetBigInteger(); StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxTransactionsPerBlock)); storage.Value = BitConverter.GetBytes(value); return(true); }
private StackItem SetFeePerByte(ApplicationEngine engine, VMArray args) { if (!CheckValidators(engine)) { return(false); } long value = (long)args[0].GetBigInteger(); StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_FeePerByte)); storage.Value = BitConverter.GetBytes(value); return(true); }
protected virtual StackItem Main(ApplicationEngine engine, string operation, VMArray args) { switch (operation) { case "onPersist": return(OnPersist(engine)); case "supportedStandards": return(SupportedStandards.Select(p => (StackItem)p).ToList()); } throw new NotSupportedException(); }
internal bool Invoke(ApplicationEngine engine) { if (!new UInt160(engine.CurrentContext.ScriptHash).Equals(ScriptHash)) { return(false); } string operation = engine.CurrentContext.EvaluationStack.Pop().GetString(); VMArray args = (VMArray)engine.CurrentContext.EvaluationStack.Pop(); StackItem result = Main(engine, operation, args); engine.CurrentContext.EvaluationStack.Push(result); return(true); }
protected internal void RuntimeNotify(byte[] eventName, Array state) { if (eventName.Length > MaxEventName) { throw new ArgumentException(); } using (MemoryStream ms = new MemoryStream(MaxNotificationSize)) using (BinaryWriter writer = new BinaryWriter(ms)) { BinarySerializer.Serialize(writer, state, MaxNotificationSize); } SendNotification(CurrentScriptHash, Utility.StrictUTF8.GetString(eventName), state); }
public static JToken ToJson(this StackItem item) { return item switch { Neo.VM.Types.Boolean _ => item.GetBoolean(), Neo.VM.Types.Buffer buffer => buffer.GetSpan().ToHexString(), Neo.VM.Types.ByteString byteString => byteString.GetSpan().ToHexString(), Neo.VM.Types.Integer @int => @int.GetInteger().ToString(), // Neo.VM.Types.InteropInterface _ => MakeVariable("InteropInterface"), Neo.VM.Types.Map map => MapToJson(map), Neo.VM.Types.Null _ => new JValue((object?)null), // Neo.VM.Types.Pointer _ => MakeVariable("Pointer"), Neo.VM.Types.Array array => new JArray(array.Select(i => i.ToJson())), _ => throw new NotSupportedException(), };
public static Variable Create(IVariableContainerSession session, Neo.VM.Types.Array array, string name) { var container = new NeoArrayContainer(session, array, name); var containerID = session.AddVariableContainer(container); var typeName = array is Neo.VM.Types.Struct ? "Struct" : "Array"; return(new Variable() { Name = name, Type = $"{typeName}[{array.Count}]", VariablesReference = containerID, IndexedVariables = array.Count, }); }
protected internal NotifyEventArgs[] GetNotifications(UInt160 hash) { IEnumerable <NotifyEventArgs> notifications = Notifications; if (hash != null) // must filter by scriptHash { notifications = notifications.Where(p => p.ScriptHash == hash); } NotifyEventArgs[] array = notifications.ToArray(); if (array.Length > Limits.MaxStackSize) { throw new InvalidOperationException(); } return(array); }
static JToken StackItemToJson(StackItem item, string?typeHint) { return(typeHint switch { "Boolean" => item.GetBoolean().ToString(), "Integer" => item.GetBigInteger().ToString(), "String" => item.GetString(), _ => item switch { Neo.VM.Types.Boolean _ => item.GetBoolean().ToString(), Neo.VM.Types.ByteArray _ => $"{item.GetBigInteger().ToHexString()} ({item.GetString()})", Neo.VM.Types.Integer _ => item.GetBigInteger().ToString(), Neo.VM.Types.Array array => new JArray(array.Select(i => StackItemToJson(i, null))), _ => throw new NotSupportedException(item.GetType().Name), } });
private StackItem SetMaxBlockSize(ApplicationEngine engine, VMArray args) { if (!CheckValidators(engine)) { return(false); } uint value = (uint)args[0].GetBigInteger(); if (Network.P2P.Message.PayloadMaxSize <= value) { return(false); } StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxBlockSize)); storage.Value = BitConverter.GetBytes(value); return(true); }
internal bool Invoke(ApplicationEngine engine) { if (!engine.CurrentScriptHash.Equals(Hash)) { return(false); } string operation = engine.CurrentContext.EvaluationStack.Pop().GetString(); VMArray args = (VMArray)engine.CurrentContext.EvaluationStack.Pop(); if (!methods.TryGetValue(operation, out ContractMethodMetadata method)) { return(false); } StackItem result = method.Delegate(engine, args); engine.CurrentContext.EvaluationStack.Push(result); return(true); }
private StackItem UnblockAccount(ApplicationEngine engine, VMArray args) { if (!CheckValidators(engine)) { return(false); } UInt160 account = new UInt160(args[0].GetByteArray()); StorageKey key = CreateStorageKey(Prefix_BlockedAccounts); StorageItem storage = engine.Snapshot.Storages[key]; HashSet <UInt160> accounts = new HashSet <UInt160>(storage.Value.AsSerializableArray <UInt160>()); if (!accounts.Remove(account)) { return(false); } storage = engine.Snapshot.Storages.GetAndChange(key); storage.Value = accounts.ToArray().ToByteArray(); return(true); }
public static JToken ToJson(this StackItem item, string typeHint = "") { var stringRep = item.ToStringRep(typeHint); return(stringRep != null ? (JToken)stringRep : item switch { Neo.VM.Types.Boolean _ => item.GetBoolean(), // Neo.VM.Types.Buffer buffer => "Buffer", Neo.VM.Types.ByteString byteString => byteString.GetSpan().ToHexString(), Neo.VM.Types.Integer @int => @int.GetInteger().ToString(), // Neo.VM.Types.InteropInterface _ => MakeVariable("InteropInterface"), // Neo.VM.Types.Map _ => MakeVariable("Map"), Neo.VM.Types.Null _ => new JValue((object?)null), // Neo.VM.Types.Pointer _ => MakeVariable("Pointer"), Neo.VM.Types.Array array => new JArray(array.Select(i => i.ToJson())), _ => throw new NotSupportedException(), });
/// <summary> /// The implementation of System.Contract.CallNative. /// Calls to a native contract. /// </summary> /// <param name="version">The version of the native contract to be called.</param> protected internal void CallNativeContract(byte version) { NativeContract contract = NativeContract.GetContract(CurrentScriptHash); if (contract is null) { throw new InvalidOperationException("It is not allowed to use \"System.Contract.CallNative\" directly."); } uint[] updates = ProtocolSettings.NativeUpdateHistory[contract.Name]; if (updates.Length == 0) { throw new InvalidOperationException($"The native contract {contract.Name} is not active."); } if (updates[0] > NativeContract.Ledger.CurrentIndex(Snapshot)) { throw new InvalidOperationException($"The native contract {contract.Name} is not active."); } contract.Invoke(this, version); }
public override void LoadContext(ApplicationEngine engine, Array args) { engine.Push(args); engine.Push(method.Name); engine.Push(contract.ScriptHash.ToArray()); }
private void CallContractInternal(ContractState contract, ContractMethodDescriptor method, Array args, CallFlags flags, ReturnTypeConvention convention) { if (invocationCounter.TryGetValue(contract.Hash, out var counter)) { invocationCounter[contract.Hash] = counter + 1; } else { invocationCounter[contract.Hash] = 1; } GetInvocationState(CurrentContext).Convention = convention; ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); UInt160 callingScriptHash = state.ScriptHash; CallFlags callingFlags = state.CallFlags; if (args.Count != method.Parameters.Length) { throw new InvalidOperationException($"Method {method.Name} Expects {method.Parameters.Length} Arguments But Receives {args.Count} Arguments"); } ExecutionContext context_new = LoadContract(contract, method.Name, flags & callingFlags, false); state = context_new.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; if (NativeContract.IsNative(contract.Hash)) { context_new.EvaluationStack.Push(args); context_new.EvaluationStack.Push(method.Name); } else { for (int i = args.Count - 1; i >= 0; i--) { context_new.EvaluationStack.Push(args[i]); } } }
protected internal void CallContract(UInt160 contractHash, string method, Array args) { CallContractEx(contractHash, method, args, CallFlags.All); }