這篇“Neo虛擬機怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Neo虛擬機怎么實現”文章吧。
虛擬機所處的位置
在框架圖中,我們可以看出Virtual Machine有以下作用
讀取Opcode(smart contract),在Execution Engine中執行
Execution Engine可以進行邏輯運算
Interop Service可以調用External Data
系統調用(OP_SYSCALL)可以訪問區塊鏈賬本的信息
下面我們先看一下虛擬機如何讀取Opcode。
關鍵的幾個對象
Execution Engine:執行引擎
Execution Context:執行上下文
Stack Item:堆棧的一條數據
Crypto:C#的加密庫
IScriptTable里面存貯了AppCall命令可以調用的其他contract的代碼,這一塊需要研究一下區塊鏈的實現,這個以后再仔細研究。
InteropService專門用來響應SYSCALL,具體有哪些是系統調用,用來干什么的,后面通過例子再來說明。
InvocationStack是調用棧,傳入參數,調用其他合約都會有一個新的調用棧
EvaluationStack是計算棧,用來執行操作
AltStack是備用棧,計算棧算出的中間結果可以保存在備用棧
執行上下文
每個變量都蠻好理解的,重點是下面看看怎么用的。
vm代碼執行流程
構造,此時可以傳入script container,script table,后面我們看看在區塊鏈上這些都是從哪里來的,這里只專注于vm的執行流程,暫且不深究了。
2.加載.avm,avm是編譯器編譯出來的一串數字,通過engine.LoadScript可以加載。
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();
代碼執行完了以后,插入OpCode.RET
如果不是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虛擬機怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。