Разработка системы multi-approval для институциональных кошельков
Институциональные клиенты — фонды, DAO-казначейства, хедж-фонды — не могут позволить себе single point of failure в управлении активами. Один скомпрометированный ключ не должен давать полный контроль над средствами. Multi-approval система — это не просто multisig на смарт-контракте, это комплексная инфраструктура: политики подписания, роли участников, аудит-трейл, интеграции с hardware security modules и процессы восстановления.
Архитектурные варианты
Существует несколько уровней реализации multi-approval, и выбор зависит от требований клиента.
On-chain multisig
Gnosis Safe (теперь Safe{Core}) — де-факто стандарт для институциональных кошельков. Смарт-контракт хранит список owners и пороговое значение (threshold). Транзакция исполняется только при наличии threshold подписей от owners.
Архитектура Safe:
- GnosisSafe.sol — основной контракт, хранит owners mapping, threshold, nonce
- SafeProxy — минималистичный proxy, делегирующий вызовы к singleton implementation
- GnosisSafeProxyFactory — создаёт новые Safe кошельки через CREATE2 (детерминированный адрес)
- Modules — расширения функциональности: Recovery Module, Allowance Module, Guard Module
Вместо прямого использования Safe SDK можно строить поверх него собственную систему управления. Safe транзакция требует накопления подписей off-chain и финального execute вызова:
// Структура транзакции Safe
struct SafeTx {
address to;
uint256 value;
bytes data;
Enum.Operation operation; // Call или DelegateCall
uint256 safeTxGas;
uint256 baseGas;
uint256 gasPrice;
address gasToken;
address refundReceiver;
uint256 nonce;
}
Off-chain политики с on-chain исполнением
Для более сложных сценариев — time-locks, spending limits, whitelist адресов — используется комбинация: off-chain policy engine проверяет транзакцию до сбора подписей, затем collected signatures передаются в Safe для исполнения.
Fireblocks, BitGo реализуют именно эту модель: транзакция проходит через policy engine (который может требовать одобрения от конкретных людей, в конкретные временные окна, с лимитами на сумму) до того, как дойдёт до on-chain.
Детальная архитектура системы
Компоненты
Policy Engine — сервис, который хранит и применяет правила:
- Whitelist адресов-получателей
- Spending limits (дневной, недельный лимит по токену)
- Time-based rules (транзакции только в рабочие часы UTC)
- Amount thresholds (до $10k — 2 подписи, свыше $100k — 5 подписей)
- Asset-specific rules (операции с определёнными токенами требуют одобрения CFO)
Approval Workflow Engine — управляет состоянием запросов на транзакции:
PENDING_APPROVAL → COLLECTING_SIGNATURES → READY_TO_EXECUTE → EXECUTED
↘ REJECTED ↙
Каждый переход состояния логируется с timestamp и actor_id. Это обязательно для compliance.
Signature Aggregator — собирает подписи от approvers. Подписи EIP-712 (или EIP-1271 для smart contract signers). Хранит частичные подписи до достижения threshold.
Notification Service — уведомления approvers (email, Telegram, Slack) при появлении транзакции на подпись. Включает deep-link для быстрого одобрения.
Hardware Security Module (HSM) интеграция — для крупных институтов ключи approvers хранятся в HSM (AWS CloudHSM, Azure Dedicated HSM, Thales). Подпись происходит внутри HSM без экспорта private key.
База данных
CREATE TABLE approval_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
safe_address VARCHAR(42) NOT NULL,
to_address VARCHAR(42) NOT NULL,
value NUMERIC(78, 0),
data TEXT,
operation SMALLINT DEFAULT 0,
nonce BIGINT NOT NULL,
safe_tx_hash VARCHAR(66) UNIQUE NOT NULL,
status VARCHAR(32) NOT NULL DEFAULT 'pending',
created_by UUID REFERENCES users(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ,
metadata JSONB
);
CREATE TABLE approvals (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
request_id UUID REFERENCES approval_requests(id),
approver_id UUID REFERENCES users(id),
signature VARCHAR(132) NOT NULL,
signed_at TIMESTAMPTZ DEFAULT NOW(),
device_type VARCHAR(32), -- hardware_wallet, hsm, software
ip_address INET
);
CREATE TABLE policies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
rules JSONB NOT NULL,
threshold INTEGER NOT NULL,
owners JSONB NOT NULL, -- список approvers
is_active BOOLEAN DEFAULT TRUE
);
Процесс создания транзакции
- Инициатор создаёт запрос через API или UI
- Policy Engine проверяет транзакцию против активных политик
- Если политика нарушена — reject с объяснением
- Если ОК — создаётся
ApprovalRequestсо статусомpending - Вычисляется
safeTxHash(детерминированный хеш Safe транзакции) - Approvers получают уведомления
- Каждый approver подписывает
safeTxHashсвоим ключом - При достижении threshold — статус меняется на
ready_to_execute - Relayer отправляет транзакцию on-chain с aggregated signatures
// Вычисление safeTxHash
async function computeSafeTxHash(
safeAddress: string,
tx: SafeTx,
chainId: number
): Promise<string> {
const domain = {
chainId,
verifyingContract: safeAddress,
};
const types = {
SafeTx: [
{ name: "to", type: "address" },
{ name: "value", type: "uint256" },
{ name: "data", type: "bytes" },
{ name: "operation", type: "uint8" },
{ name: "safeTxGas", type: "uint256" },
{ name: "baseGas", type: "uint256" },
{ name: "gasPrice", type: "uint256" },
{ name: "gasToken", type: "address" },
{ name: "refundReceiver", type: "address" },
{ name: "nonce", type: "uint256" },
],
};
return ethers.TypedDataEncoder.hash(domain, types, tx);
}
Роли и права доступа
Типичная ролевая модель для институционального кошелька:
| Роль | Права |
|---|---|
| Admin | Управление политиками, добавление/удаление owners |
| Initiator | Создание запросов на транзакции |
| Approver | Подписание транзакций |
| Executor | Отправка on-chain после сбора подписей |
| Auditor | Read-only доступ ко всему аудит-трейлу |
| Observer | Просмотр балансов и статусов |
Роли могут комбинироваться. Для крупных организаций — разделение Initiator и Approver обязательно (четыре глаза).
Time-lock и emergency
Time-lock. Для транзакций свыше определённого порога — обязательная задержка перед исполнением (например, 24 часа). В этот период другие owners могут отменить транзакцию. Реализуется через TimelockController OpenZeppelin или кастомный Safe Module.
Emergency pause. Если обнаружена компрометация — возможность заморозить все исходящие транзакции. Требует N-of-M подписей от Guardian ключей (которые хранятся отдельно, у независимых кастодианов).
Social recovery. Если quorum owners недоступны (потеря ключей, смерть) — процедура восстановления через набор Recovery owners. Safe Recovery Module поддерживает это out of the box.
HSM интеграция
Для AWS CloudHSM:
import * as pkcs11js from "pkcs11js";
class HSMSigner {
private pkcs11: pkcs11js.PKCS11;
async sign(txHash: Buffer, keyLabel: string): Promise<Buffer> {
const session = this.pkcs11.C_OpenSession(this.slotId, pkcs11js.CKF_SERIAL_SESSION);
this.pkcs11.C_Login(session, pkcs11js.CKU_USER, this.pin);
const privateKey = this.findKeyByLabel(session, keyLabel);
this.pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_ECDSA }, privateKey);
const signature = this.pkcs11.C_Sign(session, txHash, Buffer.alloc(64));
this.pkcs11.C_Logout(session);
this.pkcs11.C_CloseSession(session);
return this.convertToEthSignature(signature);
}
}
Ключевое: private key никогда не покидает HSM. Операция подписи выполняется внутри защищённого железа с физическим tamper-protection.
Аудит и compliance
Каждое действие логируется неизменяемо:
- Создание запроса (кто, когда, откуда)
- Каждое одобрение/отклонение (кто, когда, с какого устройства)
- Исполнение on-chain (txHash)
- Изменения политик
Для финансовых организаций — экспорт в форматах, совместимых с аудиторами (CSV, PDF с цифровой подписью). Интеграция с SIEM-системами (Splunk, Datadog) через webhook.
Стек разработки
Backend: Node.js + TypeScript, PostgreSQL, Redis (очереди), Bull (job processing) Smart contracts: Safe{Core} SDK, кастомные Safe Modules на Solidity HSM: AWS CloudHSM SDK, PKCS#11 Frontend: React + wagmi, Safe{Core} Protocol Kit Notifications: SendGrid, Telegram Bot API, Slack Webhooks Infrastructure: AWS ECS, RDS, CloudHSM cluster
Сроки
- Базовая система (Safe + workflow + UI): 8-10 недель
- С HSM интеграцией: +3-4 недели
- С compliance/audit экспортом: +2 недели
- Security audit: обязателен, +3-6 недель
Итого production-ready система с HSM и аудитом: 4-5 месяцев.







