如何将NEL提供的thinWallet 接入NEO私链

2017年末刚开始接触区块链,目前在被 NEO 折磨。
一开始被官方文档和 NEO-GUI 搞得体无完肤(尤为是传说中的 F12),也找了各类调试工具用来搞 NeoContract,然并卵。
直到有一天发现了 NewEconoLab ,在它的 github 上有一个项目 neo-thinsdk-cs ,用 C# 实现了一个轻钱包 —— thinWallet。
这个轻钱包只作了一件事情,就是作交易,它把整个交易的流程都体现出来了,给开发者展现了明确的可视化交易拼接流程(包括Attribute、Inputs、Outputs、Script、Witness等,我曾经用 VS F11 一行一行的调试跟踪过它的源代码,全部的这些交易必须的数据都组装好,放到一个数据结构里,很是清晰)。
最重要的是分解了 UTXO 和 使得 Witness 变得可处理,以达成 NEO-GUI 达不到的操做。
此外,目前的 thinWallet ,默认接入到 Testnet,还不支持直接接入 Mainnet ,也不支持接入到 NEO 私有链 ,咱们都知道 Testnet 上的 Gas 十分珍贵,须要去申请才能有,而咱们部署合约,动不动就消耗 990 Gas 。而在本身的私有链上 Gas 就是大白菜了,随便乱玩均可以。
因此为了方便部署合约调试,今天的任务是将 thinWallet 接入到私有链中。node

一、环境准备

  • 基础要求:四台 Debian 9(其余发行版随你喜欢,单击此处查看支持的机器,建议建立一台虚拟机配好环境而后直接克隆,别忘了强制刷新 MAC 地址,要否则 IP 冲突) ,一台 Windows 10 ,.net core sdk,visual studio 2017 community,.net framework 4.7 SDK,NEO-CLI,搭私链跑共识,建钱包,拿到一亿的 NEO 币和至少 1000 个 Gas (至关于你的区块高度超过 125,这至少须要耗费31分钟),这些东西文档里都有,此处再也不赘述。
  • 克隆项目:NeoBlock-Mongo-Storage,NEO_Block_API,neo-thinsdk-cs,三个项目都是直接用 master 分支就能够了。

这里解释一下克隆下来的三个项目是什么样的关系,三个都是 .net 项目linux

  • neo-thinsdk-cs 是一整个解决方案,用 vs 2017 打开,里面有一个 WPF 项目是 thinWallet ,把它设置为启动项目,直接 CTRL+F5 就能够运行了,固然默认是接入 Testnet 。项目里面有一个《NEO智能合约开发(一)不可能完成的任务.docx》,好好看看。运行结果以下:


这里咱们按第二个按钮 ThinWallet Test 就行了,进去是这样的界面:git


  • 咱们能够看到右上角在调用一个 API for UTXO,这是一个 webapi ,由 NEO_Block_API 提供,你们能够看到这地方默认就是 Testnet ,区块高度也是 Testnet 的高度,切换网络那个按钮还没写功能。总共五个大面板都很好理解,第一个登陆方式,第二个 api 信息,第三个帐户信息(你的 utxo 将会出如今这里),第四个交易三要素,第五个决定是什么类型的交易。
  • NEO_Block_API 里面用到了 mongodb ,因此咱们的第三个项目 NeoBlock-Mongo-Storage 做为一个调度任务跑着,用来实时收集链上的交易信息存入 mongodb 中,供 NEO_Block_API 使用。
  • 顺便说明一下, vs 2017 很人性化,你直接 CTRL+F5 或者生成解决方案 ,会帮你还原依赖库的,看见黄色感叹号不要慌。若是你没法打开项目或者没法还原或者出现任何异常,相信我,必定是你的打开方式不对,或者你改了里面的东西改错了,或者环境有问题,三个项目是绝对没有错误的,我验证了好几遍了,请回头好好检查本身的环境等基础设施吧。

配置 NEO_Block_API

到这里,基础环境所有搭建完毕,thinWallet 也能够在 Testnet 上正常使用了,那么接下来就须要开始接入私链了。首先咱们要把 NEO_Block_API 的源代码增改一下,让它支持接入私链。github


咱们先看一下源代码长什么样,仍是 vs 2017 打开:web

我已经生成过解决方案了,因此依赖库都没问题了,结构很是简单。Controllers 是控制器,就是一些 web 接口在这里实现,lib 就是要用到的工具,RPC 定义了一些数据结构,再加一个 Startup.cs 和 Program.cs 文件,典型的 .net core web 项目。
咱们能够看到里边有一个 mongodbsettings.json 文件带了个黄色警告标志,说明这个文件丢失了,由于在 .gitignore 里边把它写进去了,因此 git 就把它忽略了,问题不大,咱们删掉它从新创建一个同样名字的文件就行了,咱们能够找一下在哪里用到了这个文件,你能够 CTRL+SHIFT+F 全局查找,最终发如今 mongoHelper.cs 里面有这么一段:mongodb

