Перейти к основному содержимому

5 записей с тегом "руководство"

Посмотреть все теги

Создание децентрализованного шифрования с @mysten/seal: Руководство для разработчиков

· 13 мин. чтения
Dora Noda
Software Engineer

Конфиденциальность становится общественной инфраструктурой. В 2025 году разработчикам нужны инструменты, которые сделают шифрование таким же простым, как хранение данных. Seal от Mysten Labs предоставляет именно это — децентрализованное управление секретами с контролем доступа в блокчейне. Это руководство научит вас создавать безопасные Web3-приложения, используя шифрование на основе идентификаторов, пороговую безопасность и программируемые политики доступа.


Введение: Почему Seal важен для Web3

Традиционные облачные приложения полагаются на централизованные системы управления ключами, где один провайдер контролирует доступ к зашифрованным данным. Хотя это удобно, это создает опасные единые точки отказа. Если провайдер скомпрометирован, отключается или решает ограничить доступ, ваши данные становятся недоступными или уязвимыми.

Seal полностью меняет эту парадигму. Разработанный Mysten Labs для блокчейна Sui, Seal — это децентрализованный сервис управления секретами (DSM), который обеспечивает:

  • Шифрование на основе идентификаторов, при котором контент защищается до того, как покинет вашу среду
  • Пороговое шифрование, которое распределяет доступ к ключам между несколькими независимыми узлами
  • Контроль доступа в блокчейне с временными блокировками, токен-гейтингом и настраиваемой логикой авторизации
  • Независимый от хранилища дизайн, который работает с Walrus, IPFS или любым другим решением для хранения

Независимо от того, создаете ли вы безопасные приложения для обмена сообщениями, платформы с ограниченным доступом к контенту или переводы активов с временной блокировкой, Seal предоставляет необходимые криптографические примитивы и инфраструктуру контроля доступа.


Начало работы

Предварительные требования

Прежде чем приступить к работе, убедитесь, что у вас есть:

  • Установленный Node.js 18+
  • Базовое знакомство с TypeScript/JavaScript
  • Кошелек Sui для тестирования (например, Sui Wallet)
  • Понимание концепций блокчейна

Установка

Установите SDK Seal через npm:

npm install @mysten/seal

Вам также понадобится Sui SDK для взаимодействия с блокчейном:

npm install @mysten/sui

Настройка проекта

Создайте новый проект и инициализируйте его:

mkdir seal-tutorial
cd seal-tutorial
npm init -y
npm install @mysten/seal @mysten/sui typescript @types/node

Создайте простую конфигурацию TypeScript:

// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}

Основные концепции: Как работает Seal

Прежде чем писать код, давайте разберемся в архитектуре Seal:

1. Шифрование на основе идентификаторов (IBE)

В отличие от традиционного шифрования, где вы шифруете данные с помощью публичного ключа, IBE позволяет шифровать данные для идентификатора (например, адреса электронной почты или адреса Sui). Получатель может расшифровать данные только в том случае, если он может доказать, что контролирует этот идентификатор.

2. Пороговое шифрование

Вместо того чтобы доверять одному серверу ключей, Seal использует t-из-n пороговые схемы. Вы можете настроить 3 из 5 серверов ключей, что означает, что любые 3 сервера могут сотрудничать для предоставления ключей дешифрования, но 2 или меньше не могут.

3. Контроль доступа в блокчейне

Политики доступа обеспечиваются смарт-контрактами Sui. Прежде чем сервер ключей предоставит ключи дешифрования, он проверяет, соответствует ли запрашивающий требованиям политики в блокчейне (владение токенами, временные ограничения и т. д.).

4. Сеть серверов ключей

Распределенные серверы ключей проверяют политики доступа и генерируют ключи дешифрования. Эти серверы управляются различными сторонами для обеспечения отсутствия единой точки контроля.


Базовая реализация: Ваше первое приложение Seal

Давайте создадим простое приложение, которое шифрует конфиденциальные данные и контролирует доступ через политики блокчейна Sui.

Шаг 1: Инициализация клиента Seal

// src/seal-client.ts
import { SealClient } from "@mysten/seal";
import { SuiClient } from "@mysten/sui/client";

export async function createSealClient() {
// Initialize Sui client for testnet
const suiClient = new SuiClient({
url: "https://fullnode.testnet.sui.io",
});

// Configure Seal client with testnet key servers
const sealClient = new SealClient({
suiClient,
keyServers: [
"https://keyserver1.seal-testnet.com",
"https://keyserver2.seal-testnet.com",
"https://keyserver3.seal-testnet.com",
],
threshold: 2, // 2-of-3 threshold
network: "testnet",
});

return { sealClient, suiClient };
}

Шаг 2: Простое шифрование/дешифрование

// src/basic-encryption.ts
import { createSealClient } from "./seal-client";

async function basicExample() {
const { sealClient } = await createSealClient();

// Data to encrypt
const sensitiveData = "This is my secret message!";
const recipientAddress =
"0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";

try {
// Encrypt data for a specific Sui address
const encryptedData = await sealClient.encrypt({
data: Buffer.from(sensitiveData, "utf-8"),
recipientId: recipientAddress,
// Optional: add metadata
metadata: {
contentType: "text/plain",
timestamp: Date.now(),
},
});

console.log("Encrypted data:", {
ciphertext: encryptedData.ciphertext.toString("base64"),
encryptionId: encryptedData.encryptionId,
});

// Later, decrypt the data (requires proper authorization)
const decryptedData = await sealClient.decrypt({
ciphertext: encryptedData.ciphertext,
encryptionId: encryptedData.encryptionId,
recipientId: recipientAddress,
});

console.log("Decrypted data:", decryptedData.toString("utf-8"));
} catch (error) {
console.error("Encryption/decryption failed:", error);
}
}

basicExample();

Контроль доступа с помощью смарт-контрактов Sui

Настоящая мощь Seal заключается в программируемом контроле доступа. Давайте создадим пример шифрования с временной блокировкой, где данные могут быть расшифрованы только по истечении определенного времени.

Шаг 1: Развертывание контракта контроля доступа

Сначала нам нужен смарт-контракт Move, который определяет нашу политику доступа:

// contracts/time_lock.move
module time_lock::policy {
use sui::clock::{Self, Clock};
use sui::object::{Self, UID};
use sui::tx_context::{Self, TxContext};

public struct TimeLockPolicy has key, store {
id: UID,
unlock_time: u64,
authorized_user: address,
}

public fun create_time_lock(
unlock_time: u64,
authorized_user: address,
ctx: &mut TxContext
): TimeLockPolicy {
TimeLockPolicy {
id: object::new(ctx),
unlock_time,
authorized_user,
}
}

public fun can_decrypt(
policy: &TimeLockPolicy,
user: address,
clock: &Clock
): bool {
let current_time = clock::timestamp_ms(clock);
policy.authorized_user == user && current_time >= policy.unlock_time
}
}

Шаг 2: Интеграция с Seal

// src/time-locked-encryption.ts
import { createSealClient } from "./seal-client";
import { TransactionBlock } from "@mysten/sui/transactions";

async function createTimeLocked() {
const { sealClient, suiClient } = await createSealClient();

// Create access policy on Sui
const txb = new TransactionBlock();

const unlockTime = Date.now() + 60000; // Unlock in 1 minute
const authorizedUser =
"0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";

txb.moveCall({
target: "time_lock::policy::create_time_lock",
arguments: [txb.pure(unlockTime), txb.pure(authorizedUser)],
});

// Execute transaction to create policy
const result = await suiClient.signAndExecuteTransactionBlock({
transactionBlock: txb,
signer: yourKeypair, // Your Sui keypair
});

const policyId = result.objectChanges?.find(
(change) => change.type === "created",
)?.objectId;

// Now encrypt with this policy
const sensitiveData = "This will unlock in 1 minute!";

const encryptedData = await sealClient.encrypt({
data: Buffer.from(sensitiveData, "utf-8"),
recipientId: authorizedUser,
accessPolicy: {
policyId,
policyType: "time_lock",
},
});

console.log("Time-locked data created. Try decrypting after 1 minute.");

return {
encryptedData,
policyId,
unlockTime,
};
}

Практические примеры

Пример 1: Приложение для безопасного обмена сообщениями

// src/secure-messaging.ts
import { createSealClient } from "./seal-client";

class SecureMessenger {
private sealClient: any;

constructor(sealClient: any) {
this.sealClient = sealClient;
}

async sendMessage(
message: string,
recipientAddress: string,
senderKeypair: any,
) {
const messageData = {
content: message,
timestamp: Date.now(),
sender: senderKeypair.toSuiAddress(),
messageId: crypto.randomUUID(),
};

const encryptedMessage = await this.sealClient.encrypt({
data: Buffer.from(JSON.stringify(messageData), "utf-8"),
recipientId: recipientAddress,
metadata: {
type: "secure_message",
sender: senderKeypair.toSuiAddress(),
},
});

// Store encrypted message on decentralized storage (Walrus)
return this.storeOnWalrus(encryptedMessage);
}

async readMessage(encryptionId: string, recipientKeypair: any) {
// Retrieve from storage
const encryptedData = await this.retrieveFromWalrus(encryptionId);

// Decrypt with Seal
const decryptedData = await this.sealClient.decrypt({
ciphertext: encryptedData.ciphertext,
encryptionId: encryptedData.encryptionId,
recipientId: recipientKeypair.toSuiAddress(),
});

return JSON.parse(decryptedData.toString("utf-8"));
}

private async storeOnWalrus(data: any) {
// Integration with Walrus storage
// This would upload the encrypted data to Walrus
// and return the blob ID for retrieval
}

private async retrieveFromWalrus(blobId: string) {
// Retrieve encrypted data from Walrus using blob ID
}
}

