c#實戰開發:用.net core開發一個簡單的Web以太坊錢包 (六)


 

今天就來開發一個C# 版的簡易錢包 先回顧以前的內容

c#實戰開發:以太坊Geth 命令發布智能合約 (五)

c#實戰開發:以太坊Geth 常用命令 (四)

c#實戰開發:以太坊錢包快速同步區塊和錢包卡死解決方案 (三)

c#實戰開發:以太坊錢包對接私鏈 (二)

c#實戰開發:以太坊私鏈搭建(一)

先看一下可視化錢包有哪些功能呢?

 

那這個錢包得有什么功能呢? 

1.查看用戶

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

至此 大致功能已經完成! 感謝觀看! 下期比特幣!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM