Розроблення платформи токенізації активів
Токенізація активу — це представлення права власності або частки в реальному активі у вигляді токена на блокчейні. Звучить концептуально, але за цим стоїть конкретний набір юридичних та технічних проблем, які потрібно вирішити послідовно. Технологія — менша частина завдання. Юридичне оформлення, compliance, KYC/AML, вторинний обіг в межах регуляторики — це 60–70% роботи на будь-якому серйозному проекті токенізації.
Типи активів різноманітні й потребують різних підходів: нерухомість, акції SPV, боргові інструменти, твори мистецтва, інтелектуальна власність, товарні запаси. Але базові компоненти платформи — спільні.
Стандарти токенів для RWA
Звичайний ERC-20 не підходить для регульованих активів. Вам потрібні:
ERC-1400 (Security Token Standard) — розширення ERC-20 з обмеженнями передачі, примусовими переводами та управлінням документами. Розроблений під вимоги регуляторів цінних паперів. Підтримує partition'и (транші з різними правами):
// Ключові інтерфейси ERC-1400
interface IERC1400 is IERC20 {
// Перевірка можна ли виконати transfer (повертає код статусу + причину)
function canTransferByPartition(
bytes32 partition,
address from,
address to,
uint256 value,
bytes calldata data
) external view returns (byte, bytes32, bytes32);
// Transfer з даними (для compliance метаданих)
function transferByPartition(
bytes32 partition,
address to,
uint256 value,
bytes calldata data
) external returns (bytes32);
// Примусовий transfer (для регулятора або судового рішення)
function operatorTransferByPartition(
bytes32 partition,
address from,
address to,
uint256 value,
bytes calldata data,
bytes calldata operatorData
) external returns (bytes32);
// Документи прив'язані до токена (проспект, аудит, юридичні)
function getDocument(bytes32 name)
external view returns (string memory, bytes32);
}
ERC-3643 (T-REX: Token for Regulated EXchanges) — більш сучасний стандарт, розроблений Tokeny Solutions і прийнятий як основа багатьма платформами (Société Générale Forge, ABN AMRO). Включає шар ідентичності (ONCHAINID) та автоматизовані перевірки compliance:
// Приклад перевірки compliance T-REX
contract TokenCompliance {
IIdentityRegistry public identityRegistry;
ICompliance public compliance;
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal {
if (from != address(0) && to != address(0)) {
// Перевіряємо ідентичність одержувача
require(
identityRegistry.isVerified(to),
"Recipient identity not verified"
);
// Перевіряємо правила compliance
require(
compliance.canTransfer(from, to, amount),
"Transfer not compliant"
);
}
}
}
ERC-1155 для фракціональних активів — коли один актив поділяється на кілька видів прав (наприклад, будівля з різними типами приміщень або твір мистецтва з різними правами використання).
Шар ідентичності: KYC/AML On-Chain
Кожен власник токенів регульованого активу повинен бути верифікований. On-chain ідентичність складніша за просте картування адрес → bool.
ONCHAINID (ERC-734/735)
Стандарт для децентралізованої ідентичності, сумісний з T-REX:
// Контракт ідентичності (один на користувача)
interface IIdentity {
// Клейми — верифіковані твердження від видавців claims
function getClaim(bytes32 claimId)
external view returns (
uint256 topic, // тип клейма: KYC, AML, accredited investor
uint256 scheme, // метод верифікації
address issuer,
bytes memory signature,
bytes memory data,
string memory uri
);
function addClaim(
uint256 topic,
uint256 scheme,
address issuer,
bytes memory signature,
bytes memory data,
string memory uri
) external returns (bytes32 claimId);
}
// Теми клеймів для цінних паперів
uint256 constant KYC_CLAIM = 1;
uint256 constant AML_CLAIM = 2;
uint256 constant ACCREDITED_INVESTOR_CLAIM = 3;
uint256 constant COUNTRY_CLAIM = 4;
uint256 constant PROFESSIONAL_INVESTOR_CLAIM = 5;
Провайдер KYC (Sumsub, Fractal, Identix) проводить верифікацію та видає клейм з підписом. Клейм записується в контракт ONCHAINID користувача. При спробі передачі токена модуль compliance перевіряє наявність необхідних клеймів.
Обмеження за юрисдикцією
Регулятори вимагають обмежити продажі в певних юрисдикціях (наприклад, не можна продавати US-резидентам без реєстрації в SEC):
contract CountryRestrictionsCompliance {
// Дозволені коди країн (ISO 3166-1 numeric)
mapping(uint16 => bool) public allowedCountries;
// Обмеження власності для кожної країни
mapping(uint16 => uint256) public countryMaxInvestors;
mapping(uint16 => uint256) public countryCurrentInvestors;
function canTransfer(
address from,
address to,
uint256 amount
) external view returns (bool) {
uint16 recipientCountry = getInvestorCountry(to);
if (!allowedCountries[recipientCountry]) {
return false;
}
// Не перевищуємо лімітку інвесторів у країні
if (isNewInvestor(to, recipientCountry)) {
if (countryCurrentInvestors[recipientCountry] >=
countryMaxInvestors[recipientCountry]) {
return false;
}
}
return true;
}
}
Життєвий цикл токенізованого активу
Випуск
Перед мінтингом токенів:
- Юридична структура: SPV, траст або інша структура, яка володіє реальним активом
- Юридична думка про те, що токени не є незареєстрованими цінними паперами (або реєстрація)
- Проспект/пропозиція про розміщення (залежить від юрисдикції та обсягу)
- Угода про кастодію: хто зберігає документи, хто є трансфер-агентом
function mintSecurityTokens(
address investor,
uint256 amount,
bytes32 partition, // наприклад: "CLASS_A_SHARES"
bytes calldata data // посилання на хеш юридичного документа
) external onlyRole(ISSUER_ROLE) {
require(identityRegistry.isVerified(investor), "Not verified");
require(compliance.canTransfer(address(0), investor, amount), "Not compliant");
_issueByPartition(partition, investor, amount, data);
emit TokensIssued(investor, amount, partition, data);
}
Корпоративні дії
Токенізовані акції потребують обробки корпоративних подій:
Дивіденди:
contract DividendDistributor {
IERC1400 public securityToken;
IERC20 public paymentToken; // Зазвичай USDC
function distributeDividends(
uint256 totalDividend,
uint256 snapshotId
) external onlyRole(CORPORATE_ACTIONS_ROLE) {
uint256 totalSupplyAtSnapshot = securityToken.totalSupplyAt(snapshotId);
// Кожен власник отримує пропорційно
// Використовуємо snapshot для точного розрахунку (ERC20Snapshot або ERC20Votes)
uint256 dividendPerToken = totalDividend * 1e18 / totalSupplyAtSnapshot;
// Зберігаємо snapshot дивіденду для вилучення
dividendSnapshots[snapshotId] = DividendSnapshot({
totalDividend: totalDividend,
dividendPerToken: dividendPerToken,
paymentToken: address(paymentToken),
snapshotBlock: block.number
});
}
function claimDividend(uint256 snapshotId) external {
uint256 balance = securityToken.balanceOfAt(msg.sender, snapshotId);
require(balance > 0, "No balance at snapshot");
require(!claimed[msg.sender][snapshotId], "Already claimed");
claimed[msg.sender][snapshotId] = true;
uint256 amount = balance * dividendSnapshots[snapshotId].dividendPerToken / 1e18;
paymentToken.safeTransfer(msg.sender, amount);
}
}
Сплити та зворотні сплити:
function executeSplit(uint256 splitRatio) external onlyRole(CORPORATE_ACTIONS_ROLE) {
// splitRatio = 200 означає сплит 2:1 (кожен токен → 2 токена)
// splitRatio = 50 означає зворотний сплит 1:2
address[] memory holders = getAllHolders(); // ведеться окремо через події
for (uint i = 0; i < holders.length; i++) {
uint256 currentBalance = balanceOf(holders[i]);
if (splitRatio > 100) {
// Прямий сплит: мінтимо додаткові токени
_mint(holders[i], currentBalance * (splitRatio - 100) / 100);
} else {
// Зворотний сплит: спалюємо
_burn(holders[i], currentBalance * (100 - splitRatio) / 100);
}
}
emit SplitExecuted(splitRatio, block.timestamp);
}
Вторинний ринок та ліквідність
Вторинний обіг токенізованих активів — окрема проблема. На відміну від звичайних ERC-20, не можна просто лістити на Uniswap: кожен покупець повинен пройти KYC і покупка повинна пройти перевірку compliance.
Permissioned DEX — кастомний AMM або order book з вбудованим compliance gate:
contract ComplianceAwareOrderBook {
ICompliance public compliance;
struct Order {
address seller;
uint256 amount;
uint256 pricePerToken; // в USDC wei
bool isActive;
}
mapping(uint256 => Order) public orders;
function fillOrder(uint256 orderId, uint256 amount) external nonReentrant {
Order storage order = orders[orderId];
require(order.isActive, "Order not active");
// Перевірка compliance ЛИШ ПЕРЕД будь-якими transfer'ами
require(
compliance.canTransfer(order.seller, msg.sender, amount),
"Transfer not compliant"
);
uint256 cost = amount * order.pricePerToken / 1e18;
// Атомарний своп
paymentToken.safeTransferFrom(msg.sender, order.seller, cost);
securityToken.operatorTransferByPartition(
"DEFAULT",
order.seller,
msg.sender,
amount,
"",
""
);
emit OrderFilled(orderId, msg.sender, amount, cost);
}
}
Інтеграція з регульованими платформами — INX, tZERO, STO Global X приймають токени стандарту T-REX. Це готова ліквідність для емітентів без побудови власної торговельної площадки.
Оракули та оцінка активів
Для кредитування під заставу токенізованих активів потрібна on-chain ціна. На відміну від крипто-активів — немає ліквідного ринку. Рішення:
Модель верифікованого оцінювача — акредитований оцінювач підписує оцінку та публікує on-chain. Контракт приймає оцінки від N акредитованих оцінювачів, бере медіану:
contract AssetValuationOracle {
struct Valuation {
uint256 value; // в USD, 8 decimals
uint256 timestamp;
address appraiser;
bytes signature;
}
mapping(bytes32 => Valuation[]) public valuations; // assetId → оцінки
uint256 public constant MAX_VALUATION_AGE = 90 days;
uint256 public constant MIN_APPRAISERS = 2;
function getAssetValue(bytes32 assetId) external view returns (uint256) {
Valuation[] storage vals = valuations[assetId];
// Фільтруємо свіжі оцінки
uint256[] memory freshValues = new uint256[](vals.length);
uint256 freshCount = 0;
for (uint i = 0; i < vals.length; i++) {
if (block.timestamp - vals[i].timestamp <= MAX_VALUATION_AGE) {
freshValues[freshCount++] = vals[i].value;
}
}
require(freshCount >= MIN_APPRAISERS, "Insufficient fresh valuations");
return median(freshValues, freshCount);
}
}
Технологічний стек
| Компонент | Вибір | Обґрунтування |
|---|---|---|
| Стандарт токена | ERC-3643 (T-REX) | Широке прийняття в RWA, compliance вбудований |
| Ідентичність | ONCHAINID | Стандарт екосистеми T-REX |
| Провайдер KYC | Sumsub / Synaps | API + видача claims |
| Цепь розрахунків | Polygon PoS / Base | Дешево, EVM, активна RWA екосистема |
| Платіж | USDC / EURC | Circle стабільність, регуляторна чіткість |
| Зберігання документів | IPFS + Filecoin | Довгострокове зберігання юридичних документів |
Фази проекту
| Фаза | Вміст | Період |
|---|---|---|
| Юридичні та структурні | Юридична структура, вимоги compliance | 4–8 тиж |
| Основні контракти | ERC-3643 + ідентичність + модулі compliance | 4–6 тиж |
| Корпоративні дії | Дивіденди, сплити, примусовий transfer | 2–3 тиж |
| Інтеграція KYC | Реєстр ідентичності + API провайдера KYC | 2–3 тиж |
| Вторинний ринок | Order book або DEX з compliance | 3–4 тиж |
| Портал інвестора | Панель, вилучення, документи | 3–4 тиж |
| Аудит | Контракти | 3–4 тиж |
| Пілот випуску | Реальний актив у тестовому середовищі | 2–3 тиж |
Разом: 23–35 тижнів. Юридичний етап — змінна з найбільшим розкидом: залежить від типу активу, юрисдикції та наявності досвідченого securities-lawyer в команді клієнта.







