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的其它 ...
随机推荐
- Linux的内核和权限
1.内核包括的子系统是 : 进程管理系统 . 内存管理系统 . I/O管理系统 和文件管理系统 等四个子系统. 2.Linux系统中某个可执行文件属于root并且有setid,当一个普通用户 mik ...
- mysql命令汇总
1.mysql新增.删除用户和权限分配 查看用户及权限 mysql>use mysql mysql>select * from user\G; 新增用户 mysql>insert i ...
- Jenkins+Gradle实现android开发持续集成、打包
Jenkins简介 Jenkins 是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上.同时 Jenkins 能实施监控集成中存在的错误, ...
- java代码调用使用cxf搭建的webService服务传递对象
前边成功创建好一个cxf的webServcie服务,并带了一个无参数的方法.现在进一步尝试了使用带参数的方法,分别测了用String为参数和用自定义的对象为参数. 其中,使用String为参数时和不带 ...
- HDU5919:Sequence II
题面 Vjudge Sol 给一个数列,有m个询问,每次问数列[l,r]区间中所有数的第一次出现的位置的中位数是多少,强制在线 主席树 询问区间内不同的数的个数 树上二分找到那个中位数 # inclu ...
- [COGS2701]:动态树
题面 传送门 Sol LCT维护子树和 # include <bits/stdc++.h> # define IL inline # define RG register # define ...
- [BZOJ1005] [HNOI2008] 明明的烦恼 (prufer编码)
Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N ...
- [BZOJ1588] [HNOI2002] 营业额统计 (treap)
Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额. ...
- MySQL性能调优与架构设计
1.Scale(扩展):从数据库来看,就是让数据库能够提供更强的服务能力 ScaleOut: 是通过增加处理节点的方式来提高整体处理能力 ScaleUp: 是通过增加当前处理节点的处理能力来提高整体的 ...
- less-more使用方法及区别
Less按屏(空格,page up/page down)或按行(回车)查看文件 Less按屏(空格)或按行(回车)查看文件(不能向上翻)