千家信息网

Neo虚拟机怎么实现

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇"Neo虚拟机怎么实现"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Neo虚拟机
千家信息网最后更新 2025年02月02日Neo虚拟机怎么实现

这篇"Neo虚拟机怎么实现"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Neo虚拟机怎么实现"文章吧。

框架

虚拟机所处的位置

在框架图中,我们可以看出Virtual Machine有以下作用

  1. 读取Opcode(smart contract),在Execution Engine中执行

  2. Execution Engine可以进行逻辑运算

  3. Interop Service可以调用External Data

  4. 系统调用(OP_SYSCALL)可以访问区块链账本的信息

下面我们先看一下虚拟机如何读取Opcode。

VM对象关系

关键的几个对象

  1. Execution Engine:执行引擎

  2. Execution Context:执行上下文

  3. Stack Item:堆栈的一条数据

  4. Crypto:C#的加密库

执行引擎
  1. IScriptTable里面存贮了AppCall命令可以调用的其他contract的代码,这一块需要研究一下区块链的实现,这个以后再仔细研究。

  2. InteropService专门用来响应SYSCALL,具体有哪些是系统调用,用来干什么的,后面通过例子再来说明。

  3. InvocationStack是调用栈,传入参数,调用其他合约都会有一个新的调用栈

  4. EvaluationStack是计算栈,用来执行操作

  5. AltStack是备用栈,计算栈算出的中间结果可以保存在备用栈

执行上下文

每个变量都蛮好理解的,重点是下面看看怎么用的。

vm代码执行流程

  1. 构造,此时可以传入script container,script table,后面我们看看在区块链上这些都是从哪里来的,这里只专注于vm的执行流程,暂且不深究了。
    2.加载.avm,avm是编译器编译出来的一串数字,通过engine.LoadScript可以加载。

  2. execute开始执行, 下面看一下代码

   public void Execute()        {            State &= ~VMState.BREAK;            while (!State.HasFlag(VMState.HALT) && !State.HasFlag(VMState.FAULT) && !State.HasFlag(VMState.BREAK))                StepInto();        }
 public void StepInto()        {            if (InvocationStack.Count == 0) State |= VMState.HALT;            if (State.HasFlag(VMState.HALT) || State.HasFlag(VMState.FAULT)) return;            OpCode opcode = CurrentContext.InstructionPointer >= CurrentContext.Script.Length ? OpCode.RET : (OpCode)CurrentContext.OpReader.ReadByte();            try            {                ExecuteOp(opcode, CurrentContext);            }            catch            {                State |= VMState.FAULT;            }        }

看一下这行代码,OpCode opcode = CurrentContext.InstructionPointer >= CurrentContext.Script.Length ? OpCode.RET : (OpCode)CurrentContext.OpReader.ReadByte();

  1. 代码执行完了以后,插入OpCode.RET

  2. 如果不是RET,则read一个字节的opcode

ExecuteOp函数就是具体的执行OpCode的语义,我们通过一个例子来说明

具体的一个例子

还是上次的那个代码

using Neo.SmartContract.Framework;using Neo.SmartContract.Framework.Services.Neo;public class Sum : SmartContract{    public static int Main(int a, int b)    {        return a + b;    }}

测试虚拟机的代码

using System;using System.IO;using System.Linq;using Neo;using Neo.VM;using Neo.Cryptography;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            var engine = new ExecutionEngine(null, Crypto.Default);            engine.LoadScript(File.ReadAllBytes(@"C:\……\Test1.avm"));             using (ScriptBuilder sb = new ScriptBuilder())            {                sb.EmitPush(4); // 对应形参 b                sb.EmitPush(3); // 对应形参 a                engine.LoadScript(sb.ToArray());            }            engine.Execute(); // 开始执行            var result = engine.EvaluationStack.Peek().GetBigInteger(); // 在这里设置返回值            Console.WriteLine($"执行结果 {result}");            Console.ReadLine();        }    }}

以上就是关于"Neo虚拟机怎么实现"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

0