一、啰嗦两句

第一节的时候咱说了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. SpringCloud入门1-服务注册与发现(Eureka)

    前言 Oracle转让Java,各种动态语言的曝光率上升,Java工程师的未来在哪里?我觉得Spring Cloud让未来有无限可能.拖了半年之久的Spring Cloud学习就从今天开始了.中文教材 ...

  2. (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]一行js代码的原理分析

    再说这行代码之前,咱们先来预习一下知识. 我们都知道计算机操作系统分为32位或者64位.那么这个32位或64位指的是什么意思呢?其实,要想解释它并不难,其实这就是计算机处理数据的机制,32位表示计算机 ...

  3. Linux socket网络编程基础 tcp和udp

    Socket TCP网络通信编程 首先,服务器端需要做以下准备工作: (1)调用socket()函数.建立socket对象,指定通信协议. (2)调用bind()函数.将创建的socket对象与当前主 ...

  4. Spark源码编译(未完待续)

    在这里我们不需要搭建独立的Spark集群,利用Yarn Client调用Hadoop集群的计算资源. Spark源码编译生成配置包: 解压源码,在根去根目录下执行以下命令(sbt编译我没尝试) ./m ...

  5. HashMap并发导致死循环 CurrentHashMap

    为何出现死循环简要说明 HashMap闭环的详细原因 cocurrentHashMap的底层机制 为何出现死循环简要说明 HashMap是非线程安全的,在并发场景中如果不保持足够的同步,就有可能在执行 ...

  6. 304和浏览器http缓存

    浏览器虽然发现了本地有该资源的缓存,但是不确定是否是最新的,于是想服务器询问,若服务器认为浏览器的缓存版本还可用,那么便会返回304. 浏览器缓存分为强缓存和协商缓存. 1.浏览器请求某资源,通过he ...

  7. am335x在ubuntu下使用StarterWare编写裸机程序并在CCS中用Jlink调试

    StarterWare在AM335X上的烧录运行 步骤:1.下载安装StarterWare,我们团购的SK需要02.00.00.07版本.最近外网访问慢,我上传到论坛.2.找一张miniSD卡,不需要 ...

  8. web开发性能优化---分布式篇

    1.分布式架构-独立站点开发 模块化结构化开发,实现多资源分站点,数据分库,为后期实现分布式部署做准备,主要分为以下几部分: web站点: 1.web前端站点 2.图片.文件资源站点 3.管理端站点4 ...

  9. JavaScript小括号、中括号、大括号的多义性

    语义1,函数声明时参数表 func(arg1,arg2){ // ... } 语义2,和一些语句联合使用以达到某些限定作用 // 和for in一起使用 for(var a in obj){ // . ...

  10. 异常-----freemarker.template.TemplateException

    一,案例一 1.1.错误描述 五月 30, 2014 11:33:57 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Templ ...