機能

Execute Asset Signing

Last updated January 31, 2026

MPL Core Execute命令は、MPL Core AssetsにAsset Signersの概念を導入します。 これらのAsset Signersは、Asset自体に代わって署名者として機能し、MPL Core Assetsに以下の機能を提供します:

  • SolanaとSPLトークンを転送する
  • 他のアカウントの権限になる
  • assetSignerPdaに割り当てられたトランザクション/命令/CPI署名を必要とする他のアクションと検証を実行する MPL Core Assetsは、ブロックチェーンにトランザクション/CPIを署名して送信する機能を持っています。これにより、Core AssetはassetSignerという形で独自のウォレットを持つことができます。

Asset Signer PDA

AssetsはassetSignerPdaアカウント/アドレスにアクセスできるようになり、MPL Coreプログラムのexecute命令が、送信された追加の命令をassetSignerPdaでCPI命令に署名して通過させることができます。 これにより、assetSignerPdaアカウントは、現在のアセット所有者に代わってアカウント命令を効果的に所有および実行できます。 assetSignerPdaは、Core Assetに接続されたウォレットと考えることができます。

findAssetSignerPda()

const assetId = publickey('11111111111111111111111111111111')
const assetSignerPda = findAssetSignerPda(umi, { asset: assetId })

Execute命令

概要

execute命令を使用すると、ユーザーはCore Assetと、オンチェーンでMPL Coreプログラムのexecute命令に到達したときにAssetSignerによって署名されるパススルー命令を渡すことができます。 execute命令とその引数の概要:

const executeIx = await execute(umi, {
{
// `fetchAsset()`を介してトランザクションに署名するアセット
asset: AssetV1,
// `fetchCollection()`を介したコレクション
collection?: CollectionV1,
// TransactionBuilder | Instruction[]のいずれか
instructions: ExecuteInput,
// トランザクション/命令に必要な追加の署名者
signers?: Signer[]
}
})

検証

assetSignerPda検証

MPL Core Execute命令は、現在のAsset所有者もトランザクションに署名していることを検証します。これにより、現在のAsset所有者のみがexecute命令でassetSignerPdaを使用してトランザクションを実行できることが保証されます。

Execute操作の制御

execute機能はFreeze Executeプラグインを使用して制御できます。このプラグインにより、アセットのexecute操作をフリーズし、フリーズ解除されるまでexecute命令の処理を防ぐことができます。 Freeze Executeプラグインは以下の場合に特に役立ちます:

  • バックドNFT: 必要に応じて基礎となるアセットの引き出しを防止
  • エスクローレスプロトコル: プロトコル操作中にexecute機能を一時的にロック
  • セキュリティ対策: 複雑な操作を実行できるアセットに追加の保護レイヤーを追加 Freeze Executeプラグインがアクティブでfrozen: trueに設定されている場合、プラグインがfrozen: falseに更新されるまで、execute命令の使用はブロックされます。

Asset SignerからSOLを転送する

以下の例では、assetSignerPdaに送信されたSOLを任意の宛先に転送します。

import {
execute,
findAssetSignerPda,
fetchAsset,
fetchCollection,
} from '@metaplex-foundation/mpl-core'
import { transferSol } from '@metaplex-foundation/mpl-toolbox'
import { publickey, createNoopSigner, sol } from '@metaplex-foundation/umi'
const assetId = publickey('11111111111111111111111111111111')
const asset = await fetchAsset(umi, assetId)
// オプション - Assetがコレクションの一部の場合、コレクションオブジェクトを取得
const collection =
asset.updateAuthority.type == 'Collection' && asset.updateAuthority.address
? await fetchCollection(umi, asset.updateAuthority.address)
: undefined
// Asset signerはアカウントに1 SOLの残高を持っています
const assetSignerPda = findAssetSignerPda(umi, { asset: assetId })
// SOLを転送する宛先アカウント
const destination = publickey('2222222222222222222222222222222222')
// 標準的な`transferSol()` transactionBuilder
const transferSolIx = transferSol(umi, {
// assetSignerが後でCPI中に署名するため、noopSignerを作成
source: createNoopSigner(publicKey(assetSigner)),
// 宛先アドレス
destination,
// 転送する金額
amount: sol(0.5),
})
// `execute`命令を呼び出してチェーンに送信
const res = await execute(umi, {
// このアセットで命令を実行
asset,
// Assetがコレクションの一部の場合、`fetchCollection()`を介してコレクションオブジェクトを渡す
collection,
// 実行するtransactionBuilder/instruction[]
instructions: transferSolIx,
}).sendAndConfirm(umi)
console.log({ res })

