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的其它 ...
随机推荐
- hdu1242 Rescue bfs+优先队列
直接把Angle的位置作为起点,广度优先搜索即可,这题不是步数最少,而是time最少,就把以time作为衡量标准,加入优先队列,队首就是当前time最少的.遇到Angle的朋友就退出.只需15ms A ...
- Java并发编程笔记1-竞争条件&初识原子类&可重入锁
我们知道,在多线程访问一个共享变量的时候会发生安全问题. 首先看下面例子: public class Counter { private int count; public void add(){ t ...
- SQL2005查询死锁的表和具体的语句
查是哪个进程死锁了哪些表 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName fro ...
- 最短路径问题(Floyd-Warshall模板)
#include<bits/stdc++.h> using namespace std; int n; int x,y; ][]; ][]; int m,s,t; int main() { ...
- javascript模块化编程库require.js的用法
随着javascript的兴起,越来越多的公司开始将JS模块化,以增加开发的效率和减少重复编写代码的.更是为了能更加容易的维护日后的代码,因为现在的随着人们对交互效果的越来越强烈的需求,我们的JS代码 ...
- Shell脚本——cat/EOF输出多行
在某些场合,可能我们需要在脚本中生成一个临时文件,然后把该文件作为最终文件放入目录中.(可参考ntop.spec文件)这样有几个好处,其中之一就是临时文件不是唯一的,可以通过变量赋值,也可根据不同的判 ...
- ubuntu 下命令行播放器mplayer 使用详解
ubuntu 下命令行播放器mplayer 使用详解 2011-01-02 21:00:42| 分类: Linux/Unix | 标签: |字号大中小 订阅 使用 MPlayer 播放媒体文件最简 ...
- 笔记+R︱信用风险建模中神经网络激活函数与感知器简述
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 本笔记源于CDA-DSC课程,由常国珍老师主讲 ...
- windows 下安装或者卸载memcache
1.安装到系统服务中: 在doc中:执行此软件 memcached.exe -d install(如果提示错误,要找到cmd.exe用管理员身份打开) 2.卸载: 在doc中:执行此软件 memcac ...
- 如何获取Linux-gate.so.1动态库
前面"Linux应用程序Helloworld入门"已经提到在Linux下每个可执行文件都依赖于几个最为基本的动态库,其中一个就是linux-gate.so.1. 从上面ldd给出的 ...