Building blockchain applications with .NET is far more approachable than most C# developers assume. You do not need to abandon the tooling you already know, learn Solidity end-to-end, or rewrite your stack in JavaScript. With the open-source Nethereum library, an ASP.NET Core service can read balances, submit transactions, listen for events, and invoke smart contracts on Ethereum and any EVM-compatible chain — all in strongly typed C#. This guide walks through the architecture, the packages, and the working code you need to ship a production-grade integration.
The value proposition is straightforward: a blockchain is a shared, append-only database that no single party controls. Your .NET application does not host the ledger; it talks to a node — a server running Ethereum client software — over JSON-RPC. That node is your gateway to the network. Everything else is about how cleanly your C# code can encode requests, sign transactions, and decode results. This is where Nethereum earns its place in the .NET Architecture toolkit.
Why .NET Is a Strong Fit for Blockchain Back Ends
Most tutorials assume Node.js and web3.js, but a large share of real-world blockchain workloads are back-office systems: payment reconciliation, custody, treasury reporting, supply-chain provenance, and internal dashboards. Those systems already run on .NET in banks, insurers, and enterprises. Keeping the blockchain layer in the same runtime means shared authentication, logging, dependency injection, and deployment pipelines rather than a bolted-on microservice in a foreign language.
.NET 10, released in November 2025, is the current Long Term Support (LTS) release and is supported through November 2028, which makes it the sensible target for any new blockchain service you expect to run for years. If you are still on .NET 8 or .NET 9, note that both reach end of support on November 10, 2026, so plan the upgrade before you build something you will depend on. Nethereum targets .NET Standard 2.0 and above, so it runs cleanly on .NET 10, on older frameworks, and across desktop, cloud, and mobile.
Choosing Your Node Provider
Your application needs a JSON-RPC endpoint. You can run your own node, but for most teams a managed provider is faster and cheaper to start. Infura and Alchemy both offer free tiers with generous request quotas, and QuickNode is a common third option. A mainnet Infura endpoint looks like https://mainnet.infura.io/v3/YOUR_PROJECT_ID. For development and testing, use a public testnet such as Sepolia so you are not spending real ETH while you iterate.
A practical rule: never hard-code the endpoint or any private key in source. Store the RPC URL and secrets in configuration, user secrets, or a vault, and inject them. Treasury keys in particular belong in a key-management service, never in appsettings.json.
➡️ For the payment-processing side of this stack, see our guide on building a crypto payment system in .NET.
Setting Up the Project
Create a new ASP.NET Core Web API and add the core package. Nethereum.Web3 is the primary entry point; at the time of writing the stable release line is version 6.x on NuGet.
bash
dotnet new webapi -n BlockchainDemo
cd BlockchainDemo
dotnet add package Nethereum.Web3Register a shared Web3 client through dependency injection so you are not constructing a new HTTP client on every request. Reading the endpoint from configuration keeps secrets out of code.
csharp
// Program.cs
using Nethereum.Web3;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IWeb3>(_ =>
{
var rpcUrl = builder.Configuration["Ethereum:RpcUrl"]
?? throw new InvalidOperationException("Missing RPC URL");
return new Web3(rpcUrl);
});
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();Reading Data from the Chain
The simplest useful operation is a read — no signing, no gas, no risk. These calls hit the node and return current state. Fetching the latest block number and an account balance confirms your connection is healthy and demonstrates the async pattern every Nethereum call follows.
csharp
using Microsoft.AspNetCore.Mvc;
using Nethereum.Web3;
[ApiController]
[Route("api/[controller]")]
public class ChainController(IWeb3 web3) : ControllerBase
{
[HttpGet("block-number")]
public async Task<long> GetBlockNumber()
{
var latest = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();
return (long)latest.Value;
}
[HttpGet("balance/{address}")]
public async Task<decimal> GetBalance(string address)
{
var wei = await web3.Eth.GetBalance.SendRequestAsync(address);
// Balances are stored in wei (10^18 wei = 1 ETH); convert for display.
return Web3.Convert.FromWei(wei.Value);
}
}Two details matter here. Balances come back in wei, the smallest denomination, where 10^18 wei equals 1 ETH, so you must convert before showing a human-readable figure. And every request is asynchronous because it crosses the network to your node — treat latency and transient failures as normal, and add retry policies with a library such as Polly for anything user-facing.
Calling a Smart Contract
Smart contracts are programs deployed to the chain. To talk to one you need its address and its ABI — a JSON description of its functions. Nethereum can load a contract from the ABI and let you call read-only functions for free. Below is a canonical ERC-20 token read: fetching a token's name and an address's token balance.
csharp
// Minimal ABI fragment for two ERC-20 read functions.
const string abi = """
[
{"constant":true,"inputs":[],"name":"name",
"outputs":[{"name":"","type":"string"}],"type":"function"},
{"constant":true,"inputs":[{"name":"owner","type":"address"}],
"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"}
]
""";
var contract = web3.Eth.GetContract(abi, tokenAddress);
var name = await contract.GetFunction("name").CallAsync<string>();
var rawBalance = await contract
.GetFunction("balanceOf")
.CallAsync<System.Numerics.BigInteger>(ownerAddress);For larger contracts, hand-writing ABIs is tedious and error-prone. Nethereum ships a code generator (Nethereum.Generator.Console) and a VS Code Solidity extension that turn an ABI into typed C# service classes, so balanceOf becomes a real method with real parameters instead of a stringly-typed call. This is the workflow to prefer once you move past a proof of concept.
Writing to the Chain: Transactions and Gas
Reads are free; writes cost money. Any operation that changes state — sending ETH, transferring a token, invoking a state-changing contract function — is a transaction that must be signed with a private key and pays a gas fee to the network. In Nethereum you sign locally by constructing the Web3 client with an Account, so the key never leaves your process.
csharp
using Nethereum.Web3.Accounts;
var account = new Account(privateKey); // load from a vault, never from code
var signingWeb3 = new Web3(account, rpcUrl);
var receipt = await signingWeb3.Eth.GetEtherTransferService()
.TransferEtherAndWaitForReceiptAsync(toAddress, 0.01m);Transactions are not instant. The receipt confirms the transaction was mined, but you should design for the window between submission and confirmation — record a pending state, expose the transaction hash so users can track it on a block explorer, and reconcile once confirmed. Because fees fluctuate with network demand, estimate gas before sending and set sane limits so a fee spike cannot drain a hot wallet.
Testing Without Spending Real Money
Never develop against mainnet. Use the Sepolia testnet with faucet-funded test ETH, or run a local chain for fast, deterministic tests. Nethereum provides a DevChain template (dotnet new nethereum-devchain) that spins up a local node, a PostgreSQL-backed indexer, and a Blazor explorer orchestrated with .NET Aspire — an efficient way to test contract interactions in CI without external dependencies or cost. You can also try calls instantly at playground.nethereum.com before writing any project code.
Production Considerations
Three concerns separate a demo from a shippable service. First, key management: signing keys belong in a hardware security module or a managed vault with tight access control, and you should minimize the balance held in any hot wallet. Second, resilience: nodes go down and rate-limit, so wrap RPC calls in retries, add a fallback provider, and monitor endpoint health. Third, observability: log every transaction hash, index events you care about rather than polling, and reconcile on-chain state against your own database on a schedule. Get those right and a .NET blockchain service is no harder to operate than any other API back end.
Key Takeaways
Building blockchain applications with .NET comes down to a small, learnable stack: an ASP.NET Core service, the Nethereum library, and a JSON-RPC endpoint from a provider like Infura or Alchemy. Reads are free and safe; writes cost gas and require careful key handling. Generate typed contract services instead of hand-writing ABIs, test on Sepolia or a local DevChain, and treat key management and resilience as first-class from day one. On .NET 10 LTS you have a supported foundation through 2028 to build on with confidence.
Stay in the loop. MagicAjax.NET publishes practical .NET architecture guides every week. Subscribe to our newsletter for new tutorials on blockchain, crypto payments, and modern web development in C# — and get our Nethereum starter checklist free.