Пример 2: Платформа контента с токен-гейтингом

// src/gated-content.ts
import { createSealClient } from "./seal-client";

class ContentGating {
private sealClient: any;
private suiClient: any;

constructor(sealClient: any, suiClient: any) {
this.sealClient = sealClient;
this.suiClient = suiClient;
}

async createGatedContent(
content: string,
requiredNftCollection: string,
creatorKeypair: any,
) {
// Create NFT ownership policy
const accessPolicy = await this.createNftPolicy(
requiredNftCollection,
creatorKeypair,
);

// Encrypt content with NFT access requirement
const encryptedContent = await this.sealClient.encrypt({
data: Buffer.from(content, "utf-8"),
recipientId: "nft_holders", // Special recipient for NFT holders
accessPolicy: {
policyId: accessPolicy.policyId,
policyType: "nft_ownership",
},
});

return {
contentId: encryptedContent.encryptionId,
accessPolicy: accessPolicy.policyId,
};
}

async accessGatedContent(
contentId: string,
userAddress: string,
userKeypair: any,
) {
// Verify NFT ownership first
const hasAccess = await this.verifyNftOwnership(userAddress, contentId);

if (!hasAccess) {
throw new Error("Access denied: Required NFT not found");
}

// Decrypt content
const decryptedContent = await this.sealClient.decrypt({
encryptionId: contentId,
recipientId: userAddress,
});

return decryptedContent.toString("utf-8");
}

private async createNftPolicy(collection: string, creator: any) {
// Create Move contract that checks NFT ownership
// Returns policy object ID
}

private async verifyNftOwnership(user: string, contentId: string) {
// Check if user owns required NFT
// Query Sui for NFT ownership
}
}

Пример 3: Передача активов с временной блокировкой

// src/time-locked-transfer.ts
import { createSealClient } from "./seal-client";

async function createTimeLockTransfer(
assetData: any,
recipientAddress: string,
unlockTimestamp: number,
senderKeypair: any,
) {
const { sealClient, suiClient } = await createSealClient();

// Create time-lock policy on Sui
const timeLockPolicy = await createTimeLockPolicy(
unlockTimestamp,
recipientAddress,
senderKeypair,
suiClient,
);

// Encrypt asset transfer data
const transferData = {
asset: assetData,
recipient: recipientAddress,
unlockTime: unlockTimestamp,
transferId: crypto.randomUUID(),
};

const encryptedTransfer = await sealClient.encrypt({
data: Buffer.from(JSON.stringify(transferData), "utf-8"),
recipientId: recipientAddress,
accessPolicy: {
policyId: timeLockPolicy.policyId,
policyType: "time_lock",
},
});

console.log(`Asset locked until ${new Date(unlockTimestamp)}`);

return {
transferId: encryptedTransfer.encryptionId,
unlockTime: unlockTimestamp,
policyId: timeLockPolicy.policyId,
};
}

async function claimTimeLockTransfer(
transferId: string,
recipientKeypair: any,
) {
const { sealClient } = await createSealClient();

try {
const decryptedData = await sealClient.decrypt({
encryptionId: transferId,
recipientId: recipientKeypair.toSuiAddress(),
});

const transferData = JSON.parse(decryptedData.toString("utf-8"));

// Process the asset transfer
console.log("Asset transfer unlocked:", transferData);

return transferData;
} catch (error) {
console.error("Transfer not yet unlocked or access denied:", error);
throw error;
}
}

Интеграция с децентрализованным хранилищем Walrus

Seal бесшовно работает с Walrus, децентрализованным решением для хранения данных от Sui. Вот как интегрировать оба:

// src/walrus-integration.ts
import { createSealClient } from "./seal-client";

class SealWalrusIntegration {
private sealClient: any;
private walrusClient: any;

constructor(sealClient: any, walrusClient: any) {
this.sealClient = sealClient;
this.walrusClient = walrusClient;
}

async storeEncryptedData(
data: Buffer,
recipientAddress: string,
accessPolicy?: any,
) {
// Encrypt with Seal
const encryptedData = await this.sealClient.encrypt({
data,
recipientId: recipientAddress,
accessPolicy,
});

// Store encrypted data on Walrus
const blobId = await this.walrusClient.store(encryptedData.ciphertext);

// Return reference that includes both Seal and Walrus info
return {
blobId,
encryptionId: encryptedData.encryptionId,
accessPolicy: encryptedData.accessPolicy,
};
}

async retrieveAndDecrypt(
blobId: string,
encryptionId: string,
userKeypair: any,
) {
// Retrieve from Walrus
const encryptedData = await this.walrusClient.retrieve(blobId);

// Decrypt with Seal
const decryptedData = await this.sealClient.decrypt({
ciphertext: encryptedData,
encryptionId,
recipientId: userKeypair.toSuiAddress(),
});

return decryptedData;
}
}

// Usage example
async function walrusExample() {
const { sealClient } = await createSealClient();
const walrusClient = new WalrusClient("https://walrus-testnet.sui.io");

const integration = new SealWalrusIntegration(sealClient, walrusClient);

const fileData = Buffer.from("Important document content");
const recipientAddress = "0x...";

// Store encrypted
const result = await integration.storeEncryptedData(
fileData,
recipientAddress,
);

console.log("Stored with Blob ID:", result.blobId);

// Later, retrieve and decrypt
const decrypted = await integration.retrieveAndDecrypt(
result.blobId,
result.encryptionId,
recipientKeypair,
);

console.log("Retrieved data:", decrypted.toString());
}

Пороговое шифрование: Расширенная конфигурация

Для производственных приложений вам потребуется настроить пользовательское пороговое шифрование с несколькими серверами ключей:

// src/advanced-threshold.ts
import { SealClient } from "@mysten/seal";

async function setupProductionSeal() {
// Configure with multiple independent key servers
const keyServers = [
"https://keyserver-1.your-org.com",
"https://keyserver-2.partner-org.com",
"https://keyserver-3.third-party.com",
"https://keyserver-4.backup-provider.com",
"https://keyserver-5.fallback.com",
];

const sealClient = new SealClient({
keyServers,
threshold: 3, // 3-of-5 threshold
network: "mainnet",
// Advanced options
retryAttempts: 3,
timeoutMs: 10000,
backupKeyServers: [
"https://backup-1.emergency.com",
"https://backup-2.emergency.com",
],
});

return sealClient;
}

async function robustEncryption() {
const sealClient = await setupProductionSeal();

const criticalData = "Mission critical encrypted data";

// Encrypt with high security guarantees
const encrypted = await sealClient.encrypt({
data: Buffer.from(criticalData, "utf-8"),
recipientId: "0x...",
// Require all 5 servers for maximum security
customThreshold: 5,
// Add redundancy
redundancy: 2,
accessPolicy: {
// Multi-factor requirements
requirements: ["nft_ownership", "time_lock", "multisig_approval"],
},
});

return encrypted;
}

Лучшие практики безопасности

1. Управление ключами

// src/security-practices.ts

// GOOD: Use secure key derivation
import { generateKeypair } from "@mysten/sui/cryptography/ed25519";

const keypair = generateKeypair();

// GOOD: Store keys securely (example with environment variables)
const keypair = Ed25519Keypair.fromSecretKey(process.env.PRIVATE_KEY);

// BAD: Never hardcode keys
const badKeypair = Ed25519Keypair.fromSecretKey(
"hardcoded-secret-key-12345", // Don't do this!
);

2. Проверка политики доступа

// Always validate access policies before encryption
async function secureEncrypt(data: Buffer, recipient: string) {
const { sealClient } = await createSealClient();

// Validate recipient address
if (!isValidSuiAddress(recipient)) {
throw new Error("Invalid recipient address");
}

// Check policy exists and is valid
const policy = await validateAccessPolicy(policyId);
if (!policy.isValid) {
throw new Error("Invalid access policy");
}

return sealClient.encrypt({
data,
recipientId: recipient,
accessPolicy: policy,
});
}

3. Обработка ошибок и запасные варианты

// Robust error handling
async function resilientDecrypt(encryptionId: string, userKeypair: any) {
const { sealClient } = await createSealClient();

try {
return await sealClient.decrypt({
encryptionId,
recipientId: userKeypair.toSuiAddress(),
});
} catch (error) {
if (error.code === "ACCESS_DENIED") {
throw new Error("Access denied: Check your permissions");
} else if (error.code === "KEY_SERVER_UNAVAILABLE") {
// Try with backup configuration
return await retryWithBackupServers(encryptionId, userKeypair);
} else if (error.code === "THRESHOLD_NOT_MET") {
throw new Error("Insufficient key servers available");
} else {
throw new Error(`Decryption failed: ${error.message}`);
}
}
}

4. Проверка данных

