プラグイン

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

引数

引数
frozenbool

関数

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);
})();