Solana带转账费代币:TransferCheckedWithFee与TransferChecked差在哪
直接回答:两者都会按mint配置自动扣留转账费,区别在于TransferCheckedWithFee会额外校验你预期的费用,TransferChecked不做这项校验。按Solana官方文档的口径,带转账费扩展(TransferFeeConfig)的mint在每次转账时,转账金额会先被扣除配置的费用,被扣留的费用记在目标代币账户上;TransferCheckedWithFee用于转账并验证预期费用,而TransferChecked同样可用,并会自动在目标代币账户上扣留配置的费用。换句话说,前者多校的是“费用是否符合预期”,而不是“是否收费”。
要理解这个差别,先看适用对象和条件。转账费扩展只对带有TransferFeeConfig的mint生效;为这类mint初始化代币账户时,账户会自动带上TransferFeeAmount扩展。通过Associated Token Program创建账户时,程序会按所需大小计算并创建账户,同时满足租金豁免。也就是说,只要mint配置了转账费,普通代币账户就处在“会被扣费”的轨道上,转账行为本身绕不开扣留机制。
两种指令的实际差异落在费用校验这一环。TransferChecked走常规路径:发起转账,链上按mint当前配置扣留费用,费用记录在目标代币账户,不会因为调用方的预期不同而拦截。TransferCheckedWithFee在此之上要求调用方给出预期费用,由指令进行校验,官方文档明确其用途是“transfer tokens and verify the expected fee”。因此,当实际扣留与预期不一致时,后者会因校验不通过而失败。需要说明的是,这里只讨论“校验预期费用”和“自动扣费”这一层,费率如何计算属于mint配置层面,本文不展开。
用一个假设案例说明。假设某mint配置了转账费,费率由该mint的配置决定,你计划转出100枚代币,并预期被扣留1枚、目标账户实收99枚。若使用TransferCheckedWithFee并传入预期费用1枚,链上按配置扣留的费用与预期一致,校验通过;若配置在此期间发生变化,实际扣留与预期不符,校验就会失败。若使用TransferChecked,转账照常执行,按当时配置扣留费用,不会因为你的预期不同而报错。案例中的数字仅为说明机制,不代表任何真实费率,也不代表通用比例。
还有一层容易被忽略的机制:被扣留的费用并不直接进入对方可自由使用的余额,而是记在目标代币账户上。后续要动用这笔费用,需要由mint的withdraw_withheld_authority签名,通过WithdrawWithheldTokensFromAccounts从代币账户转到费用接收账户;也可以先由无需许可的HarvestWithheldTokensToMint把费用归集到mint账户,再用WithdrawWithheldTokensFromMint提取。此外,SetTransferFee更新的是下一次转账的费用配置,从两个epoch之后才生效。这些机制对两种指令同样适用,区别仍只在费用校验这一环。
所以选择并不复杂:需要把预期费用作为转账条件、费用不符就失败,用TransferCheckedWithFee;只要求按配置自动扣费、不校验预期,TransferChecked即可。两者都不改变扣留与提取的既有流程。