// Validate data before encryption
function validateDataForEncryption(data: Buffer): boolean {
// Check size limits
if (data.length > 1024 * 1024) {
// 1MB limit
throw new Error("Data too large for encryption");
}

// Check for sensitive patterns (optional)
const dataStr = data.toString();
if (containsSensitivePatterns(dataStr)) {
console.warn("Warning: Data contains potentially sensitive patterns");
}

return true;
}

Оптимизация производительности

1. Пакетные операции

// Batch multiple encryptions for efficiency
async function batchEncrypt(dataItems: Buffer[], recipients: string[]) {
const { sealClient } = await createSealClient();

const promises = dataItems.map((data, index) =>
sealClient.encrypt({
data,
recipientId: recipients[index],
}),
);

return Promise.all(promises);
}

2. Кэширование ответов сервера ключей

// Cache key server sessions to reduce latency
class OptimizedSealClient {
private sessionCache = new Map();

async encryptWithCaching(data: Buffer, recipient: string) {
let session = this.sessionCache.get(recipient);

if (!session || this.isSessionExpired(session)) {
session = await this.createNewSession(recipient);
this.sessionCache.set(recipient, session);
}

return this.encryptWithSession(data, session);
}
}

Тестирование вашей интеграции Seal

Модульное тестирование

// tests/seal-integration.test.ts
import { describe, it, expect } from "jest";
import { createSealClient } from "../src/seal-client";

describe("Seal Integration", () => {
it("should encrypt and decrypt data successfully", async () => {
const { sealClient } = await createSealClient();
const testData = Buffer.from("test message");
const recipient =
"0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";

const encrypted = await sealClient.encrypt({
data: testData,
recipientId: recipient,
});

expect(encrypted.encryptionId).toBeDefined();
expect(encrypted.ciphertext).toBeDefined();

const decrypted = await sealClient.decrypt({
ciphertext: encrypted.ciphertext,
encryptionId: encrypted.encryptionId,
recipientId: recipient,
});

expect(decrypted.toString()).toBe("test message");
});

it("should enforce access control policies", async () => {
// Test that unauthorized users cannot decrypt
const { sealClient } = await createSealClient();

const encrypted = await sealClient.encrypt({
data: Buffer.from("secret"),
recipientId: "authorized-user",
});

await expect(
sealClient.decrypt({
ciphertext: encrypted.ciphertext,
encryptionId: encrypted.encryptionId,
recipientId: "unauthorized-user",
}),
).rejects.toThrow("Access denied");
});
});

Развертывание в продакшене

Конфигурация среды

// config/production.ts
export const productionConfig = {
keyServers: [
process.env.KEY_SERVER_1,
process.env.KEY_SERVER_2,
process.env.KEY_SERVER_3,
process.env.KEY_SERVER_4,
process.env.KEY_SERVER_5,
],
threshold: 3,
network: "mainnet",
suiRpc: process.env.SUI_RPC_URL,
walrusGateway: process.env.WALRUS_GATEWAY,
// Security settings
maxDataSize: 1024 * 1024, // 1MB
sessionTimeout: 3600000, // 1 hour
retryAttempts: 3,
};

Мониторинг и логирование

// utils/monitoring.ts
export class SealMonitoring {
static logEncryption(encryptionId: string, recipient: string) {
console.log(`[SEAL] Encrypted data ${encryptionId} for ${recipient}`);
// Send to your monitoring service
}

static logDecryption(encryptionId: string, success: boolean) {
console.log(
`[SEAL] Decryption ${encryptionId}: ${success ? "SUCCESS" : "FAILED"}`,
);
}

static logKeyServerHealth(serverUrl: string, status: string) {
console.log(`[SEAL] Key server ${serverUrl}: ${status}`);
}
}

Ресурсы и дальнейшие шаги

Официальная документация

Сообщество и поддержка

  • Sui Discord: Присоединяйтесь к каналу #seal для поддержки сообщества
  • GitHub Issues: Сообщайте об ошибках и запрашивайте функции
  • Форумы для разработчиков: Форумы сообщества Sui для обсуждений

Расширенные темы для изучения

  1. Пользовательские политики доступа: Создавайте сложную логику авторизации с помощью контрактов Move
  2. Кросс-чейн интеграция: Используйте Seal с другими блокчейн-сетями
  3. Управление ключами для предприятий: Настройте собственную инфраструктуру серверов ключей
  4. Аудит и соответствие требованиям: Внедрите логирование и мониторинг для регулируемых сред

Примеры приложений

  • Приложение для безопасного чата: Сквозное шифрование сообщений с помощью Seal
  • Управление документами: Обмен корпоративными документами с контролем доступа
  • Управление цифровыми правами: Распространение контента с политиками использования
  • Аналитика, сохраняющая конфиденциальность: Рабочие процессы обработки зашифрованных данных

Заключение

Seal представляет собой фундаментальный сдвиг в сторону превращения конфиденциальности и шифрования в инфраструктурные проблемы в Web3. Объединяя шифрование на основе идентификаторов, пороговую безопасность и программируемый контроль доступа, он предоставляет разработчикам мощные инструменты для создания по-настоящему безопасных и децентрализованных приложений.

Основные преимущества использования Seal включают:

  • Отсутствие единой точки отказа: Распределенные серверы ключей устраняют центральные органы
  • Программируемая безопасность: Политики доступа на основе смарт-контрактов обеспечивают гибкую авторизацию
  • Удобство для разработчиков: SDK TypeScript легко интегрируется с существующими инструментами Web3
  • Независимость от хранилища: Работает с Walrus, IPFS или любым другим решением для хранения
  • Готовность к продакшену: Создан Mysten Labs с учетом корпоративных стандартов безопасности

Независимо от того, защищаете ли вы пользовательские данные, внедряете модели подписки или создаете сложные многосторонние приложения, Seal предоставляет криптографические примитивы и инфраструктуру контроля доступа, необходимые для уверенного создания.

Начните создавать сегодня и присоединяйтесь к растущей экосистеме разработчиков, которые делают конфиденциальность фундаментальной частью общественной инфраструктуры.


Готовы начать создавать? Установите @mysten/seal и начните экспериментировать с примерами из этого руководства. Децентрализованная сеть ждет приложений, которые ставят конфиденциальность и безопасность на первое место.

PYUSD на Solana: Практическое руководство по интеграции (с BlockEden.xyz RPC)

· 9 мин. чтения
Dora Noda
Software Engineer

PayPal USD (PYUSD) появился на Solana, что знаменует собой важную веху для цифровых платежей. Это руководство предлагает прямое, ориентированное на производство пошаговое описание для инженеров, интегрирующих PYUSD в кошельки, dApps и коммерческие платформы на Solana.

Все примеры используют актуальный код, совместимый с Token-2022, и разработаны для бесперебойной работы с RPC-конечными точками Solana от BlockEden.xyz с низкой задержкой.

TL;DR

  • Что: PayPal USD (PYUSD) теперь является нативным токеном SPL стандарта Token-2022 на Solana, предлагая быстрые и недорогие расчеты для всемирно признанного стейблкоина.
  • Ключевые параметры: Минт 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo, десятичные знаки 6 и токен-программа Token-2022.
  • Набор функций: Использует расширения токенов Solana (Token-2022). Имеет инициализированный, но в настоящее время неактивный Transfer Hook (нулевая программа), а также возможности конфиденциальной передачи и другие расширения.
  • Кроссчейн: Официальная интеграция LayerZero позволяет PYUSD перемещаться между Ethereum и Solana через безопасный механизм сжигания и минтинга, минуя традиционные мосты.
  • Действие: Используйте это руководство как готовый шаблон для добавления поддержки PYUSD в ваше приложение с помощью надежного Solana RPC от BlockEden.xyz.

Почему PYUSD на Solana важен

Сочетание бренда PayPal с производительностью Solana создает мощную новую основу для цифровых долларов.

  1. Доверие потребителей встречается с удобством использования криптовалют: PYUSD выпускается регулируемой трастовой компанией Paxos и глубоко интегрирован в PayPal и Venmo. Это предоставляет пользователям знакомый актив. Они могут хранить единый баланс PYUSD и выбирать вывод средств на внешний кошелек как в Ethereum, так и в Solana, абстрагируясь от сложности блокчейна.
  2. Готовые к платежам рельсы: Архитектура Solana обеспечивает финализацию транзакций менее чем за секунду и комиссии, составляющие доли цента. PYUSD накладывает стабильную, узнаваемую единицу учета поверх этой эффективной расчетной сети, что делает его идеальным для платежей, коммерции и денежных переводов.
  3. Контроль институционального уровня: Запускаясь как токен Token-2022, PYUSD может использовать встроенные расширения для таких функций, как конфиденциальные переводы, расширенные метаданные и постоянный делегат. Это обеспечивает расширенное соответствие требованиям и функциональность без необходимости в индивидуальных, трудно поддающихся аудиту смарт-контрактах.

Самое главное (Запомните это)

Прежде чем написать хоть одну строку кода, зафиксируйте эти параметры. Всегда проверяйте адрес минта в надежном эксплорере, чтобы избежать взаимодействия с мошенническими токенами.

  • Минт (Mainnet): 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo
  • Десятичные знаки: 6 (что означает 1 PYUSD = 1 000 000 базовых единиц)
  • Токен-программа: Token-2022 (ID программы: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb)
  • Используемые расширения токенов (при минтинге):
    • Метаданные и указатель метаданных
    • Постоянный делегат
    • Transfer Hook (инициализирован с нулевой программой)
    • Конфигурация конфиденциальной передачи

