プラグイン
Freeze Execute
Last updated January 31, 2026
概要
Freeze Executeプラグインは、Assetの ExecuteライフサイクルイベントをフリーズできるOwner Managedプラグインです。フリーズされると、AssetはそのAsset Signer PDAを通じて任意の命令を実行できなくなり、フリーズが解除されるまですべてのexecute操作を効果的にブロックします。
重要: これはOwner Managedプラグインであるため、Assetが新しいオーナーに転送された後、authorityは保持されません。新しいオーナーが以前のauthorityにプラグインのfreezeステータスを変更できるようにしたい場合は、authorityを再追加する必要があります。
Freeze Executeプラグインは、以下のようなシナリオで特に有用です:
- Backed NFT: 基礎資産(SOL、トークン)の所有権を表すNFTをロックし、不正な引き出しを防止
- エスクローレスアセット管理: 所有権を移転せずに金融操作に関与している間アセットをフリーズ
- ステーキングプロトコル: 所有権を維持しながらステーキング期間中のアセット実行を防止
- スマートコントラクトセキュリティ: 複雑な操作を実行できるアセットに保護レイヤーを追加
- ガバナンス制御: ガバナンスや投票に関与するアセットにフリーズメカニズムを実装
- アセットレンタル: レンタル中のアセットの実行を防止
- 担保管理: DeFiプロトコルで担保として使用されるアセットをロック
対応
| MPL Core Asset | ✅ |
| MPL Core Collection | ✅ |
引数
| 引数 | 値 |
|---|---|
| frozen | bool |
関数
AssetへのFreeze Executeプラグインの追加
addPluginコマンドは、AssetにFreeze Executeプラグインを追加します。このプラグインにより、AssetのExecute機能をフリーズし、任意の命令の実行を防ぐことができます。
MPL Core AssetへのFreeze Executeプラグインの追加
import { publicKey } from '@metaplex-foundation/umi'
import { addPlugin, mplCore } from '@metaplex-foundation/mpl-core'
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
;(async () => {
const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
const assetAddress = publicKey('11111111111111111111111111111111')
await addPlugin(umi, {
asset: assetAddress,
plugin: { type: 'FreezeExecute', data: { frozen: false } },
}).sendAndConfirm(umi)
})()
Freeze Executeプラグインを持つAssetの作成
Asset作成時にFreeze Executeプラグインを追加することもできます:
Freeze Executeプラグインを持つAssetの作成
import { generateSigner } from '@metaplex-foundation/umi'
import { create, mplCore } from '@metaplex-foundation/mpl-core'
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
;(async () => {
const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
const assetSigner = generateSigner(umi)
const delegateAddress = generateSigner(umi)
await create(umi, {
asset: assetSigner,
name: 'My Asset',
uri: 'https://example.com/my-asset.json',
plugins: [
{
type: 'FreezeExecute',
data: { frozen: false },
authority: { type: 'Address', address: delegateAddress.publicKey },
},
],
}).sendAndConfirm(umi)
})()
Freeze Executeプラグインを持つCollectionの作成
Freeze ExecuteプラグインはCollectionにも適用できます:
Freeze Executeプラグインを持つCollectionの作成
import { generateSigner } from '@metaplex-foundation/umi'
import { createCollection, mplCore } from '@metaplex-foundation/mpl-core'
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
;(async () => {
const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
const collectionSigner = generateSigner(umi)
await createCollection(umi, {
collection: collectionSigner,
name: 'My Collection',
uri: 'https://example.com/my-collection.json',
plugins: [{ type: 'FreezeExecute', frozen: false }],
}).sendAndConfirm(umi)
})()
Execute操作のフリーズ
updatePluginコマンドを使用して、AssetのExecute機能をフリーズし、フリーズ解除されるまで任意の命令の実行を防ぐことができます。
MPL Core AssetのExecute操作のフリーズ
import { createUmi, publicKey } from '@metaplex-foundation/umi'
import { updatePlugin, mplCore } from '@metaplex-foundation/mpl-core'
;(async () => {
const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
const assetAddress = publicKey('11111111111111111111111111111111')
await updatePlugin(umi, {
asset: assetAddress,
plugin: { type: 'FreezeExecute', data: { frozen: true } },
}).sendAndConfirm(umi)
})()
Execute操作のフリーズ解除
updatePluginコマンドを使用して、AssetのExecute機能のフリーズを解除し、任意の命令を実行する能力を復元することもできます。
MPL Core AssetのExecute操作のフリーズ解除
import { createUmi, publicKey } from '@metaplex-foundation/umi'
import { updatePlugin, mplCore } from '@metaplex-foundation/mpl-core'
;(async () => {
const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
const assetAddress = publicKey('11111111111111111111111111111111')
await updatePlugin(umi, {
asset: assetAddress,
plugin: { type: 'FreezeExecute', data: { frozen: false } },
}).sendAndConfirm(umi)
})()
プラグインAuthority
Freeze Executeプラグインは、execute操作のフリーズ/フリーズ解除を制御できる人を決定するために、さまざまなauthorityタイプをサポートしています:
- Owner Authority(デフォルト): アセットオーナーのみがフリーズ/フリーズ解除可能
- Delegate Authority: 特定のアドレスにフリーズを制御する権限をデリゲート可能
- Update Authority: アセットのupdate authorityがフリーズを制御可能(ただし明示的にデリゲートされた場合のみ)
プラグインAuthorityの設定
import { generateSigner } from "@metaplex-foundation/umi";
import { create, mplCore } from "@metaplex-foundation/mpl-core";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
(async () => {
const umi = createUmi("https://api.devnet.solana.com").use(mplCore());
const assetSigner = generateSigner(umi);
const delegateAddress = generateSigner(umi);
await create(umi, {
asset: assetSigner,
name: "My Asset",
uri: "https://example.com/my-asset.json",
plugins: [
{
type: "FreezeExecute",
data: { frozen: false },
authority: { type: "Address", address: delegateAddress.publicKey },
},
],
}).sendAndConfirm(umi);
})();
重要な注意事項
frozenフィールドがtrueに設定されると、すべてのexecute操作がブロックされます- デフォルトauthority: アセットオーナーがデフォルトでプラグインを制御します
- Authorityデリゲーション: 現在のauthorityのみがexecute機能をフリーズ/フリーズ解除できます
- Authority制約: authorityが他の人にデリゲートされている場合、元のオーナーはauthorityが取り消されるまでフリーズを解除できません
- フリーズ中はプラグインを削除できません
- フリーズ中はauthorityを再割り当てできません
- プラグインはExecute命令システムと連携します
ユースケース例: Backed NFT
Freeze Executeプラグインの一般的なユースケースは、NFTが基礎資産(SOLやトークンなど)の所有権を表し、execute命令を通じて引き出し可能な「backed NFT」を作成することです。プラグインにより、これらのexecute操作を一時的にフリーズできます。
Backed NFTの例
import {
generateSigner,
publicKey,
sol,
createNoopSigner,
keypairIdentity,
} from "@metaplex-foundation/umi";
import {
create,
execute,
findAssetSignerPda,
updatePlugin,
fetchAsset,
mplCore,
} from "@metaplex-foundation/mpl-core";
import { transferSol } from "@metaplex-foundation/mpl-toolbox";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
(async () => {
const umi = createUmi("https://api.devnet.solana.com").use(mplCore());
// 代わりにあなたのウォレットを使用
const wallet = generateSigner(umi);
umi.use(keypairIdentity(wallet));
// 1. フリーズされたexecute機能を持つアセットを作成
const assetSigner = generateSigner(umi);
await create(umi, {
asset: assetSigner,
name: "Backed NFT",
uri: "https://example.com/backed-nft.json",
plugins: [{ type: "FreezeExecute", frozen: true }],
}).sendAndConfirm(umi);
// 2. Asset Signer PDAを見つける
const [assetSignerPda] = findAssetSignerPda(umi, {
asset: assetSigner.publicKey,
});
// 3. NFTを「裏付ける」ためにSOLを入金
await transferSol(umi, {
source: umi.identity,
destination: publicKey(assetSignerPda),
amount: sol(0.01), // 0.01 SOLの裏付け
}).sendAndConfirm(umi);
// 4. フリーズ中はexecute操作がブロックされる
// このトランザクションは失敗します:
try {
await execute(umi, {
asset: await fetchAsset(umi, assetSigner.publicKey),
instructions: transferSol(umi, {
source: createNoopSigner(publicKey(assetSignerPda)),
destination: generateSigner(umi).publicKey,
amount: sol(0.001),
}),
}).sendAndConfirm(umi, { send: { skipPreflight: true } });
} catch (e) {
console.log("予想通りexecuteが失敗", e);
}
// 5. 引き出しを許可するためにフリーズ解除
await updatePlugin(umi, {
asset: assetSigner.publicKey,
plugin: { type: "FreezeExecute", data: { frozen: false } },
}).sendAndConfirm(umi);
// 6. これでexecute操作が許可される
const recipient = generateSigner(umi);
await execute(umi, {
asset: await fetchAsset(umi, assetSigner.publicKey),
instructions: transferSol(umi, {
source: createNoopSigner(publicKey(assetSignerPda)),
destination: recipient.publicKey,
amount: sol(0.001),
}),
}).sendAndConfirm(umi);
})();
