bool CheckWitness(ExecutionEngineBase engine) { // Fake CheckWitness var context = engine.CurrentContext; { if (context == null) { return(false); } if (!context.EvaluationStack.TryPop(out StackItemBase it)) { return(false); } using (it) { if (it.ToByteArray() == null) { return(false); } using (var itb = engine.CreateBool(true)) context.EvaluationStack.Push(itb); } } return(true); }
private bool Contract_GetStorageContext(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var stack = ctx.EvaluationStack; var contract = stack.PopObject <Contract>(); if (!_contractsCreated.TryGetValue(contract.ScriptHash, out var created)) { return(false); } if (!created.Equals(new UInt160(engine.CurrentContext.ScriptHash))) { return(false); } stack.PushObject(new StorageContext { ScriptHash = contract.ScriptHash, IsReadOnly = false }); return(true); }
private StackItemBase DeserializeStackItem(ExecutionEngineBase engine, BinaryReader reader) { EStackItemType type = (EStackItemType)reader.ReadByte(); switch (type) { case EStackItemType.ByteArray: return(engine.CreateByteArray(reader.ReadVarBytes())); case EStackItemType.Bool: return(engine.CreateBool(reader.ReadBoolean())); case EStackItemType.Integer: return(engine.CreateInteger(new BigInteger(reader.ReadVarBytes()))); case EStackItemType.Array: case EStackItemType.Struct: { ArrayStackItemBase array; if (type == EStackItemType.Struct) { array = engine.CreateStruct(); } else { array = engine.CreateArray(); } ulong count = reader.ReadVarInt(); while (count-- > 0) { array.Add(DeserializeStackItem(engine, reader)); } return(array); } case EStackItemType.Map: { var map = engine.CreateMap(); ulong count = reader.ReadVarInt(); while (count-- > 0) { StackItemBase key = DeserializeStackItem(engine, reader); StackItemBase value = DeserializeStackItem(engine, reader); map[key] = value; key.Dispose(); value.Dispose(); } return(map); } default: throw new FormatException(); } }
protected virtual bool Runtime_CheckWitness(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } bool result; var hashOrPubkey = ctx.EvaluationStack.PopByteArray(); if (hashOrPubkey.Length == 20) { result = CheckWitness(engine, new UInt160(hashOrPubkey)); } else if (hashOrPubkey.Length == 33) { result = CheckWitness(engine, new ECPoint(hashOrPubkey)); } else { return(false); } ctx.EvaluationStack.Push(result); return(true); }
void CheckItem(ExecutionEngineBase engine, StackItemBase item) { int c = engine.ResultStack.Count; engine.ResultStack.Push(item); Assert.AreEqual(engine.ResultStack.Count, c + 1); Assert.IsTrue(engine.ResultStack.TryPeek(0, out StackItemBase obj)); // PEEK obj.Dispose(); obj = engine.ResultStack.Peek(0); Assert.IsNotNull(obj); Assert.AreEqual(obj.Type, item.Type); Assert.IsTrue(obj.Equals(item)); // POP obj.Dispose(); obj = engine.ResultStack.Pop(); Assert.AreEqual(engine.ResultStack.Count, c); Assert.IsNotNull(obj); Assert.AreEqual(obj.Type, item.Type); Assert.IsTrue(obj.Equals(item)); obj.Dispose(); }
private bool Contract_Destroy(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var stack = ctx.EvaluationStack; var hash = new UInt160(engine.CurrentContext.ScriptHash); var contract = _contracts.TryGet(hash); if (contract == null) { return(true); } _contracts.Delete(hash); if (contract.HasStorage) { foreach (var pair in _storages.Find(hash.ToArray())) { _storages.Delete(pair.Key); } } return(true); }
protected bool CheckWitness(ExecutionEngineBase engine, UInt160 hash) { // TODO: IVerifiable? //IVerifiable container = (IVerifiable)engine.MessageProvider; //UInt160[] _hashes_for_verifying = container.GetScriptHashesForVerifying(); //return _hashes_for_verifying.Contains(hash); return(true); }
/// <summary> /// Assert result /// </summary> /// <param name="engine">Engine</param> /// <param name="result">Result</param> /// <param name="logBag">Log bag</param> /// <param name="notBag">Not bag</param> /// <param name="message">Message</param> private void AssertResult(ExecutionEngineBase engine, VMUTExecutionEngineState result, List <string> logBag, List <JToken> notBag, string message) { AssertAreEqual(engine.State.ToString(), result.State.ToString(), message + "State is different"); AssertAreEqual(engine.ConsumedGas, result.ConsumedGas, message + "Consumed gas is different"); AssertAreEqual(logBag.ToArray(), result.Logs ?? new string[0], message + "Logs are different"); AssertAreEqual(notBag.ToArray(), result.Notifications == null ? new JToken[0] : result.Notifications.Select(u => PrepareJsonItem(u)).ToArray(), message + "Notifies are different"); AssertResult(engine.InvocationStack, result.InvocationStack, message); AssertResult(engine.ResultStack, result.ResultStack, message); }
private bool Asset_Create(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var stack = ctx.EvaluationStack; //var tx = (InvocationTransaction)engine.MessageProvider; //var assetType = (AssetType)(byte)stack.PopBigInteger(); //if (!Enum.IsDefined(typeof(AssetType), assetType) || assetType == AssetType.CreditFlag || assetType == AssetType.DutyFlag || assetType == AssetType.GoverningToken || assetType == AssetType.UtilityToken) // return false; //if (stack.PeekByteArray().Length > 1024) // return false; //var name = Encoding.UTF8.GetString(stack.PopByteArray()); //var amount = new Fixed8((long)stack.PopBigInteger()); //if (amount == Fixed8.Zero || amount < -Fixed8.Satoshi) return false; //if (assetType == AssetType.Invoice && amount != -Fixed8.Satoshi) // return false; //var precision = (byte)stack.PopBigInteger(); //if (precision > 8) return false; //if (assetType == AssetType.Share && precision != 0) return false; //if (amount != -Fixed8.Satoshi && amount.GetData() % (long)Math.Pow(10, 8 - precision) != 0) // return false; //ECPoint owner = ECPoint.DecodePoint(stack.PopByteArray(), ECCurve.Secp256r1); //if (owner.IsInfinity) return false; //if (!CheckWitness(engine, owner)) // return false; //var admin = new UInt160(stack.PopByteArray()); //var issuer = new UInt160(stack.PopByteArray()); //Asset asset = _assets.GetOrAdd(tx.Hash, () => new Asset //{ // Id = tx.Hash, // AssetType = assetType, // Name = name, // Amount = amount, // Available = Fixed8.Zero, // Precision = precision, // Fee = Fixed8.Zero, // FeeAddress = new UInt160(), // Owner = owner, // Admin = admin, // Issuer = issuer, // Expiration = Blockchain.Default.Height + 1 + 2000000, // IsFrozen = false //}); //stack.PushObject(asset); return(true); }
protected virtual bool Runtime_Log(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var message = Encoding.UTF8.GetString(ctx.EvaluationStack.PopByteArray()); _interopService.RaiseOnLog(new LogEventArgs(ctx.ScriptHash.ToArray(), message)); return(true); }
protected virtual bool Runtime_Notify(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var state = ctx.EvaluationStack.PopObject <StackItemBase>(); _interopService.RaiseOnNotify(new NotifyEventArgs(ctx.ScriptHash.ToArray(), state)); return(true); }
protected virtual bool Storage_GetReadOnlyContext(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } ctx.EvaluationStack.PushObject(new StorageContext { ScriptHash = new UInt160(ctx.ScriptHash), IsReadOnly = true }); return(true); }
private bool Runtime_Deserialize(ExecutionEngineBase engine) { var context = engine.CurrentContext; { if (context == null) { return(false); } if (!context.EvaluationStack.TryPop(out StackItemBase it)) { return(false); } var data = it.ToByteArray(); it.Dispose(); using (MemoryStream ms = new MemoryStream(data, false)) using (BinaryReader reader = new BinaryReader(ms)) { StackItemBase item = null; try { item = DeserializeStackItem(engine, reader); } catch { if (item != null) { item.Dispose(); } return(false); } context.EvaluationStack.Push(item); if (item != null) { item.Dispose(); } } } return(true); }
private bool Runtime_Serialize(ExecutionEngineBase engine) { var context = engine.CurrentContext; { if (context == null) { return(false); } if (!context.EvaluationStack.TryPop(out StackItemBase it)) { return(false); } using (it) { using (MemoryStream ms = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(ms)) { try { SerializeStackItem(it, writer); } catch { return(false); } writer.Flush(); using (var bi = engine.CreateByteArray(ms.ToArray())) context.EvaluationStack.Push(bi); } } } return(true); }
/// <summary> /// Check if the engine is clean /// </summary> /// <param name="engine">Engine</param> /// <param name="invocationStack">True for Check invocationStack</param> protected void CheckClean(ExecutionEngineBase engine, bool invocationStack = true) { Assert.AreEqual(0, engine.ResultStack.Count); if (invocationStack) { Assert.AreEqual(0, engine.InvocationStack.Count); } else { var current = engine.CurrentContext; if (current == null) { Assert.AreEqual(EVMState.Halt, engine.State); } else { Assert.AreEqual(0, current.EvaluationStack.Count); Assert.AreEqual(0, current.AltStack.Count); } } }
bool Storage_GetContext(ExecutionEngineBase engine) { var context = engine.CurrentContext; { if (context == null) { return(false); } var id = context.ScriptHash.ToHexString(); if (!Storages.TryGetValue(id, out DummyStorageContext stContext)) { stContext = new DummyStorageContext(id, context.ScriptHash); Storages[stContext.Id] = stContext; } using (var i = engine.CreateInterop(stContext)) context.EvaluationStack.Push(i); } return(true); }
bool Storage_Get(ExecutionEngineBase engine) { var context = engine.CurrentContext; { if (context == null) { return(false); } if (!context.EvaluationStack.TryPop(out InteropStackItemBase <DummyStorageContext> inter)) { return(false); } using (inter) { if (!(inter.Value is DummyStorageContext stContext)) { return(false); } if (!context.EvaluationStack.TryPop(out StackItemBase it)) { return(false); } using (it) { var key = it.ToByteArray(); if (key == null) { return(false); } if (stContext.Storage.TryGetValue(key.ToHexString(), out byte[] value))
protected bool CheckWitness(ExecutionEngineBase engine, ECPoint pubkey) { // TODO: Contract.CreateSignatureRedeemScript? //return CheckWitness(engine, Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()); return(true); }
/// <summary> /// Constructor /// </summary> /// <param name="engine">Execution Engine</param> /// <param name="service">Base Service</param> public InteropServiceAdapter(ExecutionEngineBase engine, InteropService service) { _service = service; _engine = engine; }
public InvocationProcess(ExecutionEngineBase executionEngine) { _executionEngine = executionEngine; }
private bool Contract_Create(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var stack = ctx.EvaluationStack; var script = stack.PopByteArray(); if (script.Length > 1024 * 1024) { return(false); } var parameters = stack.PopByteArray().Select(p => (ContractParameterType)p).ToArray(); if (parameters.Length > 252) { return(false); } // TODO: PopBigInteger to byte? var returnType = (ContractParameterType)(byte)stack.PopBigInteger(); var metadata = (ContractMetadata)(byte)stack.PopBigInteger(); if (stack.PeekByteArray().Length > 252) { return(false); } var name = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 252) { return(false); } var version = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 252) { return(false); } var author = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 252) { return(false); } var email = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 65536) { return(false); } var description = Encoding.UTF8.GetString(stack.PopByteArray()); var scriptHash = script.ToScriptHash(); var contract = _contracts.TryGet(scriptHash); if (contract == null) { contract = new Contract { Code = new Code { Script = script, ScriptHash = scriptHash, Parameters = parameters, ReturnType = returnType, Metadata = metadata }, Name = name, Version = version, Author = author, Email = email, Description = description }; _contracts.Add(scriptHash, contract); _contractsCreated.Add(scriptHash, new UInt160(engine.CurrentContext.ScriptHash)); } stack.PushObject(contract); return(true); }
private bool Contract_Migrate(ExecutionEngineBase engine) { var ctx = engine.CurrentContext; if (ctx == null) { return(false); } var stack = ctx.EvaluationStack; var script = stack.PopByteArray(); if (script.Length > 1024 * 1024) { return(false); } var parameters = stack.PopByteArray().Select(p => (ContractParameterType)p).ToArray(); if (parameters.Length > 252) { return(false); } var returnType = (ContractParameterType)(byte)stack.PopBigInteger(); var metadata = (ContractMetadata)(byte)stack.PopBigInteger(); if (stack.PeekByteArray().Length > 252) { return(false); } var name = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 252) { return(false); } var version = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 252) { return(false); } var author = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 252) { return(false); } var email = Encoding.UTF8.GetString(stack.PopByteArray()); if (stack.PeekByteArray().Length > 65536) { return(false); } var description = Encoding.UTF8.GetString(stack.PopByteArray()); var scriptHash = script.ToScriptHash(); var contract = _contracts.TryGet(scriptHash); if (contract == null) { contract = new Contract { Code = new Code { Script = script, ScriptHash = scriptHash, Parameters = parameters, ReturnType = returnType, Metadata = metadata }, Name = name, Version = version, Author = author, Email = email, Description = description }; _contracts.Add(scriptHash, contract); _contractsCreated.Add(scriptHash, new UInt160(engine.CurrentContext.ScriptHash)); if (contract.HasStorage) { foreach (var pair in _storages.Find(engine.CurrentContext.ScriptHash).ToArray()) { _storages.Add(new StorageKey { ScriptHash = scriptHash, Key = pair.Key.Key }, new StorageValue { Value = pair.Value.Value }); } } } stack.PushObject(contract); return(Contract_Destroy(engine)); }