一、啰嗦两句

第一节的时候咱说了C#编译完了之后,就该NEO的编译器搞事情了。我们完全可以按这个节奏搞,手动用NEO的编译器neon编译dll文件生成指令码文件.avm。但是NEO团队给我们写智能合约提供了个插件,咱们就先看看这玩意怎么玩,然后简单的介绍一下NEO的编译器源码。

二、NeoContractPlugin

咱在VS里【工具】-》【扩展和更新】里搜下NeoContractPlugin,安装这个模板。

完事新建项目时候就能新建一个NeoContract的项目了

创建完之后,就是这样滴。

好,按NEO的模板创建出来的东东,多了build.tasks和Neo.ConvertTask.dll这俩文件,除此之外,在项目文件里还导入了一个project和AfterBuild之后的任务。这里做的事情,其实就是告诉项目编译完了之后跑一个ConvertTask的任务,看到项目里的Neo.ConvertTask.dll了么,后面我们介绍它。

ConvertTask这个任务是干嘛的,我们来看一眼源码,源码在项目neo-devpack-dotnet中

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Diagnostics; namespace Neo
{
/// <summary>
/// this class generate config / xml file by template
/// </summary>
public class ConvertTask : Task
{
[Required]
public ITaskItem DataSource { get; set; } /// <summary>
/// execute replace logic
/// </summary>
/// <returns>ture successful, false failure</returns>
public override bool Execute()
{
var srcdll = this.DataSource.ToString();
string dllname = System.IO.Path.GetFileName(srcdll);
ProcessStartInfo pinfo = new ProcessStartInfo();
pinfo.FileName = "cmd.exe";
pinfo.WorkingDirectory = System.IO.Path.GetDirectoryName(srcdll);
pinfo.UseShellExecute = false;
pinfo.RedirectStandardInput = true;
pinfo.RedirectStandardOutput = true;
pinfo.CreateNoWindow = true;
pinfo.StandardOutputEncoding = System.Text.Encoding.UTF8; Process p = Process.Start(pinfo);
p.StandardInput.AutoFlush = true;
p.StandardInput.WriteLine("neon " + dllname);
p.StandardInput.WriteLine("exit"); //前四行后一行不要
string lastline = null;
int count = ;
bool bSucc = false;
while (p.StandardOutput.EndOfStream == false)
{
var line = p.StandardOutput.ReadLine();
count++;
if (count <= ) continue; if (lastline != null && lastline.Length > )
{
if (lastline[] == '<')
{
if (lastline.IndexOf("<WARN>") == )
{
this.Log.LogWarning(lastline.Substring());
lastline = line;
continue;
}
else if (lastline.IndexOf("<ERR>") == )
{
this.Log.LogError(lastline.Substring());
lastline = line;
continue;
}
else if (lastline.IndexOf("<WARN|") == )
{
var l = lastline.Substring();
var ine = lastline.IndexOf(">");
var text = lastline.Substring(ine + );
var file = lastline.Substring(, ine - );
var lines = file.Split(new char[] { '(', ')' });
int _line = ;
if (lines.Length > )
{
int.TryParse(lines[], out _line);
}
this.Log.LogWarning("", "", "", lines[], _line, , , , text);
lastline = line;
continue;
}
else if (lastline.IndexOf("<ERR|") == )
{
var l = lastline.Substring();
var ine = lastline.IndexOf(">");
var text = lastline.Substring(ine + );
var file = lastline.Substring(, ine - );
var lines = file.Split(new char[] { '(', ')' });
int _line = ;
if (lines.Length > )
{
int.TryParse(lines[], out _line);
}
this.Log.LogWarning("", "", "", lines[], _line, , , , text);
lastline = line;
continue;
}
}
if (lastline.IndexOf("SUCC") == )
{
bSucc = true;
}
this.Log.LogMessageFromText(lastline, MessageImportance.High); } lastline = line;
//lines.Add(line);
} //this.Log.LogMessageFromText(lastline, MessageImportance.High); p.WaitForExit();
return bSucc;
}
} }

ConvertTask

好,先不管细节,就是起了一个cmd进程跑neon,其实就是帮我们调了一下NEO的编译器,妥了,那咱们就看看编译器搞了些撒事情吧。

三、NEO编译器

这一部分最好还是看看源码,我就简单介绍一下。这里有三个类比较关键:

1. ModuleDefination: 这个类是用的库Mono.cecil,这个库可以查看或者修改IL文件,这里是官方地址:http://www.mono-project.com/docs/tools+libraries/libraries/Mono.Cecil/

2. ILModule: 这个是编译器里定义的一个类,类的主要方法就是LoadModule,一看就明白了,其实现正是使用ModuleDefination加载并读取IL文件,将其转化为ILModule。这里其实还是用一种数据类型记录的智能合约代码的元数据信息,方法、字段、属性等的描述信息,可以理解成我们用反射操作类型。

3. NeoModule: 这个是另外一个数据结构,通过一个ModuleConverter的类从ILModule逐条指令转化进NeoModule,这个结构里保持了一个有序字典,value就是转化后的指令码,也就是我们说的OpCode。之后就是把这个NeoModule Build成字节数组写入.avm文件。

