Примеры кода
Пример 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;
}
}
}