C# 实战:.NET Core 打造简易以太坊 Web 钱包(完结篇)

·

核心关键词:C# 以太坊钱包、.NET Core Web3、Nethereum 转账、智能合约部署、以太坊私链

1. 回顾与目标

在系列前五篇里,我们已经成功完成:


2. 钱包功能清单

功能点对应回调接口关键词融入
1. 查看用户GetBalance用户余额、以太坊钱包
2. 交易记录GetTransactionByHash交易哈希、区块浏览器
3. 转账SendTransactionAsyncETH 转账、Gas 费用
4. 发布合约SendRequestAndWaitForReceiptAsync智能合约部署
5. 代币转账TransferFunctionERC20、代币钱包
6. 代币查询BalanceOfFunction余额查询
7. 实时区块同步WebSocket 监听Web3 实时数据
8. 自动手续费Gas Price 数据源低费率转账

👉 动手就能跑的以太坊钱包示例代码,回归阅读即可领取!


3. 项目初始化

  1. 新建 .NET 6 Web API 项目

    dotnet new webapi -n SimpleEthWallet
    cd SimpleEthWallet
  2. 安装依赖

    dotnet add package Nethereum.Web3
    dotnet add package Nethereum.Geth
  3. 配置多节点容灾地址

    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);
}

5. 以太坊转账与 Gas 预估

5.1 解锁账户

await web3.Personal.UnlockAccount.SendRequestAsync(from, passphrase, 300);

解锁 5 分钟,降低交互次数。

5.2 实时 Gas 价格来源

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 完成助记词、地址派生与多签转账,敬请期待!