這篇文章主要介紹“Neo的Compiler工作怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在Neo的Compiler工作怎么實(shí)現(xiàn)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Neo的Compiler工作怎么實(shí)現(xiàn)”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
丁青網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司自2013年創(chuàng)立以來到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
在Neo區(qū)塊鏈系統(tǒng)中,智能合約是一段代碼,可以完成一定的邏輯,最后算出合約的結(jié)果。現(xiàn)在已經(jīng)有很多具體的應(yīng)用了,感興趣的可以看一下基于Neo做的項(xiàng)目。
如果對比特幣或者智能合約不了解,不知道為什么需要有這些代碼,可以看一下比特幣的白皮書。這里簡單說一下,在比特幣系統(tǒng)中,當(dāng)一個“人”(可以看成一個公鑰)需要和另一個“人”產(chǎn)生交易的時候,這段代碼用來檢查身份,分配比特幣。具體的了解可以看一下普林斯頓的公開課
下面進(jìn)入到Neo compiler的介紹了,前面所需的基礎(chǔ)知識本文不在關(guān)注。
基本的流程
Neo可以用各種語言寫,不過現(xiàn)在主要是C#。
Neo的編譯器主要是一個翻譯器
C#代碼被C#編譯器編譯成MSIL,對MSIL的理解可以查看Standard ECMA-335 Common Language Infrastructure (CLI)
Neo compiler使用Mono.Cecil讀取IL
Neo編譯器只關(guān)注C#中的static function,所以只是C#語言的一個超級閹割版
Neo的編譯器遍歷IL,根據(jù)語義轉(zhuǎn)成Neo虛擬機(jī)的opcode
至于MSIL向neo.vm的opcode怎么轉(zhuǎn),需要仔細(xì)研究neo.vm的opcode的設(shè)計(jì)
先看一段智能合約代碼
這段代碼沒有什么實(shí)際的作用,就是返回a+b,但是main可以接受參數(shù)。
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; } }
main function IL code
IL_0000 Nop IL_0001 Ldarg_0 IL_0002 Ldarg_1 IL_0003 Add IL_0004 Stloc_0 IL_0005 Br_S IL_0007 Ldloc_0 IL_0008 Ret
這段代碼很簡單,就是讀取參數(shù)Ldarg_0,Add,返回??梢钥吹紺LR的虛擬機(jī)也是堆棧虛擬機(jī)。
關(guān)于基于棧的虛擬機(jī)和基于寄存器的虛擬機(jī)可以看一下這些文章:
棧式虛擬機(jī)和寄存器式虛擬機(jī)?
另外還有一篇概念講解的很詳細(xì)的文章虛擬機(jī)隨談(一):解釋器,樹遍歷解釋器,基于棧與基于寄存器,大雜燴
為了感性的認(rèn)識neo編譯器做了什么,我們可以看一下上面的只能合約被翻譯成了什么
hex:53-C5-6B-6C-76-6B-00-52-7A-C4-6C-76-6B-51-52-7A-C4-61-6C-76-6B-00-C3-6C-76-6B-51-C3-93-6C-76-6B-52-52-7A-C4-62-03-00-6C-76-6B-52-C3-61-6C-75-66
實(shí)際上是一串?dāng)?shù)字了,每個數(shù)字對應(yīng)一個vm的操作碼或者是數(shù)值,為了更好理解,把匯編代碼放出來
PUSH4 PUSH3 RET PUSH3 NEWARRAY TOTALSTACK FROMALSTACK DUP TOALTSTACK PUSH0 PUSH2 ROLL SETITEM FROMALSTACK DUP TOTALSTACK PUSH1 PUSH2 ROLL SETITEM NOP FROMALSTACK DUP TOTALSTACK PUSH0 PICKITEM FROMALSTACK DUP TOTALSTACK PUSH1 PICKITEM ADD FROMALSTACK DUP TOTALSTACK PUSH2 PUSH2 ROLL SETITEM JMP FROMALSTACK DUP TOTALSTACK PUSH2 PICKITEM NOP FROMALSTACK DROP ret
neo匯編的說明,可以查看這個文檔
我們可以發(fā)現(xiàn)如下情況:
MSIL的代碼很短,Neo.VM的代碼很長,這是由于虛擬機(jī)的指令和能力不同造成的。我們只需要關(guān)注,匯編代碼處理了局部變量的存貯獲取,參數(shù)的傳遞,程序的退出,還有add指令。
匯編代碼和compiler的生成算法相關(guān),需要我們?nèi)ネ瑫r研究neo的編譯器和虛擬機(jī),才能明白具體的細(xì)節(jié)。
具體每一行的含義,怎么執(zhí)行的,可以查看這個文檔
后面還會有一個講解虛擬機(jī)的文章,到那個時候在仔細(xì)說明
代碼閱讀還是很頭痛的,所以做了兩個腦圖:
compiler執(zhí)行腦圖
compiler對象關(guān)系
對象關(guān)系
ILModule是對MSIL的一個映射,包含模塊,類型,函數(shù),字段,函數(shù)中又包含返回值,參數(shù),函數(shù)體,可以點(diǎn)開腦圖一層一層查看。
Mono.Cecil是使用來讀取MSIL的,他也是對MSIL的一個映射,由于沒有文檔,只能看代碼知道他的類結(jié)構(gòu)了,這一部分在腦圖中沒有顯示,不過沒關(guān)系,compiler會把感興趣的代碼轉(zhuǎn)成ILModule
ModuleConverter用來遍歷ILModule,把里面的MSIL轉(zhuǎn)成Neo.VM的代碼,存貯在NeoModule
具體兩邊的指令如何對應(yīng),真是需要一個一個理解的,非常繁瑣,兩邊都有很多的指令??梢钥纯催@個代碼
到此,關(guān)于“Neo的Compiler工作怎么實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!