Вы можете проверить все это в Solana Explorer. Эксплорер четко покажет официальный адрес минта и его включенные расширения.

Настройка проекта

Подготовим наше окружение. Вам понадобятся последние библиотеки Solana web3 и SPL token для обеспечения полной совместимости с Token-2022.

1. Библиотеки

Установите необходимые пакеты из npm.

npm i @solana/web3.js @solana/spl-token

2. RPC-соединение

Направьте ваше приложение на URL-адрес RPC Solana Mainnet от BlockEden.xyz. Для продакшена переменные окружения обязательны.

// package.json
// npm i @solana/web3.js @solana/spl-token

import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID,
getMint,
getOrCreateAssociatedTokenAccount,
getAssociatedTokenAddress,
createTransferCheckedInstruction,
} from "@solana/spl-token";

// Используйте ваш URL-адрес RPC Solana от BlockEden.xyz из вашей панели управления
const RPC_ENDPOINT =
process.env.SOLANA_RPC_URL ??
"[https://your-blockeden-solana-mainnet-endpoint.com](https://your-blockeden-solana-mainnet-endpoint.com)";
export const connection = new Connection(RPC_ENDPOINT, "confirmed");

// PYUSD (основная сеть)
export const PYUSD_MINT = new PublicKey(
"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
);

Чтение данных минта PYUSD

Сначала программно подтвердим свойства минта PYUSD. Это важный первый шаг для проверки правильности ваших констант и получения таких деталей, как общий объем предложения.

// Подтверждение информации о минте PYUSD через API Token-2022
const mintInfo = await getMint(
connection,
PYUSD_MINT,
"confirmed",
TOKEN_2022_PROGRAM_ID, // Укажите ID программы
);

console.log({
supply: mintInfo.supply.toString(),
decimals: mintInfo.decimals, // Ожидается 6
isInitialized: mintInfo.isInitialized,
});

Обратите внимание, что мы явно передаем TOKEN_2022_PROGRAM_ID. Это наиболее частая причина ошибок при работе с расширениями токенов.

Создание или получение связанных токен-аккаунтов (ATA)

Связанные токен-аккаунты (ATA) для токенов Token-2022 должны быть получены с использованием ID программы Token-2022. Если вы используете устаревший TOKEN_PROGRAM_ID, транзакции завершатся ошибкой "incorrect program id".

// Плательщик и владелец нового ATA. Замените на вашу логику кошелька.
const owner = Keypair.generate();

// Создать или получить ATA PYUSD владельца (с учетом Token-2022)
const ownerAta = await getOrCreateAssociatedTokenAccount(
connection,
owner, // Плательщик за создание
PYUSD_MINT, // Минт
owner.publicKey, // Владелец ATA
false, // allowOwnerOffCurve
"confirmed",
undefined, // опции
TOKEN_2022_PROGRAM_ID, // <-- ВАЖНО: Используйте ID программы Token-2022
);

console.log("ATA PYUSD владельца:", ownerAta.address.toBase58());

Проверка балансов PYUSD

Чтобы проверить баланс PYUSD пользователя, запросите его ATA, снова не забывая указать правильный ID программы.

Использование @solana/spl-token

import { getAccount } from "@solana/spl-token";

const accountInfo = await getAccount(
connection,
ownerAta.address,
"confirmed",
TOKEN_2022_PROGRAM_ID,
);

const balance = Number(accountInfo.amount) / 10 ** mintInfo.decimals; // десятичные знаки = 6
console.log("Баланс PYUSD:", balance);

Использование прямого JSON-RPC (curl)

Вы также можете проверить все токен-аккаунты для владельца и отфильтровать их по ID программы Token-2022.

curl -X POST "$SOLANA_RPC_URL" -H 'content-type: application/json' -d '{
"jsonrpc":"2.0",
"id":1,
"method":"getTokenAccountsByOwner",
"params":[
"<OWNER_PUBLIC_KEY>",
{ "programId":"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" },
{ "encoding":"jsonParsed" }
]
}'

Передача PYUSD (от пользователя к пользователю)

Общее правило для передачи любого актива Token-2022 — использовать createTransferCheckedInstruction. Эта инструкция включает десятичные знаки токена, предотвращая потенциальные уязвимости, связанные с десятичными знаками.

Вот полная, многократно используемая функция для передачи PYUSD.

import { Transaction } from '@solana/web3.js';

async function transferPyusd({
fromWallet, // Keypair отправителя
toPubkey, // PublicKey получателя
uiAmount, // Сумма в PYUSD, например, 1.25
}: {
fromWallet: Keypair;
toPubkey: PublicKey;
uiAmount: number;
}) {
const decimals = 6; // Из mintInfo.decimals
const rawAmount = BigInt(Math.round(uiAmount * (10 ** decimals)));

// Получить адрес ATA отправителя
const fromAta = await getAssociatedTokenAddress(
PYUSD_MINT,
fromWallet.publicKey,
false,
TOKEN_2022_PROGRAM_ID
);

// Убедитесь, что ATA получателя существует для Token-2022
const toAta = await getOrCreateAssociatedTokenAccount(
connection,
fromWallet, // Плательщик
PYUSD_MINT,
toPubkey,
false,
'confirmed',
undefined,
TOKEN_2022_PROGRAM_ID
);

const transferInstruction = createTransferCheckedInstruction(
fromAta, // Исходный ATA
PYUSD_MINT, // Минт
toAta.address, // Целевой ATA
fromWallet.publicKey, // Владелец исходного ATA
rawAmount, // Сумма в базовых единицах
decimals, // Десятичные знаки
[], // Подписанты мультисига
TOKEN_2022_PROGRAM_ID // <-- ВАЖНО
);

const transaction = new Transaction().add(transferInstruction);

// Установить последний blockhash и плательщика комиссии
transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
transaction.feePayer = fromWallet.publicKey;

const signature = await connection.sendTransaction(transaction, [fromWallet]);
await connection.confirmTransaction(signature, 'confirmed');

console.log('Транзакция успешно выполнена с подписью:', signature);
return signature;
}

Примечание о Transfer Hook: Минт PYUSD инициализирует расширение Transfer Hook, но устанавливает его программу в null. Это означает, что стандартные переводы в настоящее время работают без дополнительных аккаунтов или логики. Если PayPal/Paxos когда-либо активируют хук, они обновят минт, чтобы он указывал на новую программу. Ваша интеграция тогда должна будет передавать дополнительные аккаунты, требуемые интерфейсом этой программы.

Быстрый тест Solana CLI

Для быстрого ручного тестирования из командной строки вы можете использовать spl-token с правильным ID программы.

# Убедитесь, что ваш CLI указывает на основную сеть и ваш keypair профинансирован.
# Перевести 1.00 PYUSD получателю.
spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
transfer 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo 1.00 <RECIPIENT_PUBKEY> \
--fund-recipient --allow-unfunded-recipient

Кроссчейн PYUSD (Ethereum ↔ Solana)

PayPal реализовал официальный кроссчейн-механизм с использованием LayerZero. Вместо того чтобы полагаться на рискованные сторонние мосты, это нативный процесс сжигания и минтинга: PYUSD сжигается в исходной цепочке (например, Ethereum), и эквивалентная сумма минтится в целевой цепочке (Solana). Это устраняет риски, специфичные для мостов, и проскальзывание.

Полное руководство и параметры вы можете найти в официальной документации для разработчиков PayPal.

Тестирование с кранами

Для разработки и тестирования не используйте активы основной сети. Используйте официальные краны:

  • Кран Paxos PYUSD: Для получения тестовых токенов PYUSD.
  • Кран Solana: Для получения SOL в devnet/testnet для оплаты комиссий за транзакции.

Распространенные ошибки (и их исправления)

  1. Неправильный ID программы: Проблема: Транзакции завершаются ошибкой incorrect program id for instruction. Исправление: Явно передавайте TOKEN_2022_PROGRAM_ID всем вспомогательным функциям spl-token (getOrCreateAssociatedTokenAccount, getAccount, createTransferCheckedInstruction и т.д.).
  2. Неправильный минт или поддельные активы: Проблема: Ваше приложение взаимодействует с поддельным токеном PYUSD. Исправление: Жестко закодируйте и проверьте официальный адрес минта: 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo. Используйте эксплорер, который предупреждает о неканонических минтах.
  3. Несоответствие десятичных знаков: Проблема: Отправка 1 PYUSD фактически отправляет 0.000001 PYUSD. Исправление: Всегда конвертируйте суммы пользовательского интерфейса в сырые суммы, умножая на 10^6. Для безопасности программно получайте десятичные знаки минта.
  4. Предположения о хуке: Проблема: Вы заранее создаете сложную логику для Transfer Hook, который не активен. Исправление: Проверьте данные расширения минта. На сегодняшний день хук PYUSD равен null. Создайте свою систему так, чтобы она адаптировалась, если программа хука будет включена в будущем.

Контрольный список для продакшена PYUSD + BlockEden.xyz

