Разработка системы социальных токенов
Социальные токены — это один из немногих Web3-продуктов, где технические возможности блокчейна нашли действительно органичный use case. Создатель контента, инфлюенсер, DAO или сообщество выпускает токен, который представляет доступ, участие и экономическую связь с этим создателем. Проблема большинства существующих реализаций — в том, что токен существует изолированно: нельзя "использовать" его за пределами одного приложения, economics слабые (зачем холдить?), механизмы распределения не создают настоящую aligned community. Правильная система социальных токенов решает эти три проблемы комплексно.
Типология социальных токенов
Перед проектированием нужно определить тип:
Creator tokens — персональный токен конкретного человека (музыканта, художника, Twitch-стримера). Холдеры получают доступ к эксклюзивному контенту, backstage, early access. Примеры: Rally.io, Roll, Friends With Benefits ($FWB).
Community/DAO tokens — токен сообщества с governance правами. Холдеры голосуют по решениям, разделяют treasury, управляют направлением проекта.
Social graph tokens — токены, отражающие репутацию и социальные связи (Lens Protocol, Farcaster). Soulbound или частично transferable.
Access tokens — простейшая форма: токен как ключ к закрытому чату, платформе, серверу Discord. Технически NFT или ERC-20 с минимальным балансом.
Token Bonding Curves: экономика creator tokens
Простая фиксированная цена не работает для creator tokens — нет механизма автоматического price discovery и ликвидности. Bonding curve — математическая функция, которая определяет цену токена в зависимости от текущего supply:
Price = f(Supply)
При покупке токены mint'ятся, резерв (ETH/USDC) пополняется. При продаже — токены burn'ятся, резерв выдаётся. Без orderbook, без контрагента.
Линейная bonding curve
contract LinearBondingCurve {
// Price = slope * supply + initialPrice
uint256 public slope; // in wei per token^2 / 1e18
uint256 public initialPrice; // стартовая цена
uint256 public totalSupply;
uint256 public reserveBalance;
IERC20 public reserveToken; // USDC
IERC20 public bondedToken;
function getBuyPrice(uint256 tokenAmount) public view returns (uint256) {
// интеграл от currentSupply до (currentSupply + tokenAmount)
// area under linear curve = slope/2 * (s1^2 - s0^2) + initialPrice * (s1 - s0)
uint256 s0 = totalSupply;
uint256 s1 = totalSupply + tokenAmount;
uint256 area = (slope * (s1 * s1 - s0 * s0)) / (2 * 1e18);
uint256 baseCost = initialPrice * tokenAmount / 1e18;
return area + baseCost;
}
function getSellReturn(uint256 tokenAmount) public view returns (uint256) {
require(tokenAmount <= totalSupply, "Not enough supply");
uint256 s0 = totalSupply - tokenAmount;
uint256 s1 = totalSupply;
uint256 area = (slope * (s1 * s1 - s0 * s0)) / (2 * 1e18);
uint256 baseCost = initialPrice * tokenAmount / 1e18;
// spread: продажа возвращает чуть меньше чем покупка (creator fee)
uint256 gross = area + baseCost;
return gross * (10000 - creatorFee) / 10000;
}
function buy(uint256 tokenAmount, uint256 maxCost) external nonReentrant {
uint256 cost = getBuyPrice(tokenAmount);
require(cost <= maxCost, "Slippage exceeded");
reserveToken.safeTransferFrom(msg.sender, address(this), cost);
reserveBalance += cost;
totalSupply += tokenAmount;
// mint tokens to buyer
IMintable(address(bondedToken)).mint(msg.sender, tokenAmount);
// creator fee из spread идёт создателю
uint256 creatorShare = cost * creatorFeeRate / 10000;
reserveToken.safeTransfer(creatorAddress, creatorShare);
emit TokensBought(msg.sender, tokenAmount, cost);
}
}
Sigmoid curve для более стабильного роста
Линейная кривая создаёт чрезмерный рост цены. Sigmoid (S-образная) кривая лучше отражает реальную adoption dynamics: медленный рост на старте, быстрый в середине, plateau при насыщении:
Price = maxPrice / (1 + e^(-k * (supply - inflection)))
Реализация sigmoid on-chain требует аппроксимации — полноценный exp() газово дорог. Используются кусочно-линейные аппроксимации или предвычисленные lookup tables.
Access и gating механизмы
Токен должен реально что-то открывать. Типичные механизмы:
On-chain gating через балансы
// Проверка на frontend (не безопасна для критичного контента)
const hasAccess = useToken({
address: creatorTokenAddress,
functionName: "balanceOf",
args: [userAddress],
});
return hasAccess >= MINIMUM_BALANCE;
// Проверка на backend (надёжная версия)
app.middleware("/exclusive/*", async (req, res, next) => {
const { address, signature, message } = req.headers;
// верифицируем подпись (SIWE — Sign In With Ethereum)
const session = await verifySiwe(message, signature, address);
if (!session.valid) return res.status(401).json({ error: "Invalid signature" });
// проверяем баланс токена на-chain
const balance = await provider.readContract({
address: creatorTokenAddress,
abi: erc20Abi,
functionName: "balanceOf",
args: [session.address],
});
if (balance < MINIMUM_BALANCE) {
return res.status(403).json({ error: "Insufficient token balance" });
}
next();
});
NFT-based memberships (ERC-1155)
Вместо количества fungible токенов — specific NFT за разные уровни членства:
contract CreatorMembership is ERC1155 {
uint256 public constant BRONZE = 1;
uint256 public constant SILVER = 2;
uint256 public constant GOLD = 3;
uint256 public constant LIFETIME = 4;
mapping(uint256 => uint256) public membershipPrice; // в USDC
mapping(uint256 => uint256) public membershipDuration; // в секундах
mapping(address => mapping(uint256 => uint256)) public membershipExpiry;
function purchaseMembership(uint256 tierId) external {
require(membershipPrice[tierId] > 0, "Invalid tier");
usdc.safeTransferFrom(msg.sender, creatorAddress, membershipPrice[tierId]);
uint256 expiry;
if (tierId == LIFETIME) {
expiry = type(uint256).max;
} else {
expiry = block.timestamp + membershipDuration[tierId];
}
membershipExpiry[msg.sender][tierId] = expiry;
_mint(msg.sender, tierId, 1, "");
}
function hasActiveMembership(address user, uint256 tierId) public view returns (bool) {
return membershipExpiry[user][tierId] > block.timestamp;
}
// memberships non-transferable по дефолту
function _beforeTokenTransfer(...) internal override {
require(from == address(0) || to == address(0), "Membership non-transferable");
}
}
Интеграция с социальными протоколами
Современная система социальных токенов не должна существовать изолированно. Интеграция с open social protocols:
Lens Protocol (Polygon) — on-chain social graph. Follow NFT, publication NFT, collect NFT. Creator token можно привязать к Lens profile: только держатели токена могут комментировать или получают скидку при collect.
Farcaster (Base/Optimism) — decentralized social network с on-chain идентификацией. Farcaster Frames позволяют встраивать интерактивные компоненты прямо в посты — включая покупку creator tokens без выхода из приложения.
// Farcaster Frame для покупки creator tokens
app.post("/frames/buy-token", async (req, res) => {
const { trustedData } = req.body;
const { fid, buttonIndex, inputText } = await validateFrameMessage(trustedData);
const amount = parseInt(inputText) || 1;
const price = await getCurvePrice(amount);
// формируем transaction calldata для direct mint
const txData = encodeFunctionData({
abi: bondingCurveAbi,
functionName: "buy",
args: [BigInt(amount * 1e18), BigInt(price * 1.01 * 1e6)], // 1% slippage
});
return res.json({
type: "tx",
chainId: "eip155:8453", // Base
method: "eth_sendTransaction",
params: {
abi: bondingCurveAbi,
to: bondingCurveAddress,
data: txData,
}
});
});
Токеномика и механики удержания
Технически правильная система не гарантирует adoption. Важны токеномические механики:
Revenue sharing: процент от доходов создателя (merchandise, стриминг, консультации) автоматически распределяется держателям через on-chain split контракт (0xSplits). Это создаёт реальный incentive держать токен.
Exclusive access layering: не бинарный access (есть/нет), а градация: 1 токен = базовый доступ, 10 токенов = приоритетный чат, 100 токенов = advisory board access. Создаёт стимул накапливать.
Governance над creator decisions: держатели голосуют по некоторым решениям создателя — список трекинга, тема следующего обучающего курса, направление DAO. Это создаёт engaged community, а не просто инвесторов.
Soul-bound reputation layer поверх transferable tokens: некоторые ачивменты (первые 100 держателей, участие в конкретном голосовании) выдаются как non-transferable badges. Transferable token отражает экономический интерес, soulbound badge — историю участия.
Платформенная инфраструктура
| Компонент | Технологии |
|---|---|
| Token contracts | ERC-20 + bonding curve / ERC-1155 memberships |
| Social layer | Lens Protocol integration / custom social graph |
| Content gating | SIWE auth + on-chain balance check |
| Fan dashboard | Next.js + wagmi, real-time через Alchemy webhooks |
| Creator dashboard | Аналитика продаж, управление benefits, сплит доходов |
| Notifications | Push Protocol (EPNS) — web3-native нотификации |
| Payments | Stablecoin (USDC) + native token для minimize volatility |
Push Protocol (ранее EPNS) — важная деталь: он позволяет отправлять нотификации wallet адресам через web3-нативный канал. Важно для уведомлений о новом контенте, голосованиях и распределении дохода без email.







