Solana 多对多转账:钱包一一配对
配对钱包转账在 Solana 上怎么走:一行一笔交易,每笔 0.001 SOL,以及宁可跳过整行也不削减金额的 rent 规则。

在 Solana 上批量转账有三种形态,这三种一直被人混作一谈。批量转账工具从一个钱包付给一份名单。归集工具把许多钱包收进一个。剩下的那种情况,也就是多对多,前两者都表达不出来。
一笔多对多转账让每个发送钱包只对应自己的收款地址。发送钱包 1 付给地址 1,发送钱包 40 付给地址 40,两行互不相干。每一行是一笔单独的交易,由出钱的那个钱包自己签名。
听着像细枝末节。实际上这是资金只有一个来源,和四十个彼此独立的来源之间的差别。
- 一行就是一笔交易。这一行的发送钱包承担这一行的全部开销。
- 平台费每笔转账 0.001 SOL,网络费 0.000005 SOL。
- 从没持有过该代币的收款方,还要再加 0.00149 SOL 的 rent 押金。
- 过不了检查的行会被整行跳过,而不是把金额削下去。
批量转账的三种形态
批量转账工具是一对多。一个钱包,一份收款名单,一个付款方。空投要的就是这种形态。
批量归集工具是多对一。四十个钱包,一个目的地,跑完之后所有余额落在同一处。
多对多工具是第三种形态,也是唯一认得配对关系的一种。它读两列地址和一个金额,把一行当作一个整体,用这一行写明的那个钱包来签名。没有公用资金池,行与行之间也不互相补位。
一行要花多少
在多对多转账里,一行上最多摆着三项开销,全部由这一行的发送钱包承担。没有公用的出资账户,所以一个连自己这一行都付不起的钱包,也不会向上一行借。网络那一项是每个签名 5000 lamport 的基础费,Solana 自家的手续费文档写得很清楚。
| 项目 | SOL 模式 | 代币模式 |
|---|---|---|
| 平台费 | 0.001 SOL | 0.001 SOL |
| 网络费 | 0.000005 SOL | 0.000005 SOL |
| 收款方的代币账户 | 不涉及 | 0.00149 SOL,且仅当该收款方从未持有过这种代币 |
第三行值得看两遍,因为绊住人的正是它。把一个 SPL 代币发给一个从没碰过它的地址,等于新建一个账户来装它,而 Solana 要为这个账户收一笔 rent 押金。这笔押金远远高于网络费。
一百个新收款方,这一项就占到账单里的 0.149 SOL 左右,而这一百行的平台费只有 0.1 SOL。押金不会被销毁:它留在收款方的代币账户里,日后谁关掉这个账户就退给谁。
被跳过的行
多对多在签名之前会跑两道检查,两道都是把行拦下来,而不是改动它。
第一道是简单的算术。如果发送钱包付不起自己的金额加手续费,再加上可能要开的代币账户,这一行就被打上标记,原样留着。不会有半截发出去的情况。
第二道更古怪,也值得弄明白,因为第一次碰到时,它看起来像个 bug。Solana 不允许留下一个余额大于零、却低于免 rent 门槛的账户。普通钱包的这个门槛是 0.00065 SOL,出自 Solana 的账户文档里那条公式。
把账户彻底清空是允许的。在里面留下 0.00005 SOL 则不允许。凡是会让钱包落进零到门槛之间这段区间的行,都会被标成 rent dust,原样留着不发。
为什么不干脆把金额削一点
另一条路是把金额一点点削到刚好够用,那样更糟。数字是人自己填进去的。一个不吭声就改了数字再发出去的工具,事后没法再拿表格对账。
要么把余额整个发走,要么降低金额,让剩下的部分越过门槛。预览会提前说清哪几行受影响,工具也会在签名之前,用一次调用把所有目标账户查一遍,所以你看到的估算就是你要付的。
一行一笔交易,为什么这点要紧
多对多把每一行都做成自己独立的交易,所以倒下的那行只倒它自己。换成把多笔转账堆进一笔交易的批处理,只要有一个目的地址出错,同一笔里其余的好转账也会一起失败。
这是有代价的:四十对就是四十个签名,每个多付 0.000005 SOL 的网络费,这笔钱不值得去省。换来的是一份可以逐行读的结果:失败的只是结果表里带着原因的一行,重跑也只重跑那一行。想知道优先费怎么影响这些交易上链的速度,数字放在 Solana 优先费该给多少那一篇里。
什么时候多对多才是对的形态
对大多数人来说,最实在的用途是轮换钱包。手上一批钱包带着你想甩掉的旧历史,就用钱包批量生成器做一批新的,让旧钱包 7 只给新钱包 7 转钱,别的都不动。一次运行,四十对,四十笔互相独立的交易。
第二种是付款名单,付款方逐行变化。几个项目,几个金库,一张表。批量转账工具根本表达不了,因为它的资金来源正好只有一个。
第三种是快照之后的再分配,每个持有者由一个事先指派给他的钱包付款。分发之前怎么读那份持有者分布,写在如何解读代币持有者分布里。
名单要怎么备
多对多的第一趟先用两行跑。结果表会告诉你一行到底花了多少,连代币账户押金一起算进去,然后再去发整份名单。
顺手也查一下收款方是不是已经持有这种代币。半数是老持有者的名单,押金那一项会直接砍掉一半,而在一百行的规模上,这一项在整张账单里分量不小。
开跑之前把哪个钱包付哪一行记下来。跑完之后再去还原这份对应关系,比现在听上去费劲,尤其当发送钱包是刚生成的、还没有可供辨认的历史时。
关于余额最后提一句:每个发送钱包里的钱,要够它那一行的金额加手续费,还要想好发完之后剩多少。剩零没问题,剩得比 0.00065 SOL 多也没问题,剩在两者之间,这一行就会被跳过,你得回头调整金额或补足余额再跑,比一开始就想清楚更慢。
名单变大之后会变的事
十行的时候,上面这些都不费事。多对多跑到两千行,有两件事会变成真正的工作,而且都发生在工具之外。
第一件是备款。每个发送钱包在开跑前都得备好自己的金额加手续费,没有哪一行能替另一行垫上。这意味着要先跑一趟分发,通常从一个金库出,金额宁可备得宽松些,也别掐着算。
第二件是事后对账。四十行看看表就行。两千行就得把结果导出来,跟原始表逐行核对,因为被跳过的行在区块浏览器里根本不会出现:它们作为交易从未存在过。
还有一个不那么显眼的效果。如果名单里新收款方和老收款方混着,每行成本就不是恒定的,拿前十行算出来的平均值,会和实际总数对不上。数一数有多少收款方要新开账户,只把这个数乘以 0.00149 SOL。
常见问题
这跟把批量转账工具跑很多遍有什么不同?
批量转账工具按设计只有一个出资钱包,每跑一次,所有收款方都从这一个钱包拿钱。要换四十个付款钱包,就得跑四十次,外加四十次手工切换钱包。多对多是一次运行,四十行。
失败的行会不会产生费用?
要看失败发生在哪一步。没通过预检的行根本不签名,没有交易到达网络,所以不花钱。已经签名、广播,却在链上失败的行,和任何失败的 Solana 交易一样,要付网络费。平台费是同一笔交易里的一条指令,转账不成功就不会结算。
发送方和收款方可以重叠吗?
可以。同一个钱包能在某一行发出、在另一行收到。每一行都是独立的交易,行与行之间不保证先后顺序。如果第 2 行要花第 1 行刚转进来的钱,就拆成两次运行。
为什么我的行被标成 rent dust?
因为这一行发完之后,发送钱包会剩下介于零和 0.00065 SOL 之间的余额,而 Solana 不接受处于这种状态的账户。把余额整个发走让钱包归零,或者降低金额,让剩下的部分越过门槛。
只发代币的钱包也需要 SOL 吗?
需要。就算挪的是代币,网络费和平台费也是用 SOL 付的,收款方要新开账户时,代币账户押金同样用 SOL 付。只有代币、没有 SOL 的钱包什么也发不出去。
配对的数量有上限吗?
没有固定上限,粘贴几千对进去,工具也不会拦。这些配对按每批 100 笔签名并发出,再按每批最多 256 笔确认,每次确认最长等 90 秒,所以长的一趟要几分钟,不是几秒。能盯着看的一趟才是能修的一趟,很长的名单分成几趟小的更好处理。真正拦住你的往往是准备工作:每个发送钱包都得事先备好钱。
一句话怎么定
如果表里有一列写着付款方,要的就是多对多这种形态。如果所有行都从同一个钱包出,那就用批量转账工具,省掉这套配置。要是有一行没发出去,先看是不是撞上了 rent 门槛,再去怀疑是不是出了 bug。关于这个门槛,租金不足怎么办那篇写得更细。


