NEO从入门到开窗(3) - NEO编译器
一、啰嗦两句
第一节的时候咱说了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编译器的更多相关文章
- NEO从入门到开窗(4) - NEO CLI
一.唠叨两句 首先,我们都知道区块链是去中心化的,其中节点都是对等节点,每个节点都几乎有完整的区块链特性,CLI就是NEO的一个命令行对等节点,当然也有GUI这个项目,图形化的NEO节点.节点之间需要 ...
- NEO从入门到开窗(2) - 智能合约的面相
一.啰嗦两句 昨天讲了智能合约的一生,那丫长啥样啊?今儿我就跟各位唠叨唠叨. 二.一个简单的智能合约 下面这段就是NEO实例源码里的一个,干撒用的?聪明的你一眼儿就看出来了吧,就是一个所谓域名合约的增 ...
- NEO从入门到开窗(1) - 一个智能合约的诞生
一.啰嗦两句 最近一直都在研究区块链,BitCoin,Etherenum, Hyper Ledger Fabric还有今天的主角小蚂蚁,当然出名以后改了一个艺名叫NEO.区块链大部分都是用Golang ...
- [转]NEO与以太坊:为什么NEO可能是2018年最强的加密货币
本文转自:https://baijiahao.baidu.com/s?id=1591291802129464257&wfr=spider&for=pc NEO,它可以与以太坊竞争吗?N ...
- [WebGL入门]十一,着色器编译器和连接器
注意:文章翻译http://wgld.org/,原作者杉本雅広(doxas).文章中假设有我的额外说明.我会加上[lufy:].另外.鄙人webgl研究还不够深入.一些专业词语,假设翻译有误.欢迎大家 ...
- NEO
平台: Windows 类型: 虚拟机镜像 软件包: .net core neo application server basic software blockchain neo open sourc ...
- C#区块链零基础入门,学习路线图 转
C#区块链零基础入门,学习路线图 一.1分钟短视频<区块链100问>了解区块链基本概念 http://tech.sina.com.cn/zt_d/blockchain_100/ 二.C#区 ...
- SpringBoot入门:Spring Data JPA 和 JPA(理论)
参考链接: Spring Data JPA - Reference Documentation Spring Data JPA--参考文档 中文版 纯洁的微笑:http://www.ityouknow ...
- spring boot(二):web综合开发
上篇文章介绍了Spring boot初级教程:spring boot(一):入门篇,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续为大家介绍spring boot的其它 ...
随机推荐
- Spring data mongodb ObjectId ,根据id日期条件查询,省略@CreatedDate注解
先看看ObjectId 的json 结构,非常丰富,这里有唯一机器码,日期,时间戳等等,所以强烈建议ID 使用 ObjectId 类型,并且自带索引 Spring data mongodb 注解 @C ...
- Spring / Hibernate 应用性能调优
来源:ImportNew - 陈晓舜 对大部分典型的Spring/Hibernate企业应用来说,应用的性能大部分由持久层的性能决定. 这篇文章会重温一下怎么去确认我们的应用是否是”数据库依赖(dat ...
- flask中jinjia2模板引擎详解3
接上文 模板继承 Jinji2中的模板继承是jinjia2比较强大的功能之一. 模板继承可以定义一个父级公共的模板,把同一类的模板框架定义出来共享. 这样做一方面可以提取共享代码,减少代码冗余和重复的 ...
- H3C路由交换常用命令
1.查看Linux下查看端口状态 root@root:~# netstat -an|grep -E "6002|6003" 2.H3C交换机显示当前配置 [H3C]display ...
- 在DirectShow的视频图像上叠加线条和文字
在DirectShow的视频图像上叠加线条和文字 最近一直在从事工业测量方面的开发工作,难免会用到各种各样的相机,其中支持DX的USB相机开发起来比较方便,由于工作需要经常要在视频图像上叠加线条和文字 ...
- Ubuntu12.04LTS安装好后是空白桌面的解决步骤(更新显卡驱动)
安装完毕启动后,明显慢的要死,登陆后竟然是一个空白的桌面环境,Ctrl+Alt+T 根本没有任何反应.唯一的反应就是右键能够创建文件和文档. 同时打开的窗口没有最大化,最小化及关闭按钮. GOOGLE ...
- Filter的注册2
既然Filter是一种COM组件,使用前就必须先注册.Filter的注册程序为regsvr32.exe (位于操作系统目录的system32子目录下).假设现在有一个Filter文件,它的完整路径为C ...
- hdu5860 Death Sequence
这题一开始写的线段数是从中间开始查找 k个 导致是nlogn 每次查找应该都是从头找每次找的个数不同就好了 还有一种递推的写法我放下面了 #include<bits/stdc++.h> u ...
- jQuery框架-1.基础知识
jQuery简介 jQuery,顾名思义是JavaScript和查询(Query),jQuery是免费.开源的.它可以简化查询DOM对象.处理事件.制作动画.处理Ajax交互过程且兼容多浏览器的jav ...
- select选中获取索引三种写法
$('#someId').prop('selectedIndex'); $('option:selected', '#someId').index(); $('#someId option').ind ...