理解这三个类的含义就明白编译器的流程了。这里的难点是指令码,非常多,所以需要详细了解的自己看下源码吧。

四、小结

好了,今天就简单讲了一下NEO的智能合约模板背后都搞了啥,以及NEO编译器大概怎么编译的。通过前面几讲,大伙儿应该从工程的角度对NEO的智能合约这部分有些了解了。

后续,准备从NEO的命令行全节点Neo-cli入手讲讲NEO的内部机制。

NEO从入门到开窗(3) - NEO编译器的更多相关文章

  1. NEO从入门到开窗(4) - NEO CLI

    一.唠叨两句 首先,我们都知道区块链是去中心化的,其中节点都是对等节点,每个节点都几乎有完整的区块链特性,CLI就是NEO的一个命令行对等节点,当然也有GUI这个项目,图形化的NEO节点.节点之间需要 ...

  2. NEO从入门到开窗(2) - 智能合约的面相

    一.啰嗦两句 昨天讲了智能合约的一生,那丫长啥样啊?今儿我就跟各位唠叨唠叨. 二.一个简单的智能合约 下面这段就是NEO实例源码里的一个,干撒用的?聪明的你一眼儿就看出来了吧,就是一个所谓域名合约的增 ...

  3. NEO从入门到开窗(1) - 一个智能合约的诞生

    一.啰嗦两句 最近一直都在研究区块链,BitCoin,Etherenum, Hyper Ledger Fabric还有今天的主角小蚂蚁,当然出名以后改了一个艺名叫NEO.区块链大部分都是用Golang ...

  4. [转]NEO与以太坊:为什么NEO可能是2018年最强的加密货币

    本文转自:https://baijiahao.baidu.com/s?id=1591291802129464257&wfr=spider&for=pc NEO,它可以与以太坊竞争吗?N ...

  5. [WebGL入门]十一,着色器编译器和连接器

    注意:文章翻译http://wgld.org/,原作者杉本雅広(doxas).文章中假设有我的额外说明.我会加上[lufy:].另外.鄙人webgl研究还不够深入.一些专业词语,假设翻译有误.欢迎大家 ...

  6. NEO

    平台: Windows 类型: 虚拟机镜像 软件包: .net core neo application server basic software blockchain neo open sourc ...

  7. C#区块链零基础入门,学习路线图 转

    C#区块链零基础入门,学习路线图 一.1分钟短视频<区块链100问>了解区块链基本概念 http://tech.sina.com.cn/zt_d/blockchain_100/ 二.C#区 ...

  8. SpringBoot入门:Spring Data JPA 和 JPA(理论)

    参考链接: Spring Data JPA - Reference Documentation Spring Data JPA--参考文档 中文版 纯洁的微笑:http://www.ityouknow ...

  9. spring boot(二):web综合开发

    上篇文章介绍了Spring boot初级教程:spring boot(一):入门篇,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续为大家介绍spring boot的其它 ...

随机推荐

  1. 前端js,后台python实现RSA非对称加密

    先熟悉使用 在后台使用RSA实现秘钥生产,加密,解密; # -*- encoding:utf-8 -*- import base64 from Crypto import Random from Cr ...

  2. 安装CentOS7

    安装环境:虚拟机*1 使用软件:CentOS7镜像*1 安装过程: 虚拟机配置步骤(主要部分): 1.安装为Linux:CentOS 64位 2.分配1G内存(若需求大可根据实际情况分配) 3.分配4 ...

  3. java 集合框架(四)Set

    一.概述 Set是一种没有重复元素的集合,它所有的方法都是直接继承自Collection接口,并且添加了一个对重复元素的限制.Set要求强化了equals和hashCode两个方法,以使Set集合可以 ...

  4. dm642的中断定时器

    TIMER_Handle TimerHandle0; void timer1() { ////////////定时器///////////////////////  TimerHandle0 = TI ...

  5. CWnd *和HWnd转换

      CWnd *和HWnd转换 CWnd*得到HWnd CWnd    wnd;   HWND    hWnd; hWnd    =    wnd.m_hWnd;           //    or ...

  6. JavaScript获取屏幕和页面的宽度和高度

    JavaScript获取屏幕和页面的宽度和高度 1.设计源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...

  7. Error: expected expression, got '}'

    1.错误描述 Error: expected expression, got '}' .globalEval/<@http://localhost:8080/Sys/resource/globa ...

  8. 将泛类型集合List类转换成DataTable

    /// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list&q ...

  9. 安装使用pyclone进行克隆演化推断

    pyclone介绍   可以根据多个样品突变的allele frequency 和 copy number,推断出有该突变的细胞克隆所占的比例(cellular prevalence)在不同样品间的变 ...

  10. 异常-----java.sql.SQLException:ORA-01861:文字和格式字符串不匹配

    1.错误描述 java.sql.SQLException:ORA-01861:文字和格式字符串不匹配 2.错误原因 字段名为statis_date在数据库中存储的数据类型是Date,而在Java中拼接 ...