核心关键词:C# 以太坊钱包、.NET Core Web3、Nethereum 转账、智能合约部署、以太坊私链
1. 回顾与目标
在系列前五篇里,我们已经成功完成:
- 搭建私链
- 快速同步区块
- 常用 Geth 命令
- 发布第一个智能合约
本篇作为最终章,将把以上能力整合到一个 C# 版轻量级以太坊 Web 钱包,演示查看用户、转账、发布与调用智能合约、代币转账等高阶功能。
2. 钱包功能清单
| 功能点 | 对应回调接口 | 关键词融入 |
|---|---|---|
| 1. 查看用户 | GetBalance | 用户余额、以太坊钱包 |
| 2. 交易记录 | GetTransactionByHash | 交易哈希、区块浏览器 |
| 3. 转账 | SendTransactionAsync | ETH 转账、Gas 费用 |
| 4. 发布合约 | SendRequestAndWaitForReceiptAsync | 智能合约部署 |
| 5. 代币转账 | TransferFunction | ERC20、代币钱包 |
| 6. 代币查询 | BalanceOfFunction | 余额查询 |
| 7. 实时区块同步 | WebSocket 监听 | Web3 实时数据 |
| 8. 自动手续费 | Gas Price 数据源 | 低费率转账 |
3. 项目初始化
新建 .NET 6 Web API 项目
dotnet new webapi -n SimpleEthWallet cd SimpleEthWallet安装依赖
dotnet add package Nethereum.Web3 dotnet add package Nethereum.Geth配置多节点容灾地址
private readonly string[] _nodeUrls = new[] { "http://localhost:8545", "http://localhost:8546", "http://localhost:8547" };启动 任一本地 Geth 私链 均可(回顾「系列二」)。
4. 用户与余额
public async Task<string> NewAccount(string password)
{
var web3 = GetHealthyClient(); // 选一个正常节点
return await web3.Personal.NewAccount.SendRequestAsync(password);
}
public async Task<decimal> GetEthBalance(string address)
{
var web3 = GetHealthyClient();
var balanceWei = await web3.Eth.GetBalance.SendRequestAsync(address);
return Web3.Convert.FromWei(balanceWei.Value);
}- 健康检查:先轮询
{}_nodeUrls节点,对比GetBlockNumber≈ 主网高度(ethstats.net参考)。
5. 以太坊转账与 Gas 预估
5.1 解锁账户
await web3.Personal.UnlockAccount.SendRequestAsync(from, passphrase, 300);解锁 5 分钟,降低交互次数。
5.2 实时 Gas 价格来源
- WebSocket 订阅
wss://ethstats.net/primus/?_primuscb={timestamp}-0 - 计算规则:
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + 1 - 每 10 秒推送平均/建议 GasPrice,无需爬取。
5.3 带预估的转账
var txInput = new TransactionInput
{
From = from,
To = to,
Value = new HexBigInteger(Web3.Convert.ToWei(amount)),
Gas = new HexBigInteger(gasLimit),
GasPrice = new HexBigInteger(Web3.Convert.ToWei(suggestedGwei, UnitConversion.EthUnit.Gwei))
};
var txHash = await web3.Eth.Transactions.SendTransaction.SendRequestAsync(txInput);返回的交易哈希即可在 区块浏览器 查询详情。
6. 智能合约部署与交互
6.1 部署 ERC20 合约
var deploymentMessage = new StandardTokenDeployment
{
TotalSupply = 1_000_000,
FromAddress = deployerAddress,
Gas = 5_000_000,
GasPrice = Web3.Convert.ToWei(25, UnitConversion.EthUnit.Gwei)
};
var handler = web3.Eth.GetContractDeploymentHandler<StandardTokenDeployment>();
var receipt = await handler.SendRequestAndWaitForReceiptAsync(deploymentMessage);
string contractAddress = receipt.ContractAddress;6.2 代币查询 & 转账
// 查询余额
var balanceOfFunction = new BalanceOfFunction { Owner = userAddress };
var balanceHandler = web3.Eth.GetContractQueryHandler<BalanceOfFunction>();
BigInteger balance = await balanceHandler.QueryAsync<BigInteger>(balanceOfFunction, contractAddress);
// 代币转账
var transferFunction = new TransferFunction
{
To = receiver,
TokenAmount = 100 * (BigInteger)Math.Pow(10, 18), // 18 位精度
FromAddress = sender,
Gas = 100_000
};
var transferHandler = web3.Eth.GetContractTransactionHandler<TransferFunction>();
string txHash = await transferHandler.SendRequestAsync(transferFunction, contractAddress);7. 实时数据推送(WebSocket Demo)
流式监听示例:
using var ws = new ClientWebSocket();
var uri = new Uri($"wss://ethstats.net/primus/?_primuscb={GetTimeStamp()}-0");
await ws.ConnectAsync(uri, CancellationToken.None);
var buffer = new ArraySegment<byte>(new byte[4096]);
var result = await ws.ReceiveAsync(buffer, CancellationToken.None);
string json = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
var latestBlock = JsonDocument.Parse(json).RootElement.GetProperty("stats").GetProperty("blockNumber").GetString();解析后把最新区块 & 实时手续费推送给前端。
8. 成品路由示例
| 路由 | 作用 |
|---|---|
POST /wallet/account | 创建新账户 |
GET /wallet/{address}/balance | 查询 ETH 余额 |
POST /wallet/transfer | 转账(含自动 Gas 计算) |
POST /wallet/deploy-token | 一键部署 ERC20 |
GET /wallet/tx/{txHash} | 交易详情 |
WebSocket /live | 实时区块、GasPrice 推送 |
9. FAQ:高频疑问汇总
Q1:手边没有 Geth 怎么办?
A:使用 Infura 或 本地 Ganache 测试,节点 URL 设置为 https://rinkeby.infura.io/v3/YourProjectId 即可。
Q2:转账失败,Gas 耗尽?
A:优先启用 EstimateGasAsync 获取真实消耗,再 +10% 作为上限,既省又稳。
Q3:私钥如何安全存储?
A:生产环境请使用 Azure Key Vault、AWS KMS 或本地 HSM,切勿明文于代码或配置中。
Q4:能否直接打包成桌面端?
A:将 Web API + Angular/React 组件嵌入 Electron.NET,跨平台桌面一份代码即可 Compile Once, Run Win/Mac/Linux。
Q5:如何监听代币发放/销毁事件?
A:Nethereum 支持 Event<TEventDTO>,订阅 TransferEventDTO 即可实时捕捉链上 Transfer 日志。
Q6:ERC721 NFT 能支持吗?
A:完全可行。只需替换 IERC721Service 对应合约接口与调用逻辑即可。
(拓展阅读:Nethereum NFT 单元测试仓库)
10. 总结与下期预告
至此,从 私链搭建 → 合约部署 → Web 钱包 的完整闭环已实现。
下期我们将转战 比特币网络,用 NBitCoin 完成助记词、地址派生与多签转账,敬请期待!