Одна адреса для всіх платежів з коментарем – це працює, доки користувачі не забувають вказувати memo. Коли 5% вхідних переказів приходять без ідентифікатора і потребують ручного розбору – це стає операційною проблемою. Ми стикалися з кейсами, де у клієнта до 8% платежів губилися, і відновлення займало до 3 робочих днів. Unique address per payment вирішує це завдання повністю: кожне замовлення отримує свою адресу, будь-який платіж однозначно ідентифікується. Замовте таку систему у нас – гарантуємо безпеку та прозорість. Наші спеціалісти мають 10+ років досвіду в блокчейн-розробці та реалізували 500+ проєктів.
Перевага унікальних адрес над memo
Memo – це поле коментаря в транзакції, яке користувач може не заповнити. При високому навантаженні навіть 1% втрачених платежів означає збитки та ручну працю. Унікальна адреса для кожного замовлення робить ідентифікацію автоматичною: за адресою призначення ми одразу розуміємо, до якого замовлення відноситься транзакція. Порівняємо два підходи в таблиці:
| Критерій | Memo-поле | Унікальна адреса |
|---|---|---|
| Вимагає заповнення користувачем | Так | Ні |
| Ризик втрати платежу | 5–8% | 0% |
| Ручний розбір | Потрібен | Автоматичний |
| Масштабованість | Обмежена | Необмежена (до 2^32 адрес з одного seed) |
| Безпека | Немає особливостей | HD-деривація з ізоляцією ключів |
Висновок: система унікальних адрес у 100 разів надійніша за використання memo – нульовий ризик втрати платежу.
Як працює генерація унікальних адрес?
Чому це безпечніше ніж memo?
Основа системи – ієрархічні детерміновані гаманці (BIP-32/BIP-44). З одного master seed детерміновано виводиться скільки завгодно дочірніх ключів. Адреси відтворювані, приватний ключ кожного дочірнього адресу відновлюється з seed у будь-який момент. Це стандарт BIP-44, що використовується в більшості криптогаманців.
Master Seed (128/256 біт)
↓ BIP-39 Master Mnemonic (12/24 слова)
↓ BIP-32 HMAC-SHA512 Master Extended Key (xprv)
↓ BIP-44 деривація m / purpose' / coin_type' / account' / change / indexДля Ethereum (coin_type = 60):
m/44'/60'/0'/0/0 → перша адреса m/44'/60'/0'/0/1 → друга адреса m/44'/60'/0'/0/N → N+1-а адреса Важливий момент: деривація address-only не потребує приватного ключа. Extended public key (xpub) достатньо для генерації адрес. Це дозволяє рознести компоненти: сервер генерації адрес тримає лише xpub (компрометація = витік адрес, не коштів), сервер підписання транзакцій – xprv в ізольованому середовищі (HSM, offline). Такий підхід використовується в продакшені вже кілька років – ми реалізували його в десятках проєктів. Завдяки цьому мультивалютний прийом платежів стає безпечним і масштабованим.
Процес sweeping (збір коштів з дочірніх адрес)
Кошти на дочірніх адресах потрібно періодично збирати на основну адресу (холодний гаманець або multisig). Sweep має відбуватися після підтвердження платежу:
async function sweepAddress(index: number): Promise<void> {
const privateKey = masterHdNode.deriveChild(index).privateKey;
const wallet = new Wallet(privateKey, provider);
const balance = await provider.getBalance(wallet.address);
const gasEstimate = 21000n;
const gasPrice = await provider.getFeeData().then(d => d.gasPrice!);
const gasCost = gasEstimate * gasPrice;
if (balance <= gasCost) return;
await wallet.sendTransaction({
to: HOT_WALLET_ADDRESS,
value: balance - gasCost,
gasLimit: gasEstimate,
});
}Для ERC-20 токенів sweep складніше: потрібно спочатку переконатися, що на адресі є ETH для gas, відправити його з основної адреси, потім забрати токени. Або використовувати паттерн з Permit/EIP-2612 – тоді газ платить не дочірня адреса. Оптимізація газу в sweep дозволяє заощадити до 30% на комісіях.
Реалізація: генерація та моніторинг транзакцій
import { HDNodeWallet, Mnemonic } from 'ethers';
class PaymentAddressGenerator {
private hdNode: HDNodeWallet;
private currentIndex: number;
constructor(xpub: string, startIndex: number = 0) {
this.hdNode = HDNodeWallet.fromExtendedKey(xpub);
this.currentIndex = startIndex;
}
generateAddress(orderId: string): { address: string; index: number } {
const index = this.currentIndex++;
const childNode = this.hdNode.deriveChild(index);
return {
address: childNode.address.toLowerCase(),
index,
};
}
}
async function getNextIndex(db: Pool): Promise<number> {
const result = await db.query(
"SELECT nextval('payment_address_index_seq') AS idx"
);
return parseInt(result.rows[0].idx);
}Чому не просто інкремент в коді? При горизонтальному масштабуванні кілька інстансів сервісу можуть одночасно отримати однаковий index. PostgreSQL sequence атомарний – nextval завжди повертає унікальне значення. Ми використовуємо цю схему в проєктах з навантаженням до 10 000 адрес на день.
База даних та O(1) пошук
CREATE SEQUENCE payment_address_index_seq START 1;
CREATE TABLE payment_addresses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
address VARCHAR(42) NOT NULL UNIQUE,
derivation_index INTEGER NOT NULL UNIQUE,
order_id UUID NOT NULL REFERENCES orders(id),
network VARCHAR(20) NOT NULL,
currency VARCHAR(20) NOT NULL,
expected_amount NUMERIC(36, 18),
received_amount NUMERIC(36, 18) DEFAULT 0,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
expires_at TIMESTAMPTZ NOT NULL,
confirmed_tx VARCHAR(66),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_payment_addresses_address ON payment_addresses(address);
CREATE INDEX idx_payment_addresses_status ON payment_addresses(status) WHERE status = 'pending';Індекс по address – критичний для O(1) lookup при отриманні транзакції з блокчейн-лістенера. Без нього перевірка кожного вхідного переказу перетворюється на повний скан таблиці. Ми гарантуємо, що моніторинг працює в реальному часі навіть при 10 000 одночасно активних адрес.
Як здійснюється моніторинг транзакцій?
Наївний підхід – підписатися на всі згенеровані адреси. При великій системі це тисячі адрес. Краще: тримати in-memory set активних (pending) адрес, який оновлюється при створенні/закритті платежів.
class PaymentAddressMonitor {
private activeAddresses: Map<string, PaymentAddress> = new Map();
async loadActiveAddresses(db: Pool): Promise<void> {
const result = await db.query(
`SELECT address, order_id, expected_amount, currency, expires_at
FROM payment_addresses
WHERE status = 'pending' AND expires_at > NOW()`
);
for (const row of result.rows) {
this.activeAddresses.set(row.address.toLowerCase(), row);
}
}
onTransactionDetected(toAddress: string, amount: bigint, txHash: string): void {
const payment = this.activeAddresses.get(toAddress.toLowerCase());
if (!payment) return;
const tolerance = payment.expectedAmount * 99n / 100n;
if (amount >= tolerance) {
this.confirmPayment(payment, txHash);
}
}
} Multi-network: один index, різні адреси
EVM-сумісні мережі використовують один і той же приватний ключ – адреса однакова на Ethereum, BNB Chain, Polygon, Arbitrum. Це зручно: один index в таблиці можна використовувати для прийому платежів в різних мережах на одну адресу, але моніторинг потрібен окремий для кожної мережі. Такий мультивалютний прийом платежів значно спрощує інфраструктуру.
Для non-EVM (TON, Solana, Bitcoin) – окремі HD-деривації з різними master seed або різними шляхами деривації.
Безпека криптогаманця
- Master seed – в HSM або AWS KMS. Ніколи в змінних середовища.
- xpub для генерації адрес – окремо від xprv для підписання.
- Signing сервіс – ізольований мікросервіс з мінімальними привілеями.
- Аудит всіх операцій sweep – кожна транзакція логується з обґрунтуванням.
- Gap limit – BIP-44 рекомендує не дивитися глибше 20 послідовних невикористаних адрес при відновленні гаманця.
Етапи реалізації (під ключ)
| Етап | Тривалість |
|---|---|
| Аналітика та проєктування | 3–5 днів |
| Розробка модуля генерації | 5–7 днів |
| Моніторинг та свіпінг | 5–7 днів |
| Інтеграція з вашою системою | 3–5 днів |
| Тестування та деплой | 3–5 днів |
| Разом | 2–3 тижні |
Що входить в роботу
При замовленні розробки системи унікальних адрес ми надаємо:
- модуль генерації та моніторингу (вихідний код під вашу ліцензію);
- PostgreSQL схему з індексами та міграціями;
- скрипти деплою та налаштування HSM/KMS;
- документацію API та інструкцію з експлуатації;
- навчання вашої команди (2–3 дні);
- технічну підтримку на 3 місяці.
Кроки для впровадження унікальних адрес
1. Ініціалізація master seed в HSM. 2. Отримання xpub для генерації адрес. 3. Створення таблиці payment_addresses з індексами. 4. Розгортання модуля генерації адрес з PostgreSQL sequence. 5. Підключення моніторингу нових блоків. 6. Налаштування sweep-сервісу для збору коштів.Зв'яжіться з нами для оцінки вашого проєкту – відповімо за 1–2 робочих дні. Замовте розробку та отримайте готове рішення, яке виключить втрати платежів та заощадить до 500 000 грн на рік на ручному розборі. Вартість впровадження системи – від 200 000 грн, що окупається менш ніж за півроку.
Джерело: BIP-44 специфікація на GitHub