При переходе в продакшн убедитесь, что ваша инфраструктура надежна.

  • RPC: Используйте высокодоступную конечную точку BlockEden.xyz. Используйте уровень подтверждения confirmed для отзывчивого пользовательского интерфейса и запросы с finalized для операций, требующих целостности реестра.
  • Повторные попытки и идемпотентность: Оберните отправку транзакций механизмом повторных попыток с экспоненциальной задержкой. Храните ключ идемпотентности с каждой бизнес-операцией для предотвращения дублирования переводов.
  • Наблюдаемость: Регистрируйте подписи транзакций, номера слотов и балансы после транзакций. Используйте подписки BlockEden.xyz на веб-сокеты для получения сигналов о расчетах в реальном времени для бэкенда вашего приложения.
  • Соответствие требованиям: Token-2022 предоставляет примитивы для соответствия требованиям. Если вам нужно реализовать такие функции, как правило путешествий (travel rule), модель расширений позволяет сделать это чисто, сохраняя вашу бизнес-логику отдельно от основной функциональности токена.

Приложение A — Краткий справочник

Приложение B — Прямые вызовы JSON-RPC (curl)

Получить информацию об аккаунте минта и подтвердить владельца

Этот вызов извлекает данные аккаунта минта и позволяет вам убедиться, что его владельцем является программа Token-2022.

# Замените на ваш URL-адрес RPC BlockEden.xyz
curl -s -X POST "$SOLANA_RPC_URL" -H 'content-type: application/json' -d '{
"jsonrpc":"2.0","id":1,"method":"getAccountInfo",
"params":["2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
{"encoding":"base64","commitment":"confirmed"}]
}'

# В JSON-ответе поле "owner" должно быть равно "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb".

Перечислить все токен-аккаунты PYUSD для пользователя

Это полезно для кошельков, которым необходимо обнаружить все активы PYUSD для данного пользователя.

curl -s -X POST "$SOLANA_RPC_URL" -H 'content-type: application/json' -d '{
"jsonrpc":"2.0",
"id":1,
"method":"getTokenAccountsByOwner",
"params":[
"<OWNER_PUBLIC_KEY>",
{"mint":"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"},
{"encoding":"jsonParsed","commitment":"confirmed"}
]
}'

Готовы к созданию? Возьмите свою высокопроизводительную RPC-конечную точку BlockEden.xyz и начните интегрировать будущее платежей уже сегодня.

Новое руководство по NFT-сообществам (2025): От хайпа к привычке

· 10 мин. чтения
Dora Noda
Software Engineer

В 2021–22 годах NFT-сообщества подпитывались ценовыми движениями. В 2025 году те, что выживут, будут подпитываться участием. Это руководство представляет собой прагматичный, ориентированный на безопасность, учитывающий инструменты свод правил для создания долговечного NFT-сообщества.


1) Начните с четкой цели и простых правил

Прежде чем создавать единственный канал в Discord или настраивать бота, вы должны определить основу вашего сообщества. Процветающие сообщества строятся на общей идентичности и чувстве коллективной работы. Сначала задайте себе сложные вопросы:

  • Для кого вы существуете: Вы дом для коллекционеров, мастерская для создателей, лаборатория для разработчиков или галерея для кураторов? Определение вашей целевой аудитории сужает фокус.
  • Что члены делают вместе: Какова основная деятельность? Они создают искусство, курируют коллекции, разрабатывают инструменты или осваивают новые навыки? Общий глагол — это двигатель сообщества.
  • Как принимаются решения: С самого начала установите четкую модель управления. Это основная команда, набор рабочих групп или более децентрализованная система предложений и голосований? Ясность предотвращает будущие конфликты.
  • Где проходит граница: Сообщество определяется поведением, которое оно поощряет, и поведением, которое оно запрещает. Разработайте четкий Кодекс поведения (CoC), установите простую лестницу принуждения (например, предупреждение -> тайм-аут -> исключение -> бан) и создайте путь эскалации для модераторов.

Ваши правила должны быть краткими, хорошо заметными и последовательно применяемыми. В Discord это означает краткий канал #rules, подкрепленный закрепленными сообщениями в ключевых областях. Цель не в том, чтобы быть ограничительным; цель — создать безопасную и предсказуемую среду, где может процветать продуктивное участие.

2) Разработайте онбординг для импульса, а не для трения

Первые пять минут нового участника критически важны. Отличный онбординг быстро отвечает на три вопроса: почему мне стоит присоединиться, что мне делать в первую очередь и куда мне идти дальше?

  • Поток приветствия: Направляйте новичков в единый канал Начать здесь. Этот канал должен предоставлять 60-секундную ориентацию: миссию сообщества, три основных канала для посещения, краткое руководство по проверке их активов и получению помощи. Используйте автороли для практических вещей, таких как языковые или часовые предпочтения, и создайте простую ветку "представьтесь", чтобы сразу же создать социальное доказательство и связь.
  • Доступ с учетом токенов: Если у вашего сообщества есть токен или NFT, используйте роли с токен-гейтом, чтобы разблокировать специальные каналы для держателей, старожилов (OGs) или активных участников. Это создает уровни доступа и вознаграждает владение, не закрывая все сообщество. Такие инструменты, как Collab.Land и Guild, предназначены для этого, интегрируясь с Discord и Telegram для управления ролями на основе ончейн- и офчейн-критериев. Это позволяет вам поддерживать общедоступное пространство, одновременно вознаграждая ваших основных сторонников.
  • Стартовые квесты: Направляйте новых участников к их первой "победе". Это может быть простой 15-минутный путь: получить приветственный POAP, опубликовать представление и отреагировать на опрос о дорожной карте проекта. Эти небольшие действия создают импульс и превращают пассивного наблюдателя в активного участника.

3) Настройте «коммуникационный стек» для сигнала

Раскидистый, хаотичный сервер с десятками мертвых каналов — признак упадка сообщества. Минимальный сервер с каналами с высоким сигналом гораздо эффективнее.

  • Каналы, которые работают:
    • #announcements (только для записи основной командой)
    • #general (социальный центр и место для неформального общения)
    • #support (специальное место для вопросов, обрабатываемых модераторами)
    • #build или #art (пространство для основного творчества)
    • #governance (для предложений и ссылок на платформы для голосования, такие как Snapshot)
    • Используйте форумные каналы для организованных, долгосрочных обсуждений. Они идеально подходят для обзоров дизайна, официальных предложений и учебных пособий, предотвращая потерю ценных разговоров в быстро движущейся ленте чата.
  • Автоматизация, которая экономит ваше время:
    • Немедленно включите функции AutoMod в Discord. Используйте фильтры по ключевым словам и эвристику ссылок, чтобы блокировать спам и вредоносные ссылки до того, как их увидит модератор-человек. В нестабильные моменты или во время событий с высоким трафиком сочетайте это с медленным режимом (slowmode) для поддержания порядка.
  • Слушайте как оператор:
    • Включите Аналитику сервера (Server Insights) в настройках Discord. Этот встроенный инструмент предоставляет важные данные о присоединениях, ежедневных и еженедельных активных пользователях, возвращающихся участниках и активности сообщений. Используйте эти метрики для выявления проблем в вашем потоке онбординга или для обнаружения каналов, которые замолчали и нуждаются в чистке.

4) Замените хайп ритуалами

Хайп — это сахарный прилив, он создает временный всплеск энергии, но в конечном итоге неустойчив. Ритуалы, с другой стороны, — это постоянная диета, которая строит здоровое, постоянно растущее сообщество. Закрепите свой календарь надежными, повторяющимися событиями.

  • Еженедельные ритуалы:
    • Заметки о релизах (Ship Notes): Простой пост с подробным описанием того, что команда выпустила на этой неделе и что будет дальше.
    • Часы приема для создателей или разработчиков (Creator or Dev Office Hours): Запланированное время для участников, чтобы задать вопросы напрямую. Записывайте и суммируйте их для тех, кто не может присутствовать в прямом эфире.
    • В центре внимания сообщества (Community Spotlight): Представляйте участника, произведение искусства или инструмент, созданный сообществом.
  • Ежемесячные ритуалы:
    • Синхронизация управления (Governance Sync): Звонок для предварительного просмотра предстоящих предложений и проведения сессии вопросов и ответов.
    • Хакатон или художественный конкурс (Buildathon or Art Challenge): Предоставляйте темы, подсказки и даже небольшие баунти для стимулирования творчества.
  • На каждом этапе взаимодействия:
    • Вознаграждайте значимое участие с помощью POAP (Proof of Attendance Protocol). Эти простые NFT служат цифровыми сувенирами за посещение мероприятий, вклад в проект или победу в конкурсе. Они создают общую историю и заставляют участников чувствовать, что их вклад замечен, а не только их владения.

5) Управление, которое люди действительно используют

Сложные системы управления являются барьером для участия. Цель состоит в том, чтобы сделать принятие решений легким и понятным.

  • Предложения живут там, где происходит обсуждение. Предложение должно начинаться как пост в канале форума по управлению, в идеале сопровождаемый простым одностраничным резюме.
  • Голосование происходит там, где это легко. Используйте платформу для безгазового голосования, такую как Snapshot. Начните с простых опросов «да/нет» или с одним вариантом выбора. Гибкие стратегии голосования Snapshot позволяют вам согласовать силу голоса с ценностями вашего сообщества — будь то «один человек — один голос», сила, основанная на владении токенами, или система, основанная на репутации.
  • Гигиена принятия решений:
    • Установите минимальное окно для обсуждения (например, 72 часа) до начала голосования.
    • Четко определите кворум и пороги успеха заранее.
    • После завершения голосования опубликуйте краткое изложение решения и следующие шаги в канале #announcements, чтобы завершить цикл.

