今天就來開發一個C# 版的簡易錢包 先回顧之前的內容html
c#實戰開發:以太坊Geth 命令發佈智能合約 (五)git
c#實戰開發:以太坊Geth 經常使用命令 (四)github
c#實戰開發:以太坊錢包快速同步區塊和錢包卡死解決方案 (三)web
先看一下可視化錢包有哪些功能呢?api
那這個錢包得有什麼功能呢? 瀏覽器
1.查看用戶websocket
2.查看交易記錄異步
3.轉帳
4.發佈智能合約
5.代幣轉帳
6.代幣查詢
7.實時同步區塊對比
8.智能填寫手續費
首先新建一個項目 導入以太坊.net實現類庫
Install-Package Nethereum.Geth -Version 2.5.1
安裝完
初始對象 記住初始化鏈接記得把Geth客戶端打開創建鏈接
private const string url = "http://localhost:8546/"; private static Web3Geth Web3 = new Web3Geth(url);
這個url端口號就是你的公鏈端口 能夠不填直接默認
private static Web3Geth Web3 = new Web3Geth();
接下來咱們來一一實現功能 能夠先用私鏈測試結果 不會的看前面的文章導讀
1.用戶操做
首先新增一個用戶
string passPhrase = "a123456"; var Result = await Web3.Personal.NewAccount.SendRequestAsync(passPhrase);
傳入用戶密碼 等待異步結果返回 用戶公鑰
用戶新增好了
查詢餘額 把剛剛新建的用戶地址傳入
var Result = await Web3.Eth.GetBalance.SendRequestAsync(address);
若是不知道命令能夠看
以太坊API中文文檔:http://web3.tryblockchain.org/Web3.js-api-refrence.html
2.以太坊操做
首先考慮錢包的穩定性和同步的差別性 要讓轉帳有效 就要多準備幾個客戶端 防客戶端死掉 先模擬三個客戶端IP
private const string url1 = "http://localhost:8545/"; private const string url2 = "http://localhost:8546/"; private const string url3 = "http://localhost:8547/";
private static Web3Geth 1Web3 = new Web3Geth(url1);
private static Web3Geth 2Web3 = new Web3Geth(url2);
private static Web3Geth 3Web3 = new Web3Geth(url3);
怎麼知道哪一個客戶端死掉了呢?
var BlockNumber =await Web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();
獲取的當前客戶端區塊同步高度 0就直接切換 初始化對象繼續查 好比在查到5400 可是以太坊瀏覽器上同步區塊是5800 這時你的客戶端同步差別性 區塊太別太大? 手續費輸入多少?
看以太坊的區塊鏈也不是及時同步 怎麼辦呢?
好在發現了一個區塊鏈同步網站
https://ethstats.net/
能夠看到最新的區塊高度 和交易手續費 每秒都在刷 底下各大節點同步最新的數據 把這些數據拿到就能夠知道個人客戶端區塊和最高區塊的差距 已經當前最新手續費 這樣能夠告訴要轉帳的人 最合理的手續費輸入值。
咱們能夠用 HttpClient 可是創建鏈接以後數據相應太慢根本不能作到實時推送給用戶最新的區塊記錄和手續費 。
不過認真觀察了一下應該是用的websocket 因此
地址被我找到了 這樣就不用爬了 用他的地址寫成exe客戶端創建鏈接
var ws = new WebSocket("wss://ethstats.net")
可是發現數據不許 什麼狀況 發現後面有一個參數
_primuscb=1536930413898-0 那他的規則是什麼呢?
數了一個10秒請求一個新鏈接 之間沒有回傳 那這個規則只能是寫在JS了
整整3萬行 不過仍是被我找到了
new data()
原來是獲取當前js的時間戳+1;
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); long timeStamp = (long)(DateTime.Now - startTime).TotalMilliseconds+1; using (var ws = new WebSocket("wss://ethstats.net/primus/?_primuscb=" + timeStamp + "-0"))
不過數據太多要對獲取數據進行篩選
這些都作好了 就準備轉帳了 先要解鎖要轉帳的用戶
ulong? ul = null; var resultunlock =await Web3.Personal.UnlockAccount.SendRequestAsync(From, FromPassPhrase, ul);
ul 解鎖時間 空默認一次 from 用戶地址 from 用戶地址的私鑰
//轉帳 var txId = Web3.Eth.Transactions.SendTransaction.SendRequestAsync( new TransactionInput { From = From, To = To, Value = new HexBigInteger(long.Parse(GasPrice)), Gas = new HexBigInteger(long.Parse(GasLimit)) }).Result;
From 要轉帳地址 To 被轉帳地址 GasPrice 轉帳能夠數量 Gas 數量 能夠直接用 websocket 獲取到最新的數據 填入 GasPrice,Gas
轉帳成功後 會返回交易哈希 能夠在以太坊瀏覽器上查看
把剛剛的交易回傳的哈希傳入 看交易詳情
Transaction Result =await Web3.Eth.Transactions.GetTransactionByHash.SendRequestAsync(txId);
3.智能合約
首先生成智能合約abi 網站
https://ethereum.github.io/browser-solidity/#optimize=false&version=soljson-v0.4.24+commit.e67f0147.js
public static string BYTECODE = "0x6060......5654「
很長
var senderAddress = "0x12890d2cce102216644c59daE5baed380d84830c"; var privatekey = "0xb5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7"; var url = "https://rinkeby.infura.io/"; var deploymentMessage = new StandardTokenDeployment { TotalSupply = 100000, FromAddress = senderAddress }; var web3 = new Web3.Web3(new Account(privatekey), url); var deploymentHandler = web3.Eth.GetContractDeploymentHandler<StandardTokenDeployment>(); var transactionReceipt = await deploymentHandler.SendRequestAndWaitForReceiptAsync(deploymentMessage); ContractAddress = transactionReceipt.ContractAddress;
先獲取發只能合約用戶的私鑰 讓後
填入發佈數量 名字 返回合約哈希
var senderAddress = "0x12890d2cce102216644c59daE5baed380d84830c"; var balanceOfFunctionMessage = new BalanceOfFunction() { Owner = senderAddress, }; var balanceHandler = web3.Eth.GetContractQueryHandler<BalanceOfFunction>(); var balance = await balanceHandler.QueryAsync<BigInteger>(balanceOfFunctionMessage, contractAddress);
查詢合同剩餘幣數 讓後就是合同代筆轉帳
var senderAddress = "0x12890d2cce102216644c59daE5baed380d84830c"; var receiverAddress = "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe"; var privatekey = "0xb5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7"; var url = "https://rinkeby.infura.io/"; var web3 = new Web3.Web3(new Account(privatekey), url); var transactionMessage = new TransferFunction() { FromAddress = senderAddress, To = receiverAddress, TokenAmount = 100, //Set our own price GasPrice = Web3.Web3.Convert.ToWei(25, UnitConversion.EthUnit.Gwei) }; var transferHandler = web3.Eth.GetContractTransactionHandler<TransferFunction>(); /// this is done automatically so is not needed. var estimate = await transferHandler.EstimateGasAsync(transactionMessage, ContractAddress); transactionMessage.Gas = estimate.Value; var transactionHash = await transferHandler.SendRequestAsync(transactionMessage, ContractAddress);
最後返回交易哈希
一下是上面用到的開源實例庫 他還能夠還發以太坊遊戲
https://nethereum.readthedocs.io/en/latest/introduction/web3/
https://github.com/Nethereum/Nethereum
由於是開源的你們能夠本身去學習
https://gitter.im/Nethereum/Nethereum ETH學習論壇
智能合約
https://github.com/Nethereum/Nethereum/blob/master/src/Nethereum.Accounts.IntegrationTests/SignOfflineTransactionTest.cs#L23-L39
https://github.com/Nethereum/Nethereum.Workbooks/blob/master/docs/nethereum-infura-transfer.workbook
https://github.com/Nethereum/Nethereum.Workbooks/blob/master/docs/nethereum-cqs-test.workbook
至此 大體功能已經完成! 感謝觀看! 下期比特幣!