Розробка системи класифікації крипто-транзакцій
При 5000+ транзакцій за рік податкова вимагає детальну звітність. Кожна неправильно класифікована транзакція — ризик донарахувань. Для трейдерів, стейкерів і учасників DeFi розібратися в цьому вручну майже неможливо. Ми розробляємо систему, яка автоматично відносить кожну операцію до потрібного податкового типу: trade, income, airdrop або staking reward. Результат — зниження ручної праці на 80–90% і повна впевненість у звітності. Все будується на rule engine для типових випадків, ML fallback для складних і manual review queue. Отримайте консультацію — оцінимо ваш проект безкоштовно.
Як система класифікації крипто-транзакцій знижує податкові ризики?
Податкові органи все частіше запитують деталізацію крипто-операцій. У США IRS вимагає окремо звітувати airdrop і staking reward, у Німеччині — розрізняти короткострокові та довгострокові холди. Помилка в класифікації може коштувати тисяч доларів. Система використовує комбінацію правил, що перевіряються аудиторами, і ML-моделі, навченої на реальних даних. Це забезпечує точність понад 95% для типових випадків і знижує ручну роботу на 80–90%.
Як ми будуємо систему: rule engine і ML fallback
Ієрархія типів транзакцій
enum TaxCategory {
// Capital events
BUY = "buy",
SELL = "sell",
SWAP = "swap",
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",
AIRDROP = "airdrop",
HARD_FORK = "hard_fork",
REFERRAL = "referral",
PLAY_TO_EARN = "play_to_earn",
// Non-taxable
TRANSFER = "transfer",
COLLATERAL_DEPOSIT = "collateral",
COLLATERAL_RETURN = "collateral_return",
WRAPPED_TOKEN_MINT = "wrap",
WRAPPED_TOKEN_BURN = "unwrap",
LP_DEPOSIT = "lp_deposit",
LP_WITHDRAWAL = "lp_withdrawal",
// Gas
GAS_FEE = "gas_fee",
UNCLASSIFIED = "unclassified",
}
Це базова таксономія, що покриває 99% операцій. При необхідності додаються кастомні категорії під конкретний проект.
Двигун класифікації
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"],
["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) => {
if (tx.type === "receive" && !tx.assetOut && tx.source === "staking") {
return { matched: true, category: TaxCategory.STAKING_REWARD, confidence: 0.90 };
}
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-модель для невідомих патернів
Якщо жодне правило не спрацювало, підключається ML-класифікатор. Ми використовуємо RandomForest, навчений на історичних даних. Вектор ознак включає суму, типи відправника/отримувача (EOA vs контракт), відношення value in/out, час між транзакціями та інші метрики.
from sklearn.ensemble import RandomForestClassifier
import numpy as np
class TransactionMLClassifier:
def predict(self, tx_features):
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 }
ML-модель дає гіпотезу, але ми завжди даємо користувачу можливість перекласифікувати транзакцію вручну.
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);
}
if (unclassified.length > 0) {
await notifyUserReviewNeeded(userId, unclassified.length);
}
}
Транзакції з confidence < 0.9 відправляються в чергу на перевірку. Користувач бачить запропоновані категорії та підтверджує/коригує. За досвідом, у чергу потрапляє не більше 20% операцій.
Порівняння rule-based та ML-підходу
| Критерій | Rule-based | ML fallback |
|---|---|---|
| Точність для типових транзакцій | 95–98% | 85–90% |
| Швидкість обробки | <10ms | <100ms |
| Необхідні дані | On-chain + адреси користувача | Історичні розмічені дані |
| Адаптація до нових сценаріїв | Потребує додавання правил | Автоматичне перенавчання |
| Прозорість | Повна | «Чорний ящик» |
Rule-based швидший і точніший для типових випадків, ML рятує для незнайомих. Разом вони покривають 99% транзакцій.
Приклади податкової трактовки за типами транзакцій
| Тип транзакції | Податковий статус (приклад) |
|---|---|
| SWAP | Подія, що оподатковується податком на приріст капіталу |
| STAKING_REWARD | Дохід, що оподатковується як звичайний дохід |
| AIRDROP | Дохід за ринковою вартістю на момент отримання |
| TRANSFER | Не оподатковується (зміна гаманця) |
| GAS_FEE | Витрата, що зменшує оподатковувану базу |
Етапи розробки
- Аналітика — вивчаємо ваші дані, визначаємо повний перелік типів транзакцій.
- Проєктування — проєктуємо ієрархію категорій, готуємо онтологію.
- Реалізація — пишемо rule engine і ML-модуль, інтегруємо з гаманцями/біржами.
- Тестування — прогоняємо на історичних даних, коригуємо правила.
- Деплой — розгортаємо систему, налаштовуємо review queue та сповіщення.
Що входить у результат
- Rule engine з попередньо встановленими правилами під вашу юрисдикцію.
- ML-модель, донавчена на ваших даних.
- Web-дашборд для перегляду та ручної класифікації.
- REST API для інтеграції з бухгалтерськими системами.
- Документація та навчання команди.
- Підтримка протягом 6 місяців.
Як ми гарантуємо точність?
У нас 10+ років досвіду в блокчейн-розробці. За плечима понад 50 проектів з аналізу даних та автоматизації. Кожна система перед здачею проходить аудит на тестових даних. Ми надаємо гарантію на коректність класифікації для транзакцій з confidence > 0.95. У разі помилок — безкоштовне доналаштування.
Терміни та вартість
Терміни розробки: від 2 до 4 тижнів залежно від складності інтеграції. Вартість розраховується індивідуально після аналізу вашого обсягу транзакцій та вимог до класифікації. Замовте попередню оцінку — це безкоштовно.
Приклад класифікації складної транзакції
Транзакція: отримання 0.1 ETH з нового контракту, на виході 1000 UNI. Правила не спрацьовують (невідомий контракт, не масова розсилка). ML припускає airdrop з confidence 0.4. Користувач вручну класифікує як стейкінг-винагороду. Після цього коригування ми можемо додати нове правило для даного пулу.Зв'яжіться з нами для безкоштовної консультації. Отримайте демонстрацію системи — оцінимо ваш проект.







