关键术语:Transfer Hook、Token Extensions、Anchor 框架、SOL 费用、CPI 跨合约调用、PDA
Solana Token 2022 引入的 Transfer Hook 扩展允许开发者在每一笔转账发生时自动触发自定义逻辑,从而:
强制版税:NFT 二级市场自动收取创作分成
黑白名单:只允许预设地址收发代币
灵活手续费:按笔或按比例扣费
链上统计:记录转账次数、金额、来源等数据
其要点在于把「转账」这一孤立动作变成可编程事件,令整个代币生命周期更具可延展性。
Token Program 执行
transfer时检测到 Mint 启用了 Transfer Hook 扩展。Token Program 通过 CPI 调用程序员编写的 Transfer Hook 程序。
所有原始转账账户都会被设为 只读,防止特权滥用。
Hook 逻辑成功执行则转账继续;失败则整个交易回滚。
打开 Solana Playground 并点击 Import。
在终端依次输入:
build deploy test终端将打印四次成功日志,验证转账 Hook 正常工作。
示例代码(Rust,无额外账户):
pub fn transfer_hook(_ctx: Context<TransferHook>, amount: u64) -> Result<()> {
msg!("Hello Transfer Hook! 转账金额 {}", amount);
Ok(())
}
目标:为代币新增 全局转账计数器。
使用 PDA (
["counter"]) 存储计数器。需在
InitializeExtraAccountMetaList中声明额外账户。Hook 中务必检查
assert_is_transferring,防止恶意调用。
示例核心函数:
pub fn transfer_hook(ctx: Context<TransferHook>, _amount: u64) -> Result<()> {
assert_is_transferring(&ctx)?; // 防重放
let counter = &mut ctx.accounts.counter_account;
counter.value = counter.value.checked_add(1).unwrap();
msg!("累计转账次数 {}", counter.value);
Ok(())
}
现在,我们将代币转账与 自动 wSOL 手续费 相结合:每一次转账,Hook 程序将等值的 wSOL 从发送者扣走并转给指定地址。
以下每一步均可直接在 Playground 模板 中完成。
wsol_mint:Wrapped SOL 铸币账户delegate PDA:负责代扣手续费的「代理人」sender_wsol_ata&delegate_wsol_ata:双方 token account
transfer_checked(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
TransferChecked {
from: ctx.accounts.sender_wsol_token_account.to_account_info(),
mint: ctx.accounts.wsol_mint.to_account_info(),
to: ctx.accounts.delegate_wsol_token_account.to_account_info(),
authority: ctx.accounts.delegate.to_account_info(),
},
)
.with_signer(&[&[b"delegate", &[ctx.bumps.delegate]]]),
amount,
ctx.accounts.wsol_mint.decimals,
)?;
权限说明:发币者必须 approve delegate 代扣 wSOL,否则交易失败。
**Q:为何需要 fallback 指令?**A:Token Program 使用原生指令鉴别器,与 Anchor 生成的 Mac 指令识别不一致,需要在
fallback手动匹配Execute。**Q:wSOL 需预存多少?**A:Hook 的手续费与转账金额成正比,确保 wallet 内存 至少等于转账数额 + 交易费。
**Q:能限制只白名单钱包转账吗?**A:在 Hook 读取
destination_token.owner并校验黑名单/白名单即可。**Q:如何测试失败场景?**A:本地测试把
if条件抛出错误,如AmountTooBig,并在 JS 端try-catch验证失败回滚。**Q:能一次部署多个 Hook 程序?**A:每个 Mint 只能指定一个 Hook Program,可部署多个程序用不同 Mint 使用。
**Q:生产环境 gas 成本会很高吗?**A:一次 Transfer Hook 额外花费 ≈ 0.0003 SOL,主要用于新建 PDA 与 wSOL transfer,实际成本极低。
推荐阅读
Token Extensions 官方文档
Anchor Lang Book – Native CPI 章节
带着 Transfer Hook ,你可以把任何代币体验升级成「可编程资产」。现在就动手,为项目加一枚自定义逻辑的特洛伊木马吧!
