Примеры кода

Пример 1: Подключение Web3 кошелька

Базовая система подключения MetaMask кошелька к Unity игре:

using System;
using System.Threading.Tasks;
using UnityEngine;
using Nethereum.Web3;

/// 
/// Подключение к Web3 кошельку (MetaMask) из Unity
/// 
public class WalletConnection : MonoBehaviour
{
    [SerializeField] private string rpcUrl = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
    private Web3 web3;
    public string PlayerWalletAddress { get; private set; }
    
    public event Action<string> OnWalletConnected;
    public event Action<decimal> OnBalanceUpdated;

    void Start() => InitializeWeb3();

    private void InitializeWeb3()
    {
        try
        {
            web3 = new Web3(rpcUrl);
            Debug.Log("Web3 соединение инициализировано");
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка Web3: {ex.Message}");
        }
    }

    public async Task<bool> ConnectWallet()
    {
        try
        {
            var accounts = await RequestAccountAccess();
            if (accounts?.Length > 0)
            {
                PlayerWalletAddress = accounts[0];
                OnWalletConnected?.Invoke(PlayerWalletAddress);
                await UpdateBalance();
                return true;
            }
            return false;
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка подключения: {ex.Message}");
            return false;
        }
    }

    public async Task UpdateBalance()
    {
        if (string.IsNullOrEmpty(PlayerWalletAddress)) return;
        
        var balanceWei = await web3.Eth.GetBalance.SendRequestAsync(PlayerWalletAddress);
        var balanceEth = Web3.Convert.FromWei(balanceWei.Value);
        OnBalanceUpdated?.Invoke(balanceEth);
    }
}

Пример 2: Система управления NFT

Загрузка и отображение NFT коллекции игрока:

using System.Collections.Generic;
using UnityEngine;

public class NFTManager : MonoBehaviour 
{
    [System.Serializable]
    public class GameNFT
    {
        public string tokenId;
        public string name;
        public string rarity;
        public Dictionary<string, object> attributes;
    }

    private List<GameNFT> playerNFTs = new List<GameNFT>();
    
    public async Task LoadPlayerNFTs(string playerAddress)
    {
        try
        {
            playerNFTs.Clear();
            var balance = await GetNFTBalance(playerAddress);
            
            for (int i = 0; i < balance; i++)
            {
                var tokenId = await GetTokenByIndex(playerAddress, i);
                var nft = await LoadNFTMetadata(tokenId);
                if (nft != null) playerNFTs.Add(nft);
            }
            
            Debug.Log($"Загружено {playerNFTs.Count} NFT");
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка загрузки NFT: {ex.Message}");
        }
    }

    public List<GameNFT> GetNFTsByRarity(string rarity)
    {
        return playerNFTs.FindAll(nft => 
            nft.rarity.Equals(rarity, StringComparison.OrdinalIgnoreCase));
    }
}

Пример 3: Смарт-контракт игровых токенов

Solidity контракт для игровой валюты с play-to-earn механиками:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract GameCoin is ERC20, Ownable {
    uint256 public constant MAX_SUPPLY = 1000000000 * 10**18;
    
    mapping(address => uint256) public playerScore;
    mapping(address => uint256) public lastRewardClaim;
    
    event RewardClaimed(address indexed player, uint256 amount);
    
    constructor() ERC20("GameCoin", "GC") {
        _mint(msg.sender, 100000000 * 10**18);
    }
    
    function updatePlayerScore(address player, uint256 score) external onlyOwner {
        playerScore[player] = score;
    }
    
    function claimDailyReward() external {
        require(block.timestamp >= lastRewardClaim[msg.sender] + 1 days, 
                "Уже получено сегодня");
        require(playerScore[msg.sender] > 0, "Нет очков");
        
        uint256 reward = playerScore[msg.sender] / 100;
        require(reward > 0, "Мало очков");
        require(totalSupply() + reward <= MAX_SUPPLY, "Превышен лимит");
        
        lastRewardClaim[msg.sender] = block.timestamp;
        _mint(msg.sender, reward);
        
        emit RewardClaimed(msg.sender, reward);
    }
}

Пример 4: Игровой маркетплейс

Система торговли внутриигровыми предметами:

public class GameMarketplace : MonoBehaviour
{
    [System.Serializable]
    public class MarketItem
    {
        public string itemId;
        public string seller;
        public uint256 price;
        public bool isActive;
    }

    private List<MarketItem> marketItems = new List<MarketItem>();
    
    public async Task ListItemForSale(string itemId, uint256 price)
    {
        try
        {
            var listFunction = contract.GetFunction("listItem");
            var receipt = await listFunction.SendTransactionAndWaitForReceiptAsync(
                playerAddress, itemId, price);
                
            marketItems.Add(new MarketItem 
            { 
                itemId = itemId, 
                seller = playerAddress, 
                price = price, 
                isActive = true 
            });
            
            Debug.Log($"Предмет {itemId} выставлен за {price} токенов");
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка выставления: {ex.Message}");
        }
    }

    public async Task BuyItem(string itemId)
    {
        var item = marketItems.Find(x => x.itemId == itemId && x.isActive);
        if (item == null) return;
        
        try
        {
            var buyFunction = contract.GetFunction("buyItem");
            await buyFunction.SendTransactionAndWaitForReceiptAsync(
                playerAddress, itemId);
                
            item.isActive = false;
            Debug.Log($"Предмет {itemId} куплен!");
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка покупки: {ex.Message}");
        }
    }
}

Пример 5: Система игровых токенов

Управление игровыми токенами и транзакциями:

public class TokenManager : MonoBehaviour
{
    private Contract tokenContract;
    
    public async Task<uint256> GetPlayerTokenBalance(string playerAddress)
    {
        try
        {
            var balanceFunction = tokenContract.GetFunction("balanceOf");
            var balance = await balanceFunction.CallAsync<uint256>(playerAddress);
            return balance;
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка получения баланса: {ex.Message}");
            return 0;
        }
    }

    public async Task<bool> TransferTokens(string toAddress, uint256 amount)
    {
        try
        {
            var transferFunction = tokenContract.GetFunction("transfer");
            var receipt = await transferFunction.SendTransactionAndWaitForReceiptAsync(
                playerAddress, toAddress, amount);
                
            Debug.Log($"Переведено {amount} токенов на {toAddress}");
            return receipt.Status == 1;
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка перевода: {ex.Message}");
            return false;
        }
    }

    public async Task<bool> BurnTokensForUpgrade(uint256 amount)
    {
        try
        {
            var burnFunction = tokenContract.GetFunction("burn");
            await burnFunction.SendTransactionAndWaitForReceiptAsync(
                playerAddress, amount);
                
            Debug.Log($"Сожжено {amount} токенов для улучшения");
            return true;
        }
        catch (Exception ex)
        {
            Debug.LogError($"Ошибка сжигания: {ex.Message}");
            return false;
        }
    }
}