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
這裏解釋一下克隆下來的三個項目是什麼樣的關係,三個都是 .net 項目linux
這裏咱們按第二個按鈕 ThinWallet Test 就行了,進去是這樣的界面:git
到這裏,基礎環境所有搭建完畢,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.json
和 mongodbsettings.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 的代碼結構:
很顯然,上面三個項目都是通用庫,第三個是用戶端,並且咱們只須要改一個地方就能夠了,雙擊打開 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 的代碼上:
老樣子觀察代碼:
很簡單,一個入口,兩個數據接口,一個工具,沒了。
咱們能夠發如今 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 |