Fetch contract ABIs from Sourcify, Etherscan, and 4Byte Directory using the composite ABIInfoStorage pattern (.NET/C#). Use this skill when the user asks about ABI retrieval, contract verification, function signature lookup, calldata decoding, or Sourcify/Etherscan API usage.
Nethereum.DataServices provides a composite ABI lookup system that chains multiple sources with automatic fallback: Sourcify → Etherscan → 4Byte Directory.
NuGet: Nethereum.DataServices
dotnet add package Nethereum.DataServices
Use ABIInfoStorageFactory to create a fallback chain of ABI sources:
using Nethereum.DataServices.ABIInfoStorage;
// Full chain: cache → Sourcify → Etherscan → Sourcify4Byte → FourByte
var storage = ABIInfoStorageFactory.CreateDefault(etherscanApiKey: "YOUR_KEY");
// Get complete ABI
var abiInfo = await storage.GetABIInfoAsync(chainId: 1, contractAddress);
Console.WriteLine($"Contract: {abiInfo.ContractName}, Functions: {abiInfo.FunctionABIs.Count}");
| Method | Sources |
|---|---|
CreateDefault(etherscanApiKey, cache) | Cache → Sourcify → Etherscan → Sourcify4Byte → FourByte |
CreateWithSourcifyOnly(cache) | Cache → Sourcify → Sourcify4Byte → FourByte |
CreateWithEtherscanOnly(apiKey, cache) | Cache → Etherscan → Sourcify4Byte → FourByte |
CreateLocalOnly(cache) | Cache only |
CreateCustom(cache, storages...) | Custom fallback chain |
var storage = ABIInfoStorageFactory.CreateCustom(
cache: new ABIInfoInMemoryStorage(),
new SourcifyABIInfoStorage(),
new EtherscanABIInfoStorage("YOUR_KEY"),
new FourByteDirectoryABIInfoStorage());
// By 4-byte selector from input data
var func = await storage.FindFunctionABIFromInputDataAsync(chainId, contractAddress, inputData);
// By topic hash
var evt = await storage.FindEventABIAsync(chainId, contractAddress, topicHash);
// By error selector
var err = await storage.FindErrorABIAsync(chainId, contractAddress, errorSelector);
var functions = await storage.FindFunctionABIsBatchAsync(
new[] { "0xa9059cbb", "0x095ea7b3", "0x23b872dd" });
var events = await storage.FindEventABIsBatchAsync(
new[] { "0xddf252ad...", "0x8c5be1e5..." });
var combined = await storage.FindABIsBatchAsync(functionSignatures, eventSignatures);
using Nethereum.DataServices.Sourcify;
var sourcify = new SourcifyApiServiceV2();
// Get contract (ABI, sources, compilation, proxy resolution)
var contract = await sourcify.GetContractAsync(chainId: 1, contractAddress);
// Just ABI
string abi = await sourcify.GetContractAbiAsync(chainId: 1, contractAddress);
// Verify from Etherscan
var result = await sourcify.VerifyFromEtherscanAsync(chainId, address, etherscanApiKey);
// Verify with source files
var verifyResult = await sourcify.PostVerifyAsync(chainId, address, sourceFiles);
SourcifyABIInfoStorage automatically resolves proxy contracts:
var sourcifyStorage = new SourcifyABIInfoStorage(); // resolveProxies: true
var abiInfo = await sourcifyStorage.GetABIInfoAsync(chainId, proxyAddress);
// Returns implementation ABI
using Nethereum.DataServices.Etherscan;
var etherscan = new EtherscanApiService(chain: 1, apiKey: "YOUR_KEY");
var abiResponse = await etherscan.Contracts.GetAbiAsync(contractAddress);
var sourceResponse = await etherscan.Contracts.GetSourceCodeAsync(contractAddress);
using Nethereum.DataServices.FourByteDirectory;
var fourByte = new FourByteDirectoryService();
var result = await fourByte.GetFunctionSignatureByHexSignatureAsync("0xa9059cbb");
// result.Results[0].TextSignature → "transfer(address,uint256)"
using Nethereum.DataServices.Sourcify;
var sig4byte = new Sourcify4ByteSignatureService();
// Batch lookup
var result = await sig4byte.LookupAsync(
functionSignatures: new[] { "0xa9059cbb", "0x095ea7b3" },
eventSignatures: new[] { "0xddf252ad..." });
using Nethereum.DataServices.ABIInfoStorage;
var decoded = program.DecodeWithSourcify(callInput, chainId: 1);
var decoded2 = program.Decode(callInput, chainId, etherscanApiKey: "YOUR_KEY");
var decoded3 = programResult.DecodeWithStorage(trace, callInput, chainId, storage);
For local storage of Sourcify data, use Nethereum.Sourcify.Database (EF Core + PostgreSQL):
using Nethereum.Sourcify.Database;
services.AddDbContext<SourcifyDbContext>(options => options.UseNpgsql(connectionString));
services.AddScoped<ISourcifyRepository, EFCoreSourcifyRepository>();
// Query
var sig = await repo.GetSignatureByHash4Async(selectorBytes);
var verified = await repo.GetVerifiedContractAsync(chainId, addressBytes);
| Namespace | Purpose |
|---|---|
Nethereum.DataServices.ABIInfoStorage | Composite ABI lookup factory and implementations |
Nethereum.DataServices.Sourcify | Sourcify V1/V2 API, Parquet exports, 4byte signatures |
Nethereum.DataServices.Etherscan | Etherscan V2 unified API |
Nethereum.DataServices.FourByteDirectory | 4byte.directory API |
Nethereum.DataServices.Chainlist | Chainlist RPC discovery |