public mongoHelper() { var config = new ConfigurationBuilder() .AddInMemoryCollection() //将配置文件的数据加载到内存中 .SetBasePath(System.IO.Directory.GetCurrentDirectory()) //指定配置文件所在的目录 .AddJsonFile(“mongodbsettings.json”, optional: true, reloadOnChange: true) //指定加载的配置文件 .Build(); //编译成对象 mongodbConnStr_testnet = config[“mongodbConnStr_testnet”]; mongodbDatabase_testnet = config[“mongodbDatabase_testnet”]; neoCliJsonRPCUrl_testnet = config[“neoCliJsonRPCUrl_testnet”]; mongodbConnStr_mainnet = config[“mongodbConnStr_mainnet”]; mongodbDatabase_mainnet = config[“mongodbDatabase_mainnet”]; neoCliJsonRPCUrl_mainnet = config[“neoCliJsonRPCUrl_mainnet”]; mongodbConnStr_NeonOnline = config[“mongodbConnStr_NeonOnline”]; mongodbDatabase_NeonOnline = config[“mongodbDatabase_NeonOnline”]; }数据库

那么事情就简单了,咱们看到这里面一共有 8 个字段要用到,给它就是了,咱们在新建的 mongodbsettings.json 文件写上这些内容:json

{ “mongodbConnStr_testnet”: “mongodb://127.0.0.1:27017”, “mongodbDatabase_testnet”: “testnet”, “neoCliJsonRPCUrl_testnet”: “http://47.96.168.8:20332”, “mongodbConnStr_mainnet”: “mongodb://127.0.0.1:27017”, “mongodbDatabase_mainnet”: “mainnet”, “neoCliJsonRPCUrl_mainnet”: “”, “mongodbConnStr_privatenet”: “mongodb://127.0.0.1:27017”, “mongodbDatabase_privatenet”: “privatenet”, “neoCliJsonRPCUrl_privatenet”: “http://192.168.1.135:20332”, “mongodbConnStr_NeonOnline”: “mongodb://127.0.0.1:27017”, “mongodbDatabase_NeonOnline”: “neononline”}windows

mainnet 一时半会儿确定用不着,我懒得写了,testnet 仍是保留原样,加一个 privatenet 。注意 neoCliJsonRPCUrl_privatenet 这个字段的值是 http://192.168.1.135:20332 ,192.168.1.135 这台机器是四台共识机中的一台,开了 RPC ,就是:dotnet neo-cli.dll /rpc 。咱们能够用 postman 来测试一下,随便找个接口,路由是: http://192.168.1.135:20332 就用 getbestblockhash 吧:
先看一下我跑的四个共识节点,个人共识跑了挺久了,如今高度接近 7000 :
api

接下来咱们看一下 rpc 接口调用结果:



若是你没法获得相似的结果,那仍是得去多看看文档,跑跑共识。如今咱们获得了正确结果,说明私链的 RPC 彻底没有问题。此刻咱们获得了第一个须要的接口就是刚才打开的 thinWallet 右上角 RPC Node 所须要的接口地址:http://192.168.1.151:59908/api/privatenet


mongodb 你得装一下(随你 linux 仍是 windows,推荐 linux),为了演示方便,我装在了 windows 里面。装完以后就是 C:\Program Files\MongoDB\Server\3.6\bin 里面有一堆东西。其中 mongod.exe 这个是服务端,由于国际惯例有个 d 。别急着双击它,你得先创建两个文件夹:C:\data\db,否则双击就闪退了,其实你能够用 cmd 来打开,能够看到异常信息。如今你能够双击它了,结果就是一个控制台,打印了一堆日志,你能够用 mongodb 自带的可视化客户端链接一下。这边注意,咱们不须要事先建立数据库。
下面开始建立 webapi 接口,也就是新建一个控制器,在项目的 Controllers 文件夹下,新建一个类,取名:PrivatenetController.cs ,而后把随便 TestnetController.cs 或者 ** MainnetController.cs** 里面的内容所有复制粘贴到咱们的 PrivatenetController.cs 中,改一下两个地方,变成 privatenet :

[Route(“api/[controller]”)]public class PrivatenetController : Controller{ Api api = new Api(“privatenet”);

接着 mongoHelper.cs 里面改一下,把私链的东西加进去:

public string mongodbConnStr_testnet = string.Empty;
public string mongodbDatabase_testnet = string.Empty;
public string neoCliJsonRPCUrl_testnet = string.Empty;
public string mongodbConnStr_mainnet = string.Empty;
public string mongodbDatabase_mainnet = string.Empty;
public string neoCliJsonRPCUrl_mainnet = string.Empty;
public string mongodbConnStr_privatenet = string.Empty;
public string mongodbDatabase_privatenet = string.Empty;
public string neoCliJsonRPCUrl_privatenet = string.Empty;public string mongodbConnStr_NeonOnline = string.Empty;public string mongodbDatabase_NeonOnline = string.Empty;public mongoHelper() { var config = new ConfigurationBuilder() .AddInMemoryCollection() //将配置文件的数据加载到内存中 .SetBasePath(System.IO.Directory.GetCurrentDirectory()) //指定配置文件所在的目录 .AddJsonFile(“mongodbsettings.json”, optional: true, reloadOnChange: true) //指定加载的配置文件 .Build(); //编译成对象 mongodbConnStr_testnet = config[“mongodbConnStr_testnet”]; mongodbDatabase_testnet = config[“mongodbDatabase_testnet”]; neoCliJsonRPCUrl_testnet = config[“neoCliJsonRPCUrl_testnet”]; mongodbConnStr_mainnet = config[“mongodbConnStr_mainnet”]; mongodbDatabase_mainnet = config[“mongodbDatabase_mainnet”]; neoCliJsonRPCUrl_mainnet = config[“neoCliJsonRPCUrl_mainnet”]; mongodbConnStr_privatenet = config[“mongodbConnStr_privatenet”]; mongodbDatabase_privatenet = config[“mongodbDatabase_privatenet”]; neoCliJsonRPCUrl_privatenet = config[“neoCliJsonRPCUrl_privatenet”]; mongodbConnStr_NeonOnline = config[“mongodbConnStr_NeonOnline”]; mongodbDatabase_NeonOnline = config[“mongodbDatabase_NeonOnline”]; }

最后,Api.cs 里面加私链的东西:

public Api(string node) { netnode = node; switch (netnode) { case “testnet”: mongodbConnStr = mh.mongodbConnStr_testnet; mongodbDatabase = mh.mongodbDatabase_testnet; neoCliJsonRPCUrl = mh.neoCliJsonRPCUrl_testnet; break; case “mainnet”: mongodbConnStr = mh.mongodbConnStr_mainnet; mongodbDatabase = mh.mongodbDatabase_mainnet; neoCliJsonRPCUrl = mh.neoCliJsonRPCUrl_mainnet; break; case “privatenet”: mongodbConnStr = mh.mongodbConnStr_privatenet; mongodbDatabase = mh.mongodbDatabase_privatenet; neoCliJsonRPCUrl = mh.neoCliJsonRPCUrl_privatenet; break; } }

打完收工咱们来试一下,CTRL+F5,咱们能够看到内置的 IIS Express 被启动了,能够访问这个地址:
http://localhost:59908/api/privatenet
显示的结果是:

{"jsonrpc":"2.0","id":0,"error":{"code":-100,"message":"Parameter Error","data":"Value cannot be null.\r\nParameter name: s"}}


那说明 webapi 自己已经没问题了,咱们看到用的是 localhost ,若是想局域网都能用的话咱们能够改一下 .vs\config\applicationhost.config 里面的配置再运行,或者咱们用典型的 .net core 方法(我采用这种),就是在 Program.cs 里面加一点料:.UseUrls("http://*:59908"),详细以下,这是容许局域网 ip 访问的第一步:

public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls(“http://*:59908”) .Build();

第二步咱们改一下启动方式,先从新生成解决方案,而后把 appsettings.jsonmongodbsettings.json 两个文件复制到 bin\Debug\netcoreapp2.0 里面去,关掉刚才启动的 IIS Express,而后咱们以管理员身份打开 cmd ,cd 到你的 bin\Debug\netcoreapp2.0 文件夹里面,而后 dotnet NEO_Block_API.dll 就行了,结果以下:

你能够去局域网的其余机器上用 postman 访问一下,没啥问题,用 getblockcount 接口吧,路由是这个: http://192.168.1.151:59908/api/privatenet ,文档在这:http://www.xiaoyaoji.cn/share/1H0gjTDtfk/1GzzPWtpFG 。
我在这台 windows 10 上操做的,IP 是 192.168.1.151 ,因此咱们获得了第二个想要的接口地址,就是 API for UTXO 的 api 地址:http://192.168.1.151:59908/api/privatenet

thinWallet 接入私链

如今咱们来观察一下 thinWallet 的代码结构:

很显然,上面三个项目都是通用库,第三个是用户端,并且咱们只须要改一个地方就能够了,双击打开 Window_thinwallet.xaml,WPF 的界面文件,打开是这样的:


接下来咱们要把它接入私链,其实就该两个接口地址,就在这个界面代码里面,thinWallet 对这两个地址目前是写死在界面上的,咱们在界面代码里面查找一下 CTRL+F ,输入 47.96 就能找到了,一共两个地方,分别对应的填进去:



打完收工咱们来访问一下,CTRL+F5:

咱们发现一个很诡异的数字,下面那个直接访问 neo rpc 的已经彻底正常了,可是上面那个访问 webapi 的竟然是这么个诡异的数字,那么碰到问题,咱们首先得想到的事情只有一件,就是 F5,首先咱们先打开 Window_thinwallet.xaml 这个文件的后台文件,就是 Window_thinwallet.xaml.cs ,咱们观察一下里面的代码,发现有一个异步更新界面的地方:



再来看一下这个 api_getHeight 是怎么实现的,F12 过去:



真相在这里,请求了 webapi 的一个 getblockcount 的接口,那么如今来看一下 NEO_Block_API 项目对 getblockcount 是怎么实现的:


这时候就发现了,这里竟然在调用 mongodb 的数据,咱们回想一下,彷佛没有任何操做 mongodb 的地方,也就是说没有任何数据,那么咱们能够猜到,getblockcount 接口返回了一个 0 ,并且在咱们的 Window_thinwallet.xaml.cs 文件异步更新界面的地方,最后 var height = ulong.Parse(json[0].AsDict()["blockcount"].ToString()) - 1; 来了这么一句,很明确了,无符号长整型,减了个 1 ,致使变成了那个数字,如今来 F5 证实一下,断点打在 api_getHeight 这个方法的最后一句 return 的代码上:


其中 result 是请求结果,就是 0 ,已经说明了一切。那还差什么呢,想一想咱们好像漏了一个项目,没错还有最后一个调度任务项目没配置好。

NeoBlock-Mongo-Storage 开启对私链的任务调度

老样子观察代码:

很简单,一个入口,两个数据接口,一个工具,没了。
咱们能够发如今 Program.cs 里面有这么一段:

var config = new ConfigurationBuilder() .AddInMemoryCollection() //将配置文件的数据加载到内存中 .SetBasePath(System.IO.Directory.GetCurrentDirectory()) //指定配置文件所在的目录 .AddJsonFile(“appsettings.json”, optional: true, reloadOnChange: true) //指定加载的配置文件 .Build(); //编译成对象 mongodbConnStr = config[“mongodbConnStr”]; mongodbDatabase = config[“mongodbDatabase”]; NeoCliJsonRPCUrl = config[“NeoCliJsonRPCUrl”]; sleepTime = int.Parse(config[“sleepTime”]);if (int.Parse(config[“utxoIsSleep”]) == 1) { utxoIsSleep = true; }

很简单了,加个文件,appsettings.json :

{ “mongodbConnStr”: “mongodb://127.0.0.1:27017”, “mongodbDatabase”: “privatenet”, “NeoCliJsonRPCUrl”: “http://192.168.1.135:20332”, “sleepTime”: “0”, “utxoIsSleep”: “0”}

一样道理,从新生成解决方案,把这个 json 文件复制到 bin\Debug\netcoreapp2.0 里面去,而后管理员身份打开 cmd ,而后 cd 进去,而后 dotnet NeoBlockMongoStorage.dll ,看下结果:

这个狂暴的气息,而后咱们开一下 thinWallet,看下结果:

这个高度正在快速地向最高高度同步过去,同步完成以后,咱们就完成了 thinWallet 接入私链的全部步骤,你的 thinWallet 就能够在私链中随便玩了。
同步完成以后,咱们最好把 NeoBlock-Mongo-Storage 项目的 appsettings.json 改一下,把 sleepTime 从 0 改成 2000,utxoIsSleep 从 0 改成 1,由于调度是个无限循环,若是不让它睡一会,就会一直浪费你的 cpu ,同步完成了,没那么多数据要写了,让它休息休息,这样形成的效果是,上面那个高度永远比下面那个高度更新慢半拍。单位是毫秒。本身随便调节。

{ “mongodbConnStr”: “mongodb://127.0.0.1:27017”, “mongodbDatabase”: “privatenet”, “NeoCliJsonRPCUrl”: “http://192.168.1.135:20332”, “sleepTime”: “2000”, “utxoIsSleep”: “1”}

而后对着这两篇质量文档去玩吧。
不可能任务一
不可能任务二

本文由NEL内容激励计划支持

Discord:discord.io/neo
Telegram英文群:t.me/NEO_EN
Telegram中文群:t.me/NEO_Chinese开发者交流QQ群:795681763
相关文章
相关标签/搜索