Asset SignerからSPLトークンを転送する

以下の例では、assetSignerPdaアカウントからSPLトークン残高の一部を宛先に転送します。 この例は、ベースウォレットアドレスの派生トークンアカウントに関するベストプラクティスに基づいています。トークンがassetSignerPdaアドレスに基づいて正しく派生されたトークンアカウントにない場合、この例を調整する必要があります。

import {
execute,
findAssetSignerPda,
fetchAsset,
fetchCollection,
} from '@metaplex-foundation/mpl-core'
import {
transferTokens,
findAssociatedTokenPda,
} from '@metaplex-foundation/mpl-toolbox'
import { publickey } from '@metaplex-foundation/umi'
const assetId = publickey('11111111111111111111111111111111')
const asset = await fetchAsset(umi, assetId)
// オプション - Assetがコレクションの一部の場合、コレクションオブジェクトを取得
const collection =
asset.updateAuthority.type == 'Collection' && asset.updateAuthority.address
? await fetchCollection(umi, asset.updateAuthority.address)
: undefined
const splTokenMint = publickey('2222222222222222222222222222222222')
// Asset signerはトークン残高を持っています
const assetSignerPda = findAssetSignerPda(umi, { asset: assetId })
// SOLを転送する宛先ウォレット
const destinationWallet = publickey('3333333333333333333333333333333')
// 標準的な`transferTokens()` transactionBuilder
const transferTokensIx = transferTokens(umi, {
// ソースは`assetSignerPda`派生トークンアカウント
source: findAssociatedTokenPda(umi, {
mint: splTokenMint,
owner: assetSignerPda,
}),
// 宛先は`destinationWallet`派生トークンアカウント
destination: findAssociatedTokenPda(umi, {
mint: splTokenMint,
owner: destinationWallet,
}),
// lamportsで送信する金額
amount: 5000,
})
// `execute`命令を呼び出してチェーンに送信
const res = await execute(umi, {
// このアセットで命令を実行
asset,
// Assetがコレクションの一部の場合、`fetchCollection()`を介してコレクションオブジェクトを渡す
collection,
// 実行するtransactionBuilder/instruction[]
instructions: transferTokensIx,
}).sendAndConfirm(umi)
console.log({ res })

アセットの所有権を別のアセットに転送する

以下の例では、別のCore Assetが所有するCore Assetを、さらに別のAssetに転送します。

import {
execute,
fetchAsset,
fetchCollection,
findAssetSignerPda,
transfer,
} from '@metaplex-foundation/mpl-core'
import { publickey } from '@metaplex-foundation/umi'
// 転送するアセット
const assetId = publickey('11111111111111111111111111111111')
const asset = await fetchAsset(assetId)
// オプション - Assetがコレクションの一部の場合、コレクションオブジェクトを取得
const collection =
asset.updateAuthority.type == 'Collection' && asset.updateAuthority.address
? await fetchCollection(umi, asset.updateAuthority.address)
: undefined
// 転送するAssetを所有するAsset ID
const sourceAssetId = publickey('2222222222222222222222222222222222')
// ソースAssetオブジェクト
const sourceAsset = fetchAsset(umi, sourceAssetId)
// Asset signerはアカウントに1 SOLの残高を持っています
const sourceAssetSignerPda = findAssetSignerPda(umi, { asset: assetId })
// SOLを転送する宛先アカウント
const destinationAssetId = publickey('33333333333333333333333333333333')
// Assetを転送する宛先Asset signer
const destinationAssetSignerPda = findAssetSignerPda(umi, {
asset: destinationAssetId,
})
const transferAssetIx = transfer(umi, {
// `fetchAsset()`を介したAssetオブジェクト
asset,
// オプション - `fetchCollection()`を介したCollectionオブジェクト
collection,
// Assetの新しい所有者
newOwner: destinationAssetSignerPda,
}).sendAndConfirm(umi)
const res = await execute(umi, {
// このアセットで命令を実行
asset,
// Assetがコレクションの一部の場合、`fetchCollection()`を介してコレクションオブジェクトを渡す
collection,
// 実行するtransactionBuilder/instruction[]
instructions: transferAssetIx,
}).sendAndConfirm(umi)
console.log({ res })