Разработка системы классификации крипто-транзакций (trade, income, airdrop, staking reward)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка системы классификации крипто-транзакций (trade, income, airdrop, staking reward)
Средний
~1-2 недели
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    902
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1122
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    859

Разработка системы классификации крипто-транзакций

Правильная классификация транзакций — фундамент корректного налогового учёта. Trade, income, airdrop, staking reward — каждый тип имеет разную налоговую трактовку в каждой юрисдикции. Автоматическая классификация снижает ручную работу на 80-90% для большинства пользователей.

Иерархия классификации

enum TaxCategory {
  // Capital events
  BUY = "buy",                    // покупка за фиат — не taxable сама по себе
  SELL = "sell",                  // продажа — disposal event
  SWAP = "swap",                  // обмен крипто→крипто — disposal в большинстве юрисдикций
  NFT_MINT = "nft_mint",
  NFT_SALE = "nft_sale",
  NFT_ROYALTY = "nft_royalty",
  
  // Income events
  STAKING_REWARD = "staking_reward",
  MINING_REWARD = "mining_reward",
  LENDING_INTEREST = "lending_interest",
  LIQUIDITY_FEES = "liquidity_fees",   // Uniswap LP fees
  AIRDROP = "airdrop",
  HARD_FORK = "hard_fork",
  REFERRAL = "referral",
  PLAY_TO_EARN = "play_to_earn",
  
  // Non-taxable
  TRANSFER = "transfer",              // перевод между своими кошельками
  COLLATERAL_DEPOSIT = "collateral",  // залог в DeFi lending
  COLLATERAL_RETURN = "collateral_return",
  WRAPPED_TOKEN_MINT = "wrap",        // ETH→WETH не является disposal
  WRAPPED_TOKEN_BURN = "unwrap",
  LP_DEPOSIT = "lp_deposit",          // спорно, зависит от юрисдикции
  LP_WITHDRAWAL = "lp_withdrawal",
  
  // Gas
  GAS_FEE = "gas_fee",                // может добавляться к cost basis
  
  UNCLASSIFIED = "unclassified",
}

Движок классификации

class TransactionClassifier {
  async classify(tx: UnifiedTransaction, userContext: UserContext): Promise<ClassificationResult> {
    // Применяем правила в порядке приоритета
    const rules = this.getRulesForContext(userContext);
    
    for (const rule of rules) {
      const result = await rule.apply(tx, userContext);
      if (result.matched) {
        return {
          category: result.category,
          confidence: result.confidence,
          ruleId: rule.id,
          metadata: result.metadata,
        };
      }
    }
    
    return {
      category: TaxCategory.UNCLASSIFIED,
      confidence: 0,
      requiresManualReview: true,
    };
  }
}

// Правила классификации
const CLASSIFICATION_RULES: ClassificationRule[] = [
  {
    id: "SELF_TRANSFER",
    priority: 100,
    apply: async (tx, ctx) => {
      if (tx.fromAddress && tx.toAddress) {
        const [from, to] = await Promise.all([
          ctx.isUserAddress(tx.fromAddress),
          ctx.isUserAddress(tx.toAddress),
        ]);
        if (from && to) return { matched: true, category: TaxCategory.TRANSFER, confidence: 0.95 };
      }
      return { matched: false };
    },
  },
  {
    id: "WRAPPED_TOKEN",
    priority: 90,
    apply: async (tx) => {
      const wrappedPairs = [
        ["ETH", "WETH"], ["BTC", "WBTC"], ["SOL", "SOL"], // WSOL
        ["MATIC", "WMATIC"],
      ];
      const isWrap = wrappedPairs.some(
        ([native, wrapped]) =>
          (tx.assetIn === native && tx.assetOut === wrapped) ||
          (tx.assetIn === wrapped && tx.assetOut === native)
      );
      if (isWrap) return { 
        matched: true, 
        category: tx.assetIn.startsWith("W") ? TaxCategory.WRAPPED_TOKEN_BURN : TaxCategory.WRAPPED_TOKEN_MINT,
        confidence: 0.95 
      };
      return { matched: false };
    },
  },
  {
    id: "STAKING_REWARD_PATTERN",
    priority: 85,
    apply: async (tx) => {
      // Staking reward: получаем токен без отдачи эквивалентного
      if (tx.type === "receive" && !tx.assetOut && tx.source === "staking") {
        return { matched: true, category: TaxCategory.STAKING_REWARD, confidence: 0.90 };
      }
      
      // Признаки staking reward от on-chain data
      const isStakingContract = await isKnownStakingContract(tx.fromAddress);
      if (tx.type === "receive" && isStakingContract) {
        return { matched: true, category: TaxCategory.STAKING_REWARD, confidence: 0.80 };
      }
      
      return { matched: false };
    },
  },
  {
    id: "AIRDROP_PATTERN",
    priority: 80,
    apply: async (tx) => {
      if (tx.type === "receive" && !tx.assetOut) {
        // Маленький размер, новый токен, много получателей в том же блоке
        const isMassDistribution = await checkMassDistribution(tx.txHash, tx.assetIn);
        if (isMassDistribution) {
          return { matched: true, category: TaxCategory.AIRDROP, confidence: 0.75 };
        }
      }
      return { matched: false };
    },
  },
  {
    id: "CRYPTO_SWAP",
    priority: 50,
    apply: async (tx) => {
      // Меняем одну крипту на другую (не стейблкоин на фиат)
      if (tx.assetIn && tx.assetOut && 
          !isFiat(tx.assetIn) && !isFiat(tx.assetOut) &&
          tx.assetIn !== tx.assetOut) {
        return { matched: true, category: TaxCategory.SWAP, confidence: 0.85 };
      }
      return { matched: false };
    },
  },
];

ML модель для неизвестных паттернов

# Для транзакций которые не покрываются rules-based системой
from sklearn.ensemble import RandomForestClassifier
import numpy as np

class TransactionMLClassifier:
    def predict(self, tx_features):
        # features: [amount, is_eoa_sender, is_contract_sender, 
        #            contract_type, value_in/out_ratio, time_since_last_tx, ...]
        
        features = self.extract_features(tx_features)
        prediction = self.model.predict([features])[0]
        confidence = max(self.model.predict_proba([features])[0])
        
        return { "category": prediction, "confidence": confidence }

Batch классификация и review queue

// Запрос на ручную проверку неклассифицированных транзакций
async function processUnclassifiedTransactions(userId: string) {
  const unclassified = await db.getUnclassified(userId, { limit: 50 });
  
  for (const tx of unclassified) {
    // Предлагаем вероятные варианты на основе контекста
    const suggestions = await classifier.getSuggestions(tx, { topN: 3 });
    await db.updateTransactionSuggestions(tx.id, suggestions);
  }
  
  // Уведомляем пользователя что есть транзакции для review
  if (unclassified.length > 0) {
    await notifyUserReviewNeeded(userId, unclassified.length);
  }
}

Система классификации с rules engine, ML fallback и manual review queue — 2-4 недели разработки.