溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Neo虛擬機(jī)怎么實現(xiàn)

發(fā)布時間:2022-01-11 16:07:46 來源:億速云 閱讀:97 作者:iii 欄目:互聯(lián)網(wǎng)科技

這篇“Neo虛擬機(jī)怎么實現(xiàn)”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Neo虛擬機(jī)怎么實現(xiàn)”文章吧。

框架

虛擬機(jī)所處的位置

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

  1. 讀取Opcode(smart contract),在Execution Engine中執(zhí)行

  2. Execution Engine可以進(jìn)行邏輯運(yùn)算

  3. Interop Service可以調(diào)用External Data

  4. 系統(tǒng)調(diào)用(OP_SYSCALL)可以訪問區(qū)塊鏈賬本的信息

下面我們先看一下虛擬機(jī)如何讀取Opcode。

VM對象關(guān)系

關(guān)鍵的幾個對象

  1. Execution Engine:執(zhí)行引擎

  2. Execution Context:執(zhí)行上下文

  3. Stack Item:堆棧的一條數(shù)據(jù)

  4. Crypto:C#的加密庫

執(zhí)行引擎
  1. IScriptTable里面存貯了AppCall命令可以調(diào)用的其他contract的代碼,這一塊需要研究一下區(qū)塊鏈的實現(xiàn),這個以后再仔細(xì)研究。

  2. InteropService專門用來響應(yīng)SYSCALL,具體有哪些是系統(tǒng)調(diào)用,用來干什么的,后面通過例子再來說明。

  3. InvocationStack是調(diào)用棧,傳入?yún)?shù),調(diào)用其他合約都會有一個新的調(diào)用棧

  4. EvaluationStack是計算棧,用來執(zhí)行操作

  5. AltStack是備用棧,計算棧算出的中間結(jié)果可以保存在備用棧

執(zhí)行上下文 

每個變量都蠻好理解的,重點是下面看看怎么用的。

vm代碼執(zhí)行流程

  1. 構(gòu)造,此時可以傳入script container,script table,后面我們看看在區(qū)塊鏈上這些都是從哪里來的,這里只專注于vm的執(zhí)行流程,暫且不深究了。
    2.加載.avm,avm是編譯器編譯出來的一串?dāng)?shù)字,通過engine.LoadScript可以加載。

  2. execute開始執(zhí)行, 下面看一下代碼

   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. 代碼執(zhí)行完了以后,插入OpCode.RET

  2. 如果不是RET,則read一個字節(jié)的opcode

ExecuteOp函數(shù)就是具體的執(zhí)行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;
    }
}

測試虛擬機(jī)的代碼

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); // 對應(yīng)形參 b
                sb.EmitPush(3); // 對應(yīng)形參 a
                engine.LoadScript(sb.ToArray());
            }

            engine.Execute(); // 開始執(zhí)行

            var result = engine.EvaluationStack.Peek().GetBigInteger(); // 在這里設(shè)置返回值
            Console.WriteLine($"執(zhí)行結(jié)果 {result}");
            Console.ReadLine();
        }
    }
}

以上就是關(guān)于“Neo虛擬機(jī)怎么實現(xiàn)”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

neo
AI