6) Рост без шума

Погоня за метриками тщеславия, такими как количество участников, истощит вашу команду и разбавит вашу культуру. Цель состоит в том, чтобы привлекать и удерживать качественных участников.

  • Системы квестов, сделанные правильно:
    • Используйте Zealy для создания модульных квестов и таблиц лидеров, которые привязаны к реальным, ценным действиям, таким как отправка пулл-реквеста, публикация учебного пособия или активное участие в звонке сообщества.
    • Для более крупных кампаний экосистемного масштаба Galxe Quests позволяет организовывать ончейн-активности с учетными данными с надежными функциями идентификации и защиты от атак Сивиллы.
  • Редакционные платформы:
    • Используйте платформу, такую как Mirror, для длинных статей. Здесь вы рассказываете историю проекта, публикуете подробные заметки о релизах и делитесь ретроспективами. Синдицируйте эти посты в свои социальные каналы и #announcements.
  • Социальные примитивы, которые конвертируют:
    • Используйте Farcaster Frames для встраивания интерактивных возможностей, таких как опросы, предпросмотры минтов или простые формы, непосредственно в вашу социальную ленту. Это значительно снижает трение между пользователем, видящим ваш контент, и совершением действия.

7) Безопасность — это управление сообществом

Большинство так называемых «кризисов сообщества» на самом деле являются сбоями безопасности. Нормализация культуры безопасности — одна из важнейших задач менеджера сообщества.

  • Золотые правила для участников:
    • Установите четкие правила: ни один член команды никогда не напишет вам в личные сообщения первым. Всегда проверяйте ссылки перед тем, как нажать. Используйте отдельные горячие и холодные кошельки. Регулярно отзывайте разрешения на токены.
    • Закрепите политику «Как мы делаем объявления», которая подробно описывает официальные домены, социальные сети и шаблоны подписания контрактов.
    • Делитесь высококачественными, независимыми от поставщиков руководствами по безопасности кошельков и собственными ресурсами Discord по борьбе со скамом.
  • Усиление безопасности на стороне сервера:
    • Включите двухфакторную аутентификацию (2FA) для всех администраторов и модераторов. Ограничьте разрешения на упоминание @everyone. Заблокируйте разрешения ботов и интеграций до короткого, проверенного белого списка и ежеквартально пересматривайте эти разрешения.
  • Планы реагирования на инциденты:
    • Не ждите кризиса, чтобы спланировать его. Заранее напишите шаги, которые ваша команда предпримет в распространенных чрезвычайных ситуациях: опубликована поддельная ссылка на минт, учетная запись модератора скомпрометирована, бот взломан или белый список утекает. Ваш план должен охватывать стандартные фазы реагирования на инциденты: подготовка, обнаружение, локализация, устранение, восстановление и постмортем.

8) Измеряйте то, что имеет значение

Минимальная цена (флор) не говорит вам, здорово ли ваше сообщество. Участие — говорит. Сосредоточьтесь на метриках, которые отражают подлинную вовлеченность.

  • Вовлеченность:
    • Отслеживайте DAU/WAU (ежедневные/еженедельные активные пользователи), процент участников, которые публикуют сообщения хотя бы раз в неделю, количество ответов на ветку в ключевых каналах и скорость реакции на объявления.
  • Онбординг:
    • Измеряйте коэффициент конверсии от нового участника до первого поста, среднее время до первого ответа на вопрос нового участника и процент новичков, которые получают ваш приветственный POAP.
  • Вклад:
    • Подсчитывайте количество предложений по управлению, пулл-реквестов, созданных пользователями учебных пособий и мероприятий, проводимых сообществом, в месяц.
  • Ончейн-здоровье:
    • Используйте дашборды Dune для отслеживания таких метрик, как количество уникальных держателей, удержание держателей с течением времени, показатели листинга на вторичном рынке, концентрация кошельков и пересечение трейдеров с другими сообществами.

9) Лестница участников, которая масштабирует вас

Чтобы избежать выгорания и масштабировать свое влияние, вам нужно предоставить мотивированным участникам четкий путь от наблюдателя к лидеру.

  • Определите роли:
    • Приветствующие (Greeters): Приветствуют новых участников и помогают сортировать первоначальные вопросы.
    • Кураторы (Curators): Отмечают отличный контент, ведут рубрику «В центре внимания сообщества» и поддерживают обсуждения в нужном русле.
    • Управляющие (Stewards): Берут на себя ответственность за конкретную программу, такую как проведение AMA, управление учебными треками или организация хакатона.
  • Предоставьте стимулы:
    • Стимулы не обязательно должны быть финансовыми. Признание через значки и POAP, небольшой бюджет для экспериментов, случайные оплачиваемые баунти и публичные «благодарности» в официальных объявлениях имеют большое значение.
  • Создайте пути выхода:
    • Лидерство не должно быть пожизненным заключением. Регулярно меняйте обязанности, чтобы предотвратить выгорание и создать возможности для других. Когда кто-то уходит с должности, отмечайте его вклад ритуалом благодарности.

10) Дорожная карта на 30–60–90 дней, которую вы можете использовать

Дни 1–30: Основы

  • Выпустите v1 ваших каналов #rules и #start-here.
  • Настройте минимальную структуру каналов и включите AutoMod.
  • Создайте роли для держателей и участников и настройте доступ с токен-гейтом с помощью Collab.Land или Guild.
  • Опубликуйте руководство по безопасности «как мы делаем объявления» и включите Аналитику сервера (Server Insights).
  • Проведите «Неделю приветствия» с доступным для получения POAP и высококачественной AMA.

Дни 31–60: Двигатели участия

  • Запустите свои еженедельные ритуалы: заметки о релизах, часы приема и рубрику «В центре внимания сообщества».
  • Настройте свое пространство Snapshot и примите первое простое предложение, например «Операционные правила сообщества v1».
  • Проведите пилотное тестирование одного или двух модулей квестов на Zealy или Galxe, привязанных к значимым, нетривиальным действиям.
  • Опубликуйте свое первое длинное эссе на Mirror, описывающее видение проекта и ближайшую дорожную карту.

Дни 61–90: Циклы накопления

  • Представьте хакатон или художественный конкурс, вознаграждая финалистов ончейн-учетными данными.
  • Экспериментируйте с Farcaster Frame для опросов или регистрации на мероприятия, чтобы стимулировать вовлеченность непосредственно из вашей ленты.
  • Выпустите публичный дашборд Dune, отслеживающий ключевые показатели здоровья держателей и KPI участия сообщества.
  • Проведите часовое настольное упражнение по вашему плану реагирования на инциденты с вашей командой модераторов.

Обзор инструментов (просто и понятно)

  • Доступ и роли: Collab.Land, Guild
  • Голосование: Snapshot
  • Вовлеченность: POAP, Zealy, Galxe
  • Публикация: Mirror
  • Социальная активация: Farcaster Frames
  • Аналитика: Discord Server Insights (встроенная) + Dune (ончейн)

Заключительная мысль

Великие NFT-сообщества не шумные; они грамотные. Они регулярно публикуют, редко голосуют, по умолчанию защищают участников и измеряют участие с той же строгостью, с какой когда-то измеряли минимальную цену (флор). Делайте меньше, делайте это каждую неделю, и пусть ритуалы, а не хайп, делают свое дело.

Что такое крипто-эйрдропы? Краткое руководство для разработчиков и пользователей (Издание 2025 года)

· 11 мин. чтения
Dora Noda
Software Engineer

TL;DR

Крипто-эйрдроп — это распределение токенов на определенные адреса кошельков, часто бесплатно, для запуска сети, децентрализации владения или вознаграждения ранних членов сообщества. Популярные методы включают ретроактивные вознаграждения за прошлые действия, конвертацию баллов в токены, раздачи для держателей NFT или токенов, а также интерактивные "квестовые" кампании. Дьявол кроется в деталях: правила снимков, механика клейма, такая как доказательства Меркла, Sybil-устойчивость, четкая коммуникация и соблюдение законодательства критически важны для успеха. Для пользователей ценность связана с токеномикой и безопасностью. Для команд успешный эйрдроп должен соответствовать основным целям продукта, а не просто генерировать временный хайп.


Что такое эйрдроп — на самом деле?

По своей сути, крипто-эйрдроп — это маркетинговая и дистрибуционная стратегия, при которой проект отправляет свой нативный токен на кошельки определенной группы пользователей. Это не просто раздача; это просчитанный шаг для достижения конкретных целей. Согласно образовательным ресурсам Coinbase и Binance Academy, эйрдропы обычно используются, когда новая сеть, протокол DeFi или dApp хотят быстро нарастить базу пользователей. Предоставляя токены потенциальным пользователям, проекты могут стимулировать их к участию в управлении, предоставлению ликвидности, тестированию новых функций или просто к тому, чтобы стать активными членами сообщества, запуская сетевой эффект.

Где эйрдропы встречаются на практике

