插件
Freeze Execute
Last updated January 31, 2026
概述
Freeze Execute 插件是一个所有者管理的插件,允许冻结 Asset 上的 Execute 生命周期事件。当冻结时,资产无法通过其 Asset Signer PDA 执行任意指令,有效阻止任何执行操作直到解冻。
重要:由于这是一个所有者管理的插件,资产转移到新所有者后权限不会保留。如果新所有者希望之前的权限方能够更改插件的 freeze 状态,需要重新添加权限。
Freeze Execute 插件特别适用于以下场景:
- 担保 NFT:锁定代表基础资产(SOL、代币)所有权的 NFT,防止未经授权的提取
- 无托管资产管理:在不转移所有权的情况下冻结参与金融操作的资产
- 质押协议:在保持所有权的同时防止质押期间的资产执行
- 智能合约安全:为可执行复杂操作的资产添加保护层
- 治理控制:为参与治理或投票的资产实施冻结机制
- 资产租赁:在资产被租出期间防止执行
- 抵押品管理:锁定在 DeFi 协议中用作抵押品的资产
兼容性
| MPL Core Asset | ✅ |
| MPL Core Collection | ✅ |
参数
| 参数 | 值 |
|---|---|
| frozen | bool |
函数
向 Asset 添加 Freeze Execute 插件
addPlugin 命令将 Freeze Execute 插件添加到 Asset。此插件允许冻结 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
您也可以在资产创建时添加 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)
})()
插件权限
Freeze Execute 插件支持不同的权限类型来控制谁可以冻结/解冻执行操作:
- 所有者权限(默认):只有资产所有者可以冻结/解冻
- 委托权限:可以将特定地址委托来控制冻结
- 更新权限:资产的更新权限可以控制冻结,但仅在明确委托的情况下
设置插件权限
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 指令 系统配合使用
使用案例示例:担保 NFT
Freeze Execute 插件的一个常见用例是创建"担保 NFT",其中 NFT 代表可通过执行指令提取的基础资产(如 SOL 或代币)的所有权。该插件允许您临时冻结这些执行操作。
担保 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. 创建具有冻结执行功能的 Asset
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. 存入 SOL 来"担保" NFT
await transferSol(umi, {
source: umi.identity,
destination: publicKey(assetSignerPda),
amount: sol(0.01), // 0.01 SOL 担保
}).sendAndConfirm(umi);
// 4. 冻结期间执行操作被阻止
// 此交易将失败:
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("执行按预期失败", e);
}
// 5. 解冻以允许提取
await updatePlugin(umi, {
asset: assetSigner.publicKey,
plugin: { type: "FreezeExecute", data: { frozen: false } },
}).sendAndConfirm(umi);
// 6. 现在执行操作被允许
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);
})();
