![]() |
VOOZH | about |
dotnet add package Nethereum.Mud.Contracts --version 6.1.0
NuGet\Install-Package Nethereum.Mud.Contracts -Version 6.1.0
<PackageReference Include="Nethereum.Mud.Contracts" Version="6.1.0" />
<PackageVersion Include="Nethereum.Mud.Contracts" Version="6.1.0" />Directory.Packages.props
<PackageReference Include="Nethereum.Mud.Contracts" />Project file
paket add Nethereum.Mud.Contracts --version 6.1.0
#r "nuget: Nethereum.Mud.Contracts, 6.1.0"
#:package Nethereum.Mud.Contracts@6.1.0
#addin nuget:?package=Nethereum.Mud.Contracts&version=6.1.0Install as a Cake Addin
#tool nuget:?package=Nethereum.Mud.Contracts&version=6.1.0Install as a Cake Tool
Nethereum.Mud.Contracts provides contract definitions and services for interacting with MUD (Onchain Engine) World and Store contracts. It enables you to call MUD systems, query tables, and process Store events.
Store_SetRecord, Store_DeleteRecord, Store_SpliceStaticData, Store_SpliceDynamicData eventsdotnet add package Nethereum.Mud.Contracts
The World contract is the central registry for all MUD resources:
call and callFrom for system executiongrantAccess and revokeAccessThe Store is embedded in the World and manages table data:
Store_SetRecord, Store_DeleteRecord)Store_SpliceStaticData and Store_SpliceDynamicDataTables tableMUD emits events for all state changes:
Store_SetRecord
tableId, keyTuple, staticData, encodedLengths, dynamicDataStore_DeleteRecord
tableId, keyTupleStore_SpliceStaticData
tableId, keyTuple, start, dataStore_SpliceDynamicData
tableId, keyTuple, dynamicFieldIndex, start, deleteCount, encodedLengths, dataGenerated table services provide type-safe access to MUD tables:
Generated system services wrap MUD system functions:
call or direct system callsThe WorldService provides methods for interacting with the World contract:
public class WorldService
{
// Call a system
Task<TransactionReceipt> CallRequestAndWaitForReceiptAsync(
byte[] systemId,
byte[] callData
);
// Call a system with delegator
Task<TransactionReceipt> CallFromRequestAndWaitForReceiptAsync(
string delegator,
byte[] systemId,
byte[] callData
);
}
// Access control (AccessManagementSystemService)
public class AccessManagementSystemService
{
Task<TransactionReceipt> GrantAccessRequestAndWaitForReceiptAsync(
byte[] resourceId,
string grantee
);
Task<TransactionReceipt> RevokeAccessRequestAndWaitForReceiptAsync(
byte[] resourceId,
string grantee
);
}
// Batch calls (BatchCallSystemService)
public class BatchCallSystemService
{
Task<TransactionReceipt> BatchCallRequestAndWaitForReceiptAsync(
List<SystemCallData> systemCalls
);
}
using Nethereum.Web3;
using Nethereum.Mud.Contracts.World;
var web3 = new Web3("https://rpc.mud.game");
var worldAddress = "0xWorldContractAddress";
var worldService = new WorldService(web3, worldAddress);
Console.WriteLine($"Connected to World at {worldAddress}");
using Nethereum.Mud;
using Nethereum.Mud.Contracts.World;
using Nethereum.ABI.FunctionEncoding;
// Create resource ID for the system
var moveSystemResource = new SystemResource("Game", "MoveSystem");
var systemId = moveSystemResource.ResourceIdEncoded;
// Encode function call (e.g., move(direction))
var functionEncoder = new FunctionCallEncoder();
var moveFunction = new MoveFunction { Direction = 1 }; // Assuming generated function DTO
var callData = functionEncoder.EncodeRequest(moveFunction);
// Call the system via World
var receipt = await worldService.CallRequestAndWaitForReceiptAsync(
systemId,
callData
);
Console.WriteLine($"System called successfully. Tx: {receipt.TransactionHash}");
using Nethereum.Mud;
using Nethereum.Mud.Contracts.Store;
// Assuming generated PlayerTableService
var playerTableService = new PlayerTableService(web3, worldAddress);
// Query single record by key
var playerId = 42;
var playerRecord = await playerTableService.GetTableRecordAsync(playerId);
Console.WriteLine($"Player: {playerRecord.Values.Name}");
Console.WriteLine($"Level: {playerRecord.Values.Level}");
Console.WriteLine($"Health: {playerRecord.Values.Health}");
using Nethereum.Mud.Contracts.Core.StoreEvents;
var storeEventsService = new StoreEventsLogProcessingService(web3, worldAddress);
// Get all SetRecord events
var setRecordEvents = await storeEventsService.GetAllSetRecord(
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
foreach (var log in setRecordEvents)
{
var evt = log.Event;
Console.WriteLine($"Record updated:");
Console.WriteLine($" TableId: {evt.TableId.ToHex()}");
Console.WriteLine($" Keys: {string.Join(", ", evt.KeyTuple.Select(k => k.ToHex()))}");
Console.WriteLine($" Block: {log.Log.BlockNumber.Value}");
}
// Get SetRecord events for a specific table
var playerTableId = new Resource("Game", "Player").ResourceIdEncoded;
var playerEvents = await storeEventsService.GetAllSetRecordForTable(
playerTableId,
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
Console.WriteLine($"Found {playerEvents.Count} player table events");
using Nethereum.Mud.Contracts.Core.StoreEvents;
using Nethereum.Mud.TableRepository;
// Create table repository
var playerRepository = new InMemoryTableRepository<PlayerTableRecord>();
// Setup event processing
var storeEventsService = new StoreEventsLogProcessingService(web3, worldAddress);
var progressRepository = new InMemoryBlockProgressRepository();
var processor = storeEventsService.CreateProcessor(
playerRepository,
progressRepository,
logger: null,
blocksPerRequest: 1000,
retryWeight: 50,
minimumBlockConfirmations: 12
);
// Start processing from block 0
await processor.ExecuteAsync(
startAtBlockNumberIfNotProcessed: 0,
cancellationToken: CancellationToken.None
);
Console.WriteLine("Store events processed to repository");
using Nethereum.Mud.Contracts.World;
using Nethereum.Mud.Contracts.World.Systems.BatchCallSystem;
// Prepare multiple system calls
var systemCalls = new List<SystemCallData>
{
new SystemCallData
{
SystemId = moveSystemResource.ResourceIdEncoded,
CallData = EncodeMoveCall(direction: 1)
},
new SystemCallData
{
SystemId = attackSystemResource.ResourceIdEncoded,
CallData = EncodeAttackCall(targetId: 5)
},
new SystemCallData
{
SystemId = craftSystemResource.ResourceIdEncoded,
CallData = EncodeCraftCall(itemId: 10, quantity: 1)
}
};
// Execute all calls in one transaction via BatchCallSystemService
var batchCallService = new BatchCallSystemService(web3, worldAddress);
var receipt = await batchCallService.BatchCallRequestAndWaitForReceiptAsync(systemCalls);
Console.WriteLine($"Batch call successful. Gas used: {receipt.GasUsed.Value}");
using Nethereum.Mud;
using Nethereum.Mud.Contracts.World.Systems.AccessManagementSystem;
// Create resource ID for a table
var playerTableResource = new Resource("Game", "Player");
var tableId = playerTableResource.ResourceIdEncoded;
// Use AccessManagementSystemService for access control
var accessService = new AccessManagementSystemService(web3, worldAddress);
// Grant access to an address
var granteeAddress = "0xGranteeAddress";
var grantReceipt = await accessService.GrantAccessRequestAndWaitForReceiptAsync(
tableId,
granteeAddress
);
Console.WriteLine($"Access granted to {granteeAddress}");
// Revoke access
var revokeReceipt = await accessService.RevokeAccessRequestAndWaitForReceiptAsync(
tableId,
granteeAddress
);
Console.WriteLine($"Access revoked from {granteeAddress}");
using Nethereum.Mud.Contracts.World.ContractDefinition;
using Nethereum.Web3.Accounts;
var account = new Account("0xPrivateKey", chainId: 1);
var web3 = new Web3(account, "https://rpc.mud.game");
// Deploy World contract
var deploymentMessage = new WorldDeployment();
var deploymentReceipt = await WorldService.DeployContractAndWaitForReceiptAsync(
web3,
deploymentMessage
);
var worldAddress = deploymentReceipt.ContractAddress;
Console.WriteLine($"World deployed at: {worldAddress}");
using Nethereum.Mud;
using Nethereum.Mud.EncodingDecoding;
// Define table schema
var playerTableResource = new Resource("Game", "Player");
var schema = SchemaEncoder.GetSchemaEncoded<PlayerKey, PlayerValue>(
playerTableResource.ResourceIdEncoded
);
// Register table via RegistrationSystemService
var registrationService = new RegistrationSystemService(web3, worldAddress);
var registerTableReceipt = await registrationService.RegisterTableRequestAndWaitForReceiptAsync(
tableId: playerTableResource.ResourceIdEncoded,
fieldLayout: schema.FieldLayout,
keySchema: schema.KeySchema,
valueSchema: schema.ValueSchema,
keyNames: new[] { "playerId" },
fieldNames: new[] { "name", "level", "health" }
);
Console.WriteLine($"Table registered: {playerTableResource.NameSpace}:{playerTableResource.Name}");
using Nethereum.Mud.Contracts.Store.Tables;
// TablesTableService queries the on-chain Tables table
var tablesService = new TablesTableService(web3, worldAddress);
// Get schema for a specific table
var playerTableId = new Resource("Game", "Player").ResourceIdEncoded;
var tableRecord = await tablesService.GetTableRecordAsync(playerTableId);
var schema = tableRecord.GetTableSchema();
Console.WriteLine($"Table: {schema.Name}");
Console.WriteLine($"Namespace: {schema.Namespace}");
Console.WriteLine($"Keys: {string.Join(", ", schema.SchemaKeys.Select(k => k.Name))}");
Console.WriteLine($"Values: {string.Join(", ", schema.SchemaValues.Select(v => v.Name))}");
public class WorldService : ContractWeb3ServiceBase
{
public WorldService(Web3 web3, string contractAddress);
// System calls
Task<TransactionReceipt> CallRequestAndWaitForReceiptAsync(
byte[] systemId,
byte[] callData
);
Task<TransactionReceipt> CallFromRequestAndWaitForReceiptAsync(
string delegator,
byte[] systemId,
byte[] callData
);
}
public class AccessManagementSystemService
{
Task<TransactionReceipt> GrantAccessRequestAndWaitForReceiptAsync(
byte[] resourceId,
string grantee
);
Task<TransactionReceipt> RevokeAccessRequestAndWaitForReceiptAsync(
byte[] resourceId,
string grantee
);
}
public class BatchCallSystemService
{
Task<TransactionReceipt> BatchCallRequestAndWaitForReceiptAsync(
List<SystemCallData> systemCalls
);
}
public class RegistrationSystemService
{
Task<TransactionReceipt> RegisterTableRequestAndWaitForReceiptAsync(
byte[] tableId,
byte[] fieldLayout,
byte[] keySchema,
byte[] valueSchema,
string[] keyNames,
string[] fieldNames
);
}
public class StoreEventsLogProcessingService
{
public StoreEventsLogProcessingService(Web3 web3, string contractAddress);
// Query all SetRecord events
Task<List<EventLog<StoreSetRecordEventDTO>>> GetAllSetRecord(...);
Task<List<EventLog<StoreSetRecordEventDTO>>> GetAllSetRecordForTable(byte[] tableId, ...);
// Query all SpliceStaticData events
Task<List<EventLog<StoreSpliceStaticDataEventDTO>>> GetAllSpliceStaticData(...);
Task<List<EventLog<StoreSpliceStaticDataEventDTO>>> GetAllSpliceStaticDataForTable(byte[] tableId, ...);
// Process all store changes (SetRecord, DeleteRecord, SpliceStaticData, SpliceDynamicData)
Task ProcessAllStoreChangesAsync(ITableRepository tableRepository, ...);
Task ProcessAllStoreChangesAsync(ITableRepository tableRepository, byte[] tableId, ...);
Task ProcessAllStoreChangesAsync(ITableRepository tableRepository, string nameSpace, string tableName, ...);
}
Example of a generated table service:
public class PlayerTableService
{
public PlayerTableService(Web3 web3, string worldAddress);
// Query single record
Task<PlayerTableRecord> GetTableRecordAsync(BigInteger playerId);
// Query all records (via events)
Task<List<PlayerTableRecord>> GetTableRecordsAsync(
BigInteger? fromBlock = null,
BigInteger? toBlock = null
);
// Get table resource
Resource GetTableResource();
}
[Event("Store_SetRecord")]
public class StoreSetRecordEventDTO : IEventDTO
{
[Parameter("bytes32", "tableId", 1, true)]
public byte[] TableId { get; set; }
[Parameter("bytes32[]", "keyTuple", 2, false)]
public List<byte[]> KeyTuple { get; set; }
[Parameter("bytes", "staticData", 3, false)]
public byte[] StaticData { get; set; }
[Parameter("bytes32", "encodedLengths", 4, false)]
public byte[] EncodedLengths { get; set; }
[Parameter("bytes", "dynamicData", 5, false)]
public byte[] DynamicData { get; set; }
}
[Event("Store_DeleteRecord")]
public class StoreDeleteRecordEventDTO : IEventDTO
{
[Parameter("bytes32", "tableId", 1, true)]
public byte[] TableId { get; set; }
[Parameter("bytes32[]", "keyTuple", 2, false)]
public List<byte[]> KeyTuple { get; set; }
}
Generate table and system services using .nethereum-gen.multisettings:
{
"paths": ["mud.config.ts"],
"generatorConfigs": [
{
"baseNamespace": "MyGame.Tables",
"basePath": "../MyGame/Tables",
"generatorType": "MudTables"
},
{
"baseNamespace": "MyGame.Systems",
"basePath": "../MyGame/Systems",
"generatorType": "MudExtendedService"
}
]
}
MudTables generates:
PlayerTableRecord.gen.cs - Table record with Keys and ValuesPlayerTableService.gen.cs - Service for querying the tableMudExtendedService generates:
MoveSystemService.gen.cs - Service for calling system functions# Install Nethereum code generator
npm install -g nethereum-codegen
# Generate C# code
nethereum-codegen generate
# Or use VS Code extension
# https://github.com/juanfranblanco/vscode-solidity
var storeEventsService = new StoreEventsLogProcessingService(web3, worldAddress);
// Query all SetRecord events
var events = await storeEventsService.GetAllSetRecord(
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
foreach (var eventLog in events)
{
var evt = eventLog.Event;
// Update local repository
await UpdateRepositoryFromEvent(evt);
// Notify UI
await NotifyUIAsync(evt);
}
var storeEventsService = new StoreEventsLogProcessingService(web3, worldAddress);
var progressRepo = new InMemoryBlockProgressRepository();
var tableRepo = new InMemoryTableRepository<PlayerTableRecord>();
var processor = storeEventsService.CreateProcessor(
tableRepo,
progressRepo,
logger: null,
blocksPerRequest: 1000,
retryWeight: 50,
minimumBlockConfirmations: 12
);
// Process all historical events
await processor.ExecuteAsync(
startAtBlockNumberIfNotProcessed: 0,
cancellationToken: CancellationToken.None
);
var storeEventsService = new StoreEventsLogProcessingService(web3, worldAddress);
var tableRepo = new InMemoryTableRepository<PlayerTableRecord>();
// Process all store changes (SetRecord, DeleteRecord, SpliceStaticData, SpliceDynamicData)
await storeEventsService.ProcessAllStoreChangesAsync(
tableRepo,
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
// Or process changes for a specific table only
var playerTableId = new Resource("Game", "Player").ResourceIdEncoded;
await storeEventsService.ProcessAllStoreChangesAsync(
tableRepo,
playerTableId,
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
public class CustomEventHandler
{
public async Task HandleSetRecord(StoreSetRecordEventDTO evt)
{
// Custom logic for SetRecord
var tableId = evt.TableId.ToHex();
if (tableId == playerTableId)
{
await HandlePlayerUpdate(evt);
}
else if (tableId == inventoryTableId)
{
await HandleInventoryUpdate(evt);
}
}
}
var playerTableId = new Resource("Game", "Player").ResourceIdEncoded;
// Use GetAllSetRecordForTable to query events for a specific table
var playerEvents = await storeEventsService.GetAllSetRecordForTable(
playerTableId,
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
foreach (var eventLog in playerEvents)
{
// Only receives events for Player table
var playerEvent = eventLog.Event;
await HandlePlayerUpdate(playerEvent);
}
// Query static data splice events
var spliceStaticEvents = await storeEventsService.GetAllSpliceStaticData(
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
foreach (var eventLog in spliceStaticEvents)
{
var evt = eventLog.Event;
Console.WriteLine($"Static data spliced:");
Console.WriteLine($" TableId: {evt.TableId.ToHex()}");
Console.WriteLine($" Start: {evt.Start}");
Console.WriteLine($" New data length: {evt.Data.Length}");
}
// Or use ProcessAllStoreChangesAsync to handle all event types
// (SetRecord, DeleteRecord, SpliceStaticData, SpliceDynamicData)
// and apply them to a table repository automatically
await storeEventsService.ProcessAllStoreChangesAsync(
tableRepository,
fromBlockNumber: 0,
toBlockNumber: null,
cancellationToken: CancellationToken.None
);
// Initialize World connection
var worldService = new WorldService(web3, worldAddress);
// Load initial state from chain
var playerTable = new PlayerTableService(web3, worldAddress);
var players = await playerTable.GetTableRecordsAsync(fromBlock: 0);
// Subscribe to updates
var subscription = await SubscribeToStoreEvents(worldAddress);
// User action: Move player
var moveSystemResource = new SystemResource("Game", "MoveSystem");
await worldService.CallRequestAndWaitForReceiptAsync(
moveSystemResource.ResourceIdEncoded,
EncodeMoveCall(direction: 1)
);
// Continuously index all MUD events to database
var dbRepository = new PostgresTableRepository(connectionString);
var progressRepo = new PostgresBlockProgressRepository(connectionString);
var processor = storeEventsService.CreateProcessor(
dbRepository,
progressRepo,
logger,
blocksPerRequest: 1000,
retryWeight: 50,
minimumBlockConfirmations: 12
);
while (true)
{
try
{
await processor.ExecuteAsync(0);
}
catch (Exception ex)
{
logger.LogError(ex, "Indexer error, retrying...");
await Task.Delay(30000);
}
}
// Query data from multiple MUD Worlds
var world1Service = new WorldService(web3, world1Address);
var world2Service = new WorldService(web3, world2Address);
var player1Table = new PlayerTableService(web3, world1Address);
var player2Table = new PlayerTableService(web3, world2Address);
// Aggregate player data from both worlds
var players1 = await player1Table.GetTableRecordsAsync();
var players2 = await player2Table.GetTableRecordsAsync();
var allPlayers = players1.Concat(players2).ToList();
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net451 net451 is compatible. net452 net452 was computed. net46 net46 was computed. net461 net461 is compatible. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 3 NuGet packages that depend on Nethereum.Mud.Contracts:
| Package | Downloads |
|---|---|
|
Nethereum.Mud.Repositories.EntityFramework
Nethereum.Mud.Repositories.EntityFramework Nethereum Web3 Class Library providing the EF context Table Repositories to sync with the Store contracts of the Mud framework https://mud.dev/ (Encoding, Repositories, Resources, Schema, TableRecords) |
|
|
Nethereum.MudBlazorComponents
Nethereum.MudBlazorComponents Nethereum MudBlazor Components to dynamically generate Deploy, Transact and Query smart contracts user interfaces using Deployment and Function Typed Messages or Nethereum Services. Mud.dev Table components to query and upsert data using TableServices. |
|
|
Nethereum.AppChain
Nethereum AppChain - Application-specific blockchain with RocksDB storage, MUD World integration, and genesis configuration |
Showing the top 1 popular GitHub repositories that depend on Nethereum.Mud.Contracts:
| Repository | Stars |
|---|---|
|
ChainSafe/web3.unity
🕹 Unity SDK for building games that interact with blockchains.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 6.1.0 | 784 | 3/25/2026 |
| 6.0.4 | 214 | 3/18/2026 |
| 6.0.3 | 162 | 3/18/2026 |
| 6.0.1 | 194 | 3/17/2026 |
| 6.0.0 | 175 | 3/16/2026 |
| 5.8.0 | 187 | 1/6/2026 |
| 5.0.0 | 345 | 5/28/2025 |
| 4.29.0 | 278 | 2/10/2025 |
| 4.28.0 | 292 | 1/7/2025 |
| 4.27.1 | 279 | 12/24/2024 |
| 4.27.0 | 283 | 12/24/2024 |
| 4.26.0 | 339 | 10/1/2024 |
| 4.25.0 | 292 | 9/19/2024 |
| 4.21.4 | 268 | 8/9/2024 |
| 4.21.3 | 247 | 7/22/2024 |
| 4.21.2 | 941 | 6/26/2024 |
| 4.21.1 | 255 | 6/26/2024 |
| 4.21.0 | 272 | 6/18/2024 |