@mysten/sealで分散暗号化を構築する:開発者向けチュートリアル
プライバシーは公共インフラになりつつあります。2025年、開発者にはデータ保存と同じくらい簡単に暗号化を行うツールが必要です。Mysten LabsのSealは、まさにそれを提供します—オンチェーンアクセス制御を備えた分散シークレット管理。このチュートリアルでは、アイデンティティベース暗号化、閾値セキュリティ、プログラマブルアクセスポリシーを使用して安全なWeb3アプリケーションを構築する方法を教えます。
導入:なぜSealがWeb3にとって重要なのか
従来のクラウドアプリケーションは、単一のプロバイダーが暗号化データへのアクセスを制御する集中型キー管理システムに依存しています。便利ですが、これは危険な単一障害点を作り出します。プロバイダーが侵害されたり、オフラインになったり、アクセスを制限することを決定した場合、あなたのデータはアクセス不可能または脆弱になります。
Sealは、このパラダイムを完全に変えます。Mysten LabsがSuiブロックチェーン向けに構築したSealは、分散シークレット管理(DSM)サービスで、以下を可能にします:
- アイデンティティベース暗号化:コンテンツが環境を離れる前に保護される
- 閾値暗号化:複数の独立したノード間でキーアクセスを分散
- オンチェーンアクセス制御:タイムロック、トークンゲーティング、カスタム認証ロジック
- ストレージ非依存設計:Walrus、IPFS、または任意のストレージソリューションと連携
安全なメッセージングアプリ、ゲート付きコンテンツプラットフォーム、タイムロック資産転送を構築する場合、Sealは必要な暗号プリミティブとアクセス制御インフラストラクチャを提供します。
はじめに
前提条件
開始する前に、以下があることを確認してください:
- Node.js 18+がインストールされていること
- TypeScript/JavaScriptの基本的な知識
- テスト用のSuiウォレット(Sui Walletなど)
- ブロックチェーンの概念の理解
インストール
npm経由でSeal SDKをインストールします:
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-of-n閾値スキームを使用します。3-of-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() {
// テストネット用のSuiクライアントを初期化
const suiClient = new SuiClient({
url: 'https://fullnode.testnet.sui.io'
});
// テストネットキーサーバーでSealクライアントを設定
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閾値
network: 'testnet'
});
return { sealClient, suiClient };
}
ステップ2:シンプルな暗号化/復号化
// src/basic-encryption.ts
import { createSealClient } from './seal-client';
async function basicExample() {
const { sealClient } = await createSealClient();
// 暗号化するデータ
const sensitiveData = "これは私の秘密メッセージです!";
const recipientAddress = "0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";
try {
// 特定のSuiアドレス用にデータを暗号化
const encryptedData = await sealClient.encrypt({
data: Buffer.from(sensitiveData, 'utf-8'),
recipientId: recipientAddress,
// オプション:メタデータを追加
metadata: {
contentType: 'text/plain',
timestamp: Date.now()
}
});
console.log('暗号化されたデータ:', {
ciphertext: encryptedData.ciphertext.toString('base64'),
encryptionId: encryptedData.encryptionId
});
// 後でデータを復号化(適切な認証が必要)
const decryptedData = await sealClient.decrypt({
ciphertext: encryptedData.ciphertext,
encryptionId: encryptedData.encryptionId,
recipientId: recipientAddress
});
console.log('復号化されたデータ:', decryptedData.toString('utf-8'));
} catch (error) {
console.error('暗号化/復号化に失敗しました:', 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();
// Sui上でアクセスポリシーを作成
const txb = new TransactionBlock();
const unlockTime = Date.now() + 60000; // 1分後にアンロック
const authorizedUser = "0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";
txb.moveCall({
target: 'time_lock::policy::create_time_lock',
arguments: [
txb.pure(unlockTime),
txb.pure(authorizedUser)
]
});
// ポリシーを作成するトランザクションを実行
const result = await suiClient.signAndExecuteTransactionBlock({
transactionBlock: txb,
signer: yourKeypair, // あなたのSuiキーペア
});
const policyId = result.objectChanges?.find(
change => change.type === 'created'
)?.objectId;
// このポリシーで暗号化
const sensitiveData = "これは1分後にアンロックされます!";
const encryptedData = await sealClient.encrypt({
data: Buffer.from(sensitiveData, 'utf-8'),
recipientId: authorizedUser,
accessPolicy: {
policyId,
policyType: 'time_lock'
}
});
console.log('タイムロックされたデータが作成されました。1分後に復号化を試してください。');
return {
encryptedData,
policyId,
unlockTime
};
}