Эйрдропы бывают нескольких видов, каждый из которых имеет свою стратегическую цель. Вот наиболее распространенные модели, встречающиеся сегодня.

Ретроактивные (вознаграждение за прошлое поведение)

Это классическая модель, разработанная для вознаграждения ранних пользователей, которые использовали протокол до появления токена. Эйрдроп Uniswap 2020 года является определяющим примером, установившим современный шаблон, распределив токены на сумму 400UNI400 UNI на каждый адрес, который когда-либо взаимодействовал с протоколом. Это было мощное "спасибо", которое в одночасье превратило пользователей во владельцев.

Баллы → токены (сначала стимулы, потом токены)

Доминирующая тенденция в 2024 и 2025 годах, модель баллов геймифицирует участие. Проекты отслеживают действия пользователей — такие как бриджинг, своппинг или стейкинг — и начисляют офчейн "баллы". Позже эти баллы конвертируются в токены. Этот подход позволяет командам измерять и стимулировать желаемое поведение в течение более длительного периода, прежде чем приступить к запуску токена.

Раздачи для держателей/NFT

Этот тип эйрдропа нацелен на пользователей, которые уже владеют определенным токеном или NFT. Это способ вознаградить лояльность в существующей экосистеме или запустить новый проект с вовлеченным сообществом. Известный случай — ApeCoin, который предоставил права на клейм своего токена $APE держателям NFT Bored Ape и Mutant Ape Yacht Club при его запуске в 2022 году.

Экосистемные/управленческие программы

Некоторые проекты используют серию эйрдропов как часть долгосрочной стратегии децентрализации и роста сообщества. Optimism, например, провел несколько эйрдропов для пользователей, а также зарезервировал значительную часть своего предложения токенов для финансирования общественных благ через свою программу RetroPGF. Это демонстрирует приверженность созданию устойчивой и ценностно-ориентированной экосистемы.

Как работает эйрдроп (важные механики)

Разница между успешным и хаотичным эйрдропом часто сводится к техническому и стратегическому исполнению. Вот механики, которые действительно имеют значение.

Снимок и право на участие

Во-первых, проект должен решить, кто имеет право на участие. Это включает выбор снимка — определенной высоты блока или даты — после которой активность пользователя больше не будет учитываться. Критерии отбора затем определяются на основе поведения, которое проект хочет вознаградить, например, бриджинг средств, выполнение свопов, предоставление ликвидности, участие в управлении или даже вклад в код. Для своего эйрдропа Arbitrum сотрудничал с аналитической фирмой Nansen для разработки сложной модели распределения на основе снимка, сделанного на определенном блоке 6 февраля 2023 года.

Клейм против прямой отправки

Хотя прямая отправка токенов на кошельки кажется проще, большинство зрелых проектов используют поток на основе клейма. Это предотвращает отправку токенов на потерянные или скомпрометированные адреса и требует от пользователей активного участия. Наиболее распространенный шаблон — это Merkle Distributor. Проект публикует криптографический отпечаток (корень Меркла) подходящих адресов в сети. Затем каждый пользователь может сгенерировать уникальное "доказательство" для проверки своего права на участие и клейма своих токенов. Этот метод, популяризированный реализацией Uniswap с открытым исходным кодом, является газоэффективным и безопасным.

Sybil-устойчивость

Эйрдропы являются главной целью для "фармеров" — лиц, использующих сотни или тысячи кошельков (так называемая "Sybil-атака") для максимизации своих вознаграждений. Команды используют различные методы для борьбы с этим. Они включают использование аналитики для кластеризации кошельков, контролируемых одной сущностью, применение эвристики (например, возраст кошелька или разнообразие активности) и, в последнее время, внедрение программ самоотчета. Кампания LayerZero 2024 года представила широко обсуждаемую модель, в которой пользователям была предоставлена возможность самостоятельно сообщить о Sybil-активности за 15% от их аллокации; те, кто этого не сделал и был позже пойман, столкнулись с исключением.

График разблокировки и управление

Не все токены из эйрдропа доступны немедленно. Многие проекты реализуют постепенный график разблокировки (или период вестинга) для аллокаций, предоставленных команде, инвесторам и экосистемным фондам. Понимание этого графика имеет решающее значение для пользователей, чтобы оценить будущее давление предложения на рынке. Платформы, такие как TokenUnlocks, предоставляют публичные дашборды, которые отслеживают эти графики разблокировки для сотен активов.

Кейс-стади (краткие факты)

  • Uniswap (2020): Распределил 400UNI400 UNI на каждый подходящий адрес, с большими аллокациями для поставщиков ликвидности. Он установил модель клейма на основе доказательств Меркла как отраслевой стандарт и продемонстрировал силу ретроактивного вознаграждения сообщества.
  • Arbitrum (2023): Запустил свой токен управления L2, $ARB, с начальным предложением в 10 миллиардов. Эйрдроп использовал систему баллов, основанную на ончейн-активности до снимка 6 февраля 2023 года, включая передовую аналитику и Sybil-фильтры от Nansen.
  • Starknet (2024): Назвал свой эйрдроп "Программой Провизий" (Provisions Program), с открытием клеймов 20 февраля 2024 года. Он был нацелен на широкий круг участников, включая ранних пользователей, сетевых разработчиков и даже стейкеров Ethereum, предлагая многомесячное окно для клейма.
  • ZKsync (2024): Объявленный 11 июня 2024 года, это было одно из крупнейших распределений для пользователей Layer 2 на сегодняшний день. Одноразовый эйрдроп распределил 17,5% от общего предложения токенов почти на 700 000 кошельков, вознаграждая раннее сообщество протокола.

Почему команды проводят эйрдропы (и когда не стоит)

Команды используют эйрдропы по нескольким стратегическим причинам:

  • Запуск двусторонней сети: Эйрдропы могут обеспечить сеть необходимыми участниками, будь то поставщики ликвидности, трейдеры, создатели или рестейкеры.
  • Децентрализация управления: Распределение токенов широкой базе активных пользователей является основополагающим шагом к надежной децентрализации и управлению, возглавляемому сообществом.
  • Вознаграждение ранних участников: Для проектов, которые не проводили ICO или продажу токенов, эйрдроп является основным способом вознаграждения ранних сторонников, которые приносили пользу, когда результат был неопределенным.
  • Сигнализация ценностей: Дизайн эйрдропа может передавать основные принципы проекта. Фокус Optimism на финансировании общественных благ является ярким примером этого.

Однако эйрдропы — не панацея. Командам не следует проводить эйрдроп, если продукт имеет низкое удержание, сообщество слабое или полезность токена плохо определена. Эйрдроп усиливает существующие положительные петли обратной связи; он не может исправить сломанный продукт.

Для пользователей: как оценивать и участвовать — безопасно

Эйрдропы могут быть прибыльными, но они также несут значительные риски. Вот как безопасно ориентироваться в этом ландшафте.

Прежде чем гнаться за дропом

  • Проверьте легитимность: Всегда проверяйте объявления об эйрдропах через официальные каналы проекта (веб-сайт, аккаунт X, Discord). Будьте крайне осторожны с ссылками на "клейм", отправленными через личные сообщения, найденными в рекламе или продвигаемыми непроверенными аккаунтами.
  • Изучите экономику: Поймите токеномику. Каково общее предложение? Какой процент выделен пользователям? Каков график вестинга для инсайдеров? Инструменты, такие как TokenUnlocks, могут помочь вам отслеживать будущие выпуски предложения.
  • Знайте стиль: Это ретроактивный дроп, вознаграждающий за прошлое поведение, или программа баллов, требующая постоянного участия? Правила для каждого из них различны, и программы баллов могут со временем менять свои критерии.

Гигиена кошелька

  • Используйте новый кошелек: По возможности используйте выделенный, низкоценный "одноразовый" кошелек для клейма эйрдропов. Это изолирует риск от ваших основных активов.
  • Читайте, что подписываете: Никогда не одобряйте транзакции вслепую. Вредоносные сайты могут обманом заставить вас подписать разрешения, которые позволят им опустошить ваши активы. Используйте симуляторы кошельков, чтобы понять транзакцию перед подписанием. Периодически просматривайте и отзывайте устаревшие разрешения с помощью таких инструментов, как Revoke.cash.
  • Будьте осторожны с офчейн-подписями: Мошенники все чаще злоупотребляют подписями Permit и Permit2, которые являются офчейн-разрешениями, которые могут быть использованы для перемещения ваших активов без ончейн-транзакции. Будьте так же осторожны с ними, как и с ончейн-разрешениями.

Общие риски

  • Фишинг и дрейнеры: Наиболее распространенный риск — это взаимодействие с поддельным сайтом "клейма", предназначенным для опустошения вашего кошелька. Исследования таких фирм, как Scam Sniffer, показывают, что сложные наборы дрейнеров были причиной огромных потерь в 2023–2025 годах.
  • Геозонирование и KYC: Некоторые эйрдропы могут иметь географические ограничения или требовать верификации "Знай своего клиента" (KYC). Всегда читайте условия, так как жители определенных стран могут быть исключены.
  • Налоги (краткая ориентация, не совет): Налоговый режим варьируется в зависимости от юрисдикции. В США IRS обычно рассматривает токены, полученные в результате эйрдропа, как налогооблагаемый доход по их справедливой рыночной стоимости на дату получения вами контроля над ними. В Великобритании HMRC может рассматривать эйрдроп как доход, если вы совершили действие для его получения. Последующая продажа токенов может повлечь за собой налог на прирост капитала. Проконсультируйтесь с квалифицированным специалистом.

