c#实战开发(用.net|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 = https://www.it610.com/article/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(); var transactionReceipt = await deploymentHandler.SendRequestAndWaitForReceiptAsync(deploymentMessage); ContractAddress = transactionReceipt.ContractAddress;
先获取发只能合约用户的私钥 让后
填入发布数量 名字 返回合约哈希
var senderAddress = "0x12890d2cce102216644c59daE5baed380d84830c"; var balanceOfFunctionMessage = new BalanceOfFunction() { Owner = senderAddress, }; var balanceHandler = web3.Eth.GetContractQueryHandler(); var balance = await balanceHandler.QueryAsync (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(); /// 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/NethereumETH学习论坛
智能合约
https://github.com/Nethereum/Nethereum/blob/master/src/Nethereum.Accounts.IntegrationTests/SignOfflineTransactionTest.cs#L23-L39
【c#实战开发(用.net|c#实战开发:用.net core开发一个简单的Web以太坊钱包 (六))】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
至此 大致功能已经完成! 感谢观看! 下期比特币!
转载于:https://www.cnblogs.com/feizianquan/p/9607194.html
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- JS中的各种宽高度定义及其应用
- 深入理解Go之generate
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- 涉毒患者(新诗)
- 参保人员因患病来不及到指定的医疗机构就医,能否报销医疗费用()
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询