threejs-skills
Three.jsを使用して3Dシーン、インタラクティブな体験、視覚エフェクトを作成します。ユーザーが3Dグラフィックス、WebGLエクスペリエンス、3Dビジュアライゼーション、アニメーション、またはインタラクティブな3D要素を求める際に使用します。
description の原文を見る
Create 3D scenes, interactive experiences, and visual effects using Three.js. Use when user requests 3D graphics, WebGL experiences, 3D visualizations, animations, or interactive 3D elements.
SKILL.md 本文
Three.js スキル
Three.js のベストプラクティスに従い、体系的に高品質な 3D シーンとインタラクティブな体験を作成します。
使用時期
- 3D ビジュアライゼーションまたはグラフィックスのリクエスト(「3D モデルを作成する」「3D で表示する」など)
- インタラクティブな 3D 体験を望む場合(「回転するキューブ」「探索可能なシーン」など)
- WebGL またはキャンバスベースのレンダリングが必要な場合
- アニメーション、パーティクル、またはビジュアルエフェクトを求める場合
- Three.js、WebGL、または 3D レンダリングについて言及されている場合
- 3D 空間でデータを可視化したい場合
コア設定パターン
1. 必須の Three.js インポート
モダン Three.js(r183+)用の ES モジュールインポートマップを使用します:
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.183.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.183.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
</script>
npm/vite/webpack を使った本番環境用:
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
2. シーンの初期化
すべての Three.js 成果物には、これらのコアコンポーネントが必要です:
// シーン - すべての 3D オブジェクトを含む
const scene = new THREE.Scene();
// カメラ - 視点を定義する
const camera = new THREE.PerspectiveCamera(
75, // 視野角
window.innerWidth / window.innerHeight, // アスペクト比
0.1, // ニアクリッピング平面
1000, // ファークリッピング平面
);
camera.position.z = 5;
// レンダラー - シーンを描画する
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
3. アニメーションループ
renderer.setAnimationLoop()(推奨)または requestAnimationFrame を使用します:
// 推奨:setAnimationLoop(WebXR 互換性を処理)
renderer.setAnimationLoop(() => {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
});
// 代替案:手動 requestAnimationFrame
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
体系的な開発プロセス
1. シーンを定義する
以下を特定することから始めます:
- レンダリングが必要なオブジェクト
- カメラの位置と視野角
- 必要なライティング設定
- インタラクションモデル(静的、回転、ユーザー操作)
2. ジオメトリを構築する
適切なジオメトリタイプを選択します:
基本図形:
BoxGeometry- キューブ、直方体SphereGeometry- 球、惑星CylinderGeometry- 円柱、チューブPlaneGeometry- 平面、地面TorusGeometry- ドーナツ、リング
CapsuleGeometry は利用可能です(r142 以来安定):
new THREE.CapsuleGeometry(0.5, 1, 4, 8); // 半径、長さ、キャップセグメント、放射状セグメント
3. マテリアルを適用する
ビジュアルニーズに基づいてマテリアルを選択します:
一般的なマテリアル:
MeshBasicMaterial- ライティング不要、フラットカラーMeshStandardMaterial- 物理ベース、リアル(ライティング必須)MeshPhongMaterial- 光沢のある表面とスペキュラハイライトMeshLambertMaterial- マットな表面、拡散反射
const material = new THREE.MeshStandardMaterial({
color: 0x00ff00,
metalness: 0.5,
roughness: 0.5,
});
4. ライティングを追加する
ライティング対応マテリアル(Standard、Phong、Lambert)を使用する場合、ライトを追加します:
// 環境光 - 一般的な照明
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
// 平行光 - 太陽光のような
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);
ライティングをスキップ(MeshBasicMaterial の場合 - 設計上ライティング不要)
5. レスポンシブ性を処理する
ウィンドウのリサイズ処理を常に追加します:
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
一般的なパターン
回転するオブジェクト
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
OrbitControls
インポートマップまたはビルドツールを使用している場合、OrbitControls は直接動作します:
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
// アニメーションループで更新
renderer.setAnimationLoop(() => {
controls.update();
renderer.render(scene, camera);
});
カスタムカメラコントロール(代替案)
OrbitControls をインポートせずに軽量なカスタムコントロール:
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
renderer.domElement.addEventListener("mousedown", () => {
isDragging = true;
});
renderer.domElement.addEventListener("mouseup", () => {
isDragging = false;
});
renderer.domElement.addEventListener("mousemove", (event) => {
if (isDragging) {
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
// シーンの周りでカメラを回転
const rotationSpeed = 0.005;
camera.position.x += deltaX * rotationSpeed;
camera.position.y -= deltaY * rotationSpeed;
camera.lookAt(scene.position);
}
previousMousePosition = { x: event.clientX, y: event.clientY };
});
// マウスホイールでズーム
renderer.domElement.addEventListener("wheel", (event) => {
event.preventDefault();
camera.position.z += event.deltaY * 0.01;
camera.position.z = Math.max(2, Math.min(20, camera.position.z)); // クランプ
});
3D オブジェクト選択のレイキャスティング
マウスクリックとホバーを 3D オブジェクトで検出:
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const clickableObjects = []; // クリック可能なメッシュの配列
// マウス位置を更新
window.addEventListener("mousemove", (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
// クリックを検出
window.addEventListener("click", () => {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(clickableObjects);
if (intersects.length > 0) {
const clickedObject = intersects[0].object;
// クリックを処理 - 色、スケールなどを変更
clickedObject.material.color.set(0xff0000);
}
});
// アニメーションループでホバー効果
function animate() {
requestAnimationFrame(animate);
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(clickableObjects);
// すべてのオブジェクトをリセット
clickableObjects.forEach((obj) => {
obj.scale.set(1, 1, 1);
});
// ホバーされたオブジェクトをハイライト
if (intersects.length > 0) {
intersects[0].object.scale.set(1.2, 1.2, 1.2);
document.body.style.cursor = "pointer";
} else {
document.body.style.cursor = "default";
}
renderer.render(scene, camera);
}
パーティクルシステム
const particlesGeometry = new THREE.BufferGeometry();
const particlesCount = 1000;
const posArray = new Float32Array(particlesCount * 3);
for (let i = 0; i < particlesCount * 3; i++) {
posArray[i] = (Math.random() - 0.5) * 10;
}
particlesGeometry.setAttribute(
"position",
new THREE.BufferAttribute(posArray, 3),
);
const particlesMaterial = new THREE.PointsMaterial({
size: 0.02,
color: 0xffffff,
});
const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial);
scene.add(particlesMesh);
ユーザーインタラクション(マウス移動)
let mouseX = 0;
let mouseY = 0;
document.addEventListener("mousemove", (event) => {
mouseX = (event.clientX / window.innerWidth) * 2 - 1;
mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
});
function animate() {
requestAnimationFrame(animate);
camera.position.x = mouseX * 2;
camera.position.y = mouseY * 2;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
テクスチャの読み込み
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("texture-url.jpg");
const material = new THREE.MeshStandardMaterial({
map: texture,
});
ベストプラクティス
パフォーマンス
- 類似オブジェクト作成時はジオメトリとマテリアルを再利用
- カスタム図形には
BufferGeometryを使用(より効率的) - パーティクル数を制限して 60fps を維持(1000~5000 から開始)
- オブジェクト削除時はリソースを解放:
geometry.dispose(); material.dispose(); texture.dispose();
ビジュアル品質
- レンダラーに常に
antialias: trueを設定して滑らかなエッジを実現 - 適切なカメラ FOV を使用(通常 45~75 度)
- ライトを注意深く配置し、複数の明るいライトが重ならないようにする
- リアルなシーンには環境光 + 平行光を追加
コード組織
- シーン、カメラ、レンダラーを最上部で初期化
- 関連オブジェクトをグループ化(例:すべてのパーティクルを 1 つのグループに)
- アニメーションロジックをアニメーション関数に保持
- 複雑なシーンではオブジェクト作成を関数に分離
避けるべき一般的な落とし穴
- ❌
outputEncodingの代わりにoutputColorSpaceを使用(r152 で名前変更) - ❌
scene.add()でオブジェクトをシーンに追加するのを忘れる - ❌ ライティング対応マテリアルを使用してライトを追加しない
- ❌ ウィンドウリサイズを処理しない
- ❌ アニメーションループで
renderer.render()を呼び出すのを忘れる - ❌
THREE.ClockをTHREE.Timer(r183 で推奨)を検討せずに使用
ワークフロー例
ユーザー:「マウス移動に応答するインタラクティブな 3D 球を作成する」
- セットアップ:Three.js をインポート、シーン/カメラ/レンダラーを作成
- ジオメトリ:スムーズな球用に
SphereGeometry(1, 32, 32)を作成 - マテリアル:リアルな外観のために
MeshStandardMaterialを使用 - ライティング:環境光 + 平行光を追加
- インタラクション:マウス位置を追跡、カメラを更新
- アニメーション:球を回転、継続的にレンダリング
- レスポンシブ:ウィンドウリサイズハンドラを追加
- 結果:スムーズでインタラクティブな 3D 球 ✓
トラブルシューティング
黒い画面 / 何も表示されない:
- オブジェクトがシーンに追加されているか確認
- カメラ位置がオブジェクトの内側にないか確認
- renderer.render() が呼び出されているか確認
- ライティング対応マテリアル使用時はライトを追加
パフォーマンスが低い:
- パーティクル数を削減
- ジオメトリ詳細度(セグメント)を低減
- マテリアル/ジオメトリを再利用
- ブラウザコンソールのエラーを確認
オブジェクトが表示されない:
- オブジェクト位置 vs カメラ位置を確認
- マテリアルに見える色/プロパティがあるか確認
- カメラの遠平面がオブジェクトを含んでいるか確認
- 必要に応じてライティングを追加
高度なテクニック
ポートフォリオグレードレンダリング向けビジュアルポーランド
シャドウ:
// レンダラーでシャドウを有効化
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // ソフトシャドウ
// シャドウをキャストするライト
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 5);
directionalLight.castShadow = true;
// シャドウ品質を設定
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 50;
scene.add(directionalLight);
// オブジェクトはシャドウをキャスト/受け取る
mesh.castShadow = true;
mesh.receiveShadow = true;
// 地面平面はシャドウを受け取る
const groundGeometry = new THREE.PlaneGeometry(20, 20);
const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
環境マップと反射:
// キューブマップから環境マップを作成
const loader = new THREE.CubeTextureLoader();
const envMap = loader.load([
"px.jpg",
"nx.jpg", // 正 x、負 x
"py.jpg",
"ny.jpg", // 正 y、負 y
"pz.jpg",
"nz.jpg", // 正 z、負 z
]);
scene.environment = envMap; // すべての PBR マテリアルに影響
scene.background = envMap; // オプション:スカイボックスとして使用
// または特定マテリアルに適用
const material = new THREE.MeshStandardMaterial({
metalness: 1.0,
roughness: 0.1,
envMap: envMap,
});
トーンマッピングと出力エンコード:
// 色精度と HDR レンダリングを改善
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.outputColorSpace = THREE.SRGBColorSpace; // 古いバージョンでは outputEncoding
// より鮮やかでリアルな色を実現
深度向けのフォグ:
// 線形フォグ
scene.fog = new THREE.Fog(0xcccccc, 10, 50); // 色、近、遠
// または指数関数的フォグ(よりリアル)
scene.fog = new THREE.FogExp2(0xcccccc, 0.02); // 色、密度
頂点からのカスタムジオメトリ
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([-1, -1, 0, 1, -1, 0, 1, 1, 0]);
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
ポストプロセッシングエフェクト
ポストプロセッシングエフェクトはインポートマップまたはビルドツール経由で利用可能です。EffectComposer、ブルーム、DOF などについては threejs-postprocessing スキルを参照してください。
オブジェクトのグループ化
const group = new THREE.Group();
group.add(mesh1);
group.add(mesh2);
group.rotation.y = Math.PI / 4;
scene.add(group);
サマリー
Three.js 成果物には体系的なセットアップが必要です:
- インポートマップまたはビルドツール経由で Three.js をインポート
- シーン、カメラ、レンダラーを初期化
- ジオメトリ + マテリアル = メッシュを作成
- ライティング対応マテリアル使用時はライティングを追加
- アニメーションループを実装(
setAnimationLoopを推奨) - ウィンドウリサイズを処理
renderer.outputColorSpace = THREE.SRGBColorSpaceを設定
これらのパターンに従い、信頼性が高く効率的な 3D 体験を実現します。
モダン Three.js プラクティス(r183)
モジュラーインポート
// npm/vite/webpack を使用:
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
WebGPU レンダラー(代替案)
Three.js r183 には WebGL の代替として WebGPU レンダラーが含まれます:
import { WebGPURenderer } from "three/addons/renderers/webgpu/WebGPURenderer.js";
const renderer = new WebGPURenderer({ antialias: true });
await renderer.init();
renderer.setSize(window.innerWidth, window.innerHeight);
WebGPU はカスタムシェーダーに GLSL の代わりに TSL(Three.js Shading Language)を使用します。詳細は threejs-shaders を参照してください。
タイマー(r183 推奨)
THREE.Timer は r183 以降 THREE.Clock より推奨されます:
const timer = new THREE.Timer();
renderer.setAnimationLoop(() => {
timer.update();
const delta = timer.getDelta();
const elapsed = timer.getElapsed();
mesh.rotation.y += delta;
renderer.render(scene, camera);
});
Clock より優れた点:
- ページ非表示時の影響を受けない(タブが非表示の場合は一時停止)
- よりクリーンな API 設計
setAnimationLoopとの統合が向上
アニメーションライブラリ(GSAP 統合)
// スムーズなタイムラインベースアニメーション
import gsap from "gsap";
// 手動アニメーションループの代わりに:
gsap.to(mesh.position, {
x: 5,
duration: 2,
ease: "power2.inOut",
});
// 複雑なシーケンス:
const timeline = gsap.timeline();
timeline
.to(mesh.rotation, { y: Math.PI * 2, duration: 2 })
.to(mesh.scale, { x: 2, y: 2, z: 2, duration: 1 }, "-=1");
GSAP を使う理由:
- プロ仕様のイージング関数
- タイムライン制御(一時停止、反転、スクラブ)
- 複雑なアニメーション向けに手動補間より優秀
スクロールベースのインタラクション
// ページスクロールと 3D アニメーションを同期
let scrollY = window.scrollY;
window.addEventListener("scroll", () => {
scrollY = window.scrollY;
});
function animate() {
requestAnimationFrame(animate);
// スクロール位置に基づいて回転
mesh.rotation.y = scrollY * 0.001;
// シーンを通じてカメラを移動
camera.position.y = -(scrollY / window.innerHeight) * 10;
renderer.render(scene, camera);
}
高度なスクロールライブラリ:
- ScrollTrigger(GSAP プラグイン)
- Locomotive Scroll
- Lenis スムーススクロール
本番環境でのパフォーマンス最適化
// 詳細度のレベル(LOD)
const lod = new THREE.LOD();
lod.addLevel(highDetailMesh, 0); // 近距離
lod.addLevel(mediumDetailMesh, 10); // 中距離
lod.addLevel(lowDetailMesh, 50); // 遠距離
scene.add(lod);
// 多くの同一オブジェクト用のインスタンスメッシュ
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial();
const instancedMesh = new THREE.InstancedMesh(geometry, material, 1000);
// 各インスタンスの変換を設定
const matrix = new THREE.Matrix4();
for (let i = 0; i < 1000; i++) {
matrix.setPosition(
Math.random() * 100,
Math.random() * 100,
Math.random() * 100,
);
instancedMesh.setMatrixAt(i, matrix);
}
モダン読み込みパターン
// 本番環境で 3D モデルを読み込み:
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
const loader = new GLTFLoader();
loader.load("model.gltf", (gltf) => {
scene.add(gltf.scene);
// トラバースしてマテリアルをセットアップ
gltf.scene.traverse((child) => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
});
何をいつ使うかについて
インポートマップアプローチ:
- 素早いプロトタイプとデモ
- 教育用コンテンツ
- 成果物と埋め込み体験
- ビルドステップ不要
本番ビルドアプローチ:
- クライアントプロジェクトとポートフォリオ
- 複雑なアプリケーション
- パフォーマンスクリティカルなアプリケーション
- バージョン管理を使用したチームコラボレーション
推奨本番スタック
Three.js r183 + Vite
├── GSAP(アニメーション)
├── React Three Fiber(オプション - React 統合)
├── Drei(ヘルパーコンポーネント)
├── Leva(デバッグ GUI)
└── ポストプロセッシングエフェクト
制限事項
- このスキルは、上記で説明されたスコープに明確に一致するタスクの場合のみ使用してください。
- 出力を環境固有の検証、テスト、または専門家レビューの代替と見なさないでください。
- 必須入力、許可、安全境界、または成功基準が不足している場合は、停止して明確化を求めてください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- sickn33
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。