Для команд: прагматичный чек-лист по разработке эйрдропа

Планируете эйрдроп? Вот чек-лист, который поможет вам в процессе разработки.

  1. Уточните цель: Чего вы пытаетесь достичь? Вознаградить реальное использование, децентрализовать управление, обеспечить ликвидность или финансировать разработчиков? Определите свою основную цель и сделайте целевое поведение явным.
  2. Установите критерии отбора, которые отражают ваш продукт: Разработайте критерии, которые вознаграждают лояльных, высококачественных пользователей. Учитывайте действия, которые коррелируют с удержанием (например, взвешенные по времени балансы, последовательная торговля) над простым объемом, и рассмотрите возможность ограничения вознаграждений для китов. Изучите публичные постмортемы крупных эйрдропов на таких платформах, как Nansen.
  3. Встройте Sybil-устойчивость: Не полагайтесь на один метод. Комбинируйте ончейн-эвристику (возраст кошелька, разнообразие активности) с кластерным анализом. Рассмотрите новые подходы, такие как модель отчетности с помощью сообщества, впервые примененная LayerZero.
  4. Разработайте надежный путь клейма: Используйте проверенный контракт Merkle Distributor. Опубликуйте полный набор данных и дерево Меркла, чтобы любой мог независимо проверить корень и свое право на участие. Сделайте пользовательский интерфейс клейма минималистичным, проверенным аудитом и с ограничением скорости для обработки пиковых нагрузок без перегрузки ваших RPC-эндпоинтов.
  5. Сообщите план выпуска: Будьте прозрачны в отношении общего предложения токенов, аллокаций для различных групп получателей (сообщество, команда, инвесторы) и будущих событий выпуска. Публичные дашборды укрепляют доверие и поддерживают более здоровую динамику рынка.
  6. Решите вопросы управления, юридические и налоговые: Согласуйте ончейн-возможности токена (голосование, распределение комиссий, стейкинг) с вашей долгосрочной дорожной картой. Обратитесь за юридической консультацией относительно юрисдикционных ограничений и необходимых раскрытий информации. Как показывают рекомендации IRS и HMRC, детали имеют значение.

Краткий глоссарий

  • Снимок (Snapshot): Определенный блок или время, используемое в качестве отсечки для определения того, кто имеет право на эйрдроп.
  • Клейм (Merkle): Газоэффективный, основанный на доказательствах метод, который позволяет подходящим пользователям забрать свою аллокацию токенов из смарт-контракта.
  • Sybil: Сценарий, когда один участник использует множество кошельков, чтобы манипулировать распределением. Команды используют методы фильтрации для их обнаружения и удаления.
  • Баллы (Points): Офчейн или ончейн подсчеты, которые отслеживают вовлеченность пользователя. Они часто конвертируются в токены позже, но критерии могут быть изменены.
  • График разблокировки (Release schedule): Временная шкала, подробно описывающая, как и когда нециркулирующие токены (например, аллокации команды или инвесторов) поступают на рынок.

Уголок разработчика: как BlockEden может помочь

Запуск эйрдропа — это масштабное предприятие. BlockEden предоставляет инфраструктуру, чтобы вы могли осуществить его ответственно и эффективно.

  • Надежные снимки: Используйте наши высокопроизводительные RPC и индексирующие сервисы для расчета права на участие по миллионам адресов и сложным критериям в любой сети.
  • Инфраструктура клейма: Получите экспертное руководство по разработке и внедрению потоков клейма Меркла и газоэффективных контрактов распределения.
  • Sybil-операции: Используйте наши конвейеры данных для запуска эвристики, выполнения кластерного анализа и итерации вашего списка исключений перед окончательным распределением.
  • Поддержка запуска: Наша инфраструктура создана для масштабирования. Благодаря встроенным ограничениям скорости, автоматическим повторным попыткам и мониторингу в реальном времени вы можете быть уверены, что день клейма не перегрузит ваши эндпоинты.

Часто задаваемые вопросы (быстрые ответы)

Является ли эйрдроп "бесплатными деньгами"? Нет. Это распределение, связанное с определенным поведением, рыночными рисками, потенциальными налоговыми обязательствами и соображениями безопасности. Это стимул, а не подарок.

Почему я не получил эйрдроп? Скорее всего, вы либо пропустили дату снимка, либо не соответствовали минимальным порогам активности, либо были отфильтрованы правилами обнаружения Sybil-атак проекта. Легитимные проекты обычно публикуют свои критерии; внимательно их читайте.

Должны ли команды оставлять клеймы открытыми навсегда? Это зависит от ситуации. Контракт клейма Uniswap остается открытым спустя годы, но многие современные проекты устанавливают крайний срок (например, 3-6 месяцев), чтобы упростить учет, вернуть невостребованные токены в казну и сократить долгосрочное обслуживание безопасности. Выберите политику и четко ее задокументируйте.

Дополнительная литература (первоисточники)

Погружение в блокчейн-программирование с Sui Move

· 3 мин. чтения
Dora Noda
Software Engineer

Блокчейн-технология стала ведущей силой в цифровом мире, предлагая революционные решения, выходящие за рамки криптовалют. Языки программирования, предназначенные для блокчейн-технологий, занимают уникальное место. Среди этих языков Move занял значительную позицию благодаря своей надёжности и встроенным функциям безопасности. Сегодня мы представим инновационное руководство под названием "Sui Move", разработанное для обучения разработчиков языку программирования Move с использованием подхода "обучение на примерах".

Погружение в блокчейн-программирование с Sui Move

Понимание Move: язык программирования

Прежде чем мы перейдём к руководству, кратко напомним, что такое Move. Созданный дочерней компанией Facebook, Diem Association (ранее Libra), Move — это статически типизированный, ресурсно-ориентированный язык программирования. Его дизайн сосредоточен на обеспечении безопасности, что делает его идеальным языком для кодирования блокчейн- и криптовалютных проектов. Sui Move — это вариант языка программирования Move.

Ресурсы в Move — это ключевая конструкция, которая выделяет его среди других языков программирования блокчейна. Это специальные типы, которые нельзя скопировать или отбросить, их можно только перемещать между местами хранения. Эта функция позволяет точно контролировать цифровые активы и значительно снижает риск распространённых проблем безопасности, таких как двойная трата.

Sui Move: руководство по обучению на примерах

Расположенное по адресу https://blockeden.xyz/docs/sui/sui-move/intro/, "Sui Move" — это всеобъемлющее руководство по обучению на примерах, разработанное для обучения разработчиков кодированию с использованием языка программирования Move.

"Sui Move" построен на философии, что практическое обучение ускоряет понимание и повышает квалификацию. Руководство разделено на небольшие, управляемые части, каждая из которых посвящена определённому аспекту Move. Это позволяет учащимся не только понять технические особенности языка, но и получить представление о том, как и где их можно реализовать.

"Sui Move" выделяется своим подходом к обучению. Вместо того чтобы перегружать учащегося плотной теорией, он предлагает множество примеров для каждой концепции. Учащийся может напрямую взаимодействовать с этими примерами, обеспечивая динамичную среду обучения, которая поощряет исследование и глубокое понимание.

Руководство разработано таким образом, чтобы быть доступным для различных уровней опыта. Независимо от того, являетесь ли вы опытным разработчиком, желающим погрузиться в блокчейн-разработку, или новичком, который только начинает, "Sui Move" разработан для того, чтобы вы эффективно усвоили и освоили концепции.

Что вы узнаете

"Sui Move" охватывает широкий круг тем, составляющих основу языка программирования Move. Вот краткий обзор того, что вы можете ожидать:

  • Понимание синтаксиса и структуры Move.
  • Глубокое погружение в уникальную ресурсно-ориентированную модель Move.
  • Манипулирование данными с использованием функций и методов Move.
  • Изучение создания и реализации Модулей и Скриптов.
  • Обработка исключений и обеспечение безопасности в ваших программах Move.
  • Изучение создания собственной монеты и NFT.

Почему стоит выбрать Sui Move?

"Sui Move" — это не просто руководство; это хорошо структурированный путь обучения. Он предлагает:

  1. Примеры из реального мира: Каждая концепция сопровождается практическим примером, демонстрирующим, как её эффективно использовать.
  2. Всестороннее освещение: Он обеспечивает глубокое понимание Move, от базового синтаксиса до продвинутых конструкций.
  3. Пошаговое руководство: Каждый модуль разработан для постепенного формирования вашего понимания, сокращая кривую обучения и упрощая освоение сложных концепций.
  4. Гибкость: Он подходит для широкого круга учащихся, от новичков до опытных разработчиков.

Блокчейн-технология формирует будущее многих отраслей, и освоение такого языка, как Move, может открыть новые возможности для разработчиков. С "Sui Move" у вас есть ресурс, который может эффективно провести вас через ваш путь обучения. Так что погрузитесь, начните кодировать и исследуйте захватывающие возможности, которые Move и блокчейн-технология открывают для вас.

Начните прямо сейчас по адресу https://blockeden.xyz/docs/sui/sui-move/intro/.