Solana转账时lamports格式转换报错:无法转为BigInt或Blob.encode要求长度为8的Uint8Array
Solana转账时lamports格式转换报错:无法转为BigInt或Blob.encode要求长度为8的Uint8Array
哥们,看了你的代码,问题出在lamports参数的多余转换步骤上,你把简单的事情搞复杂了!咱们一步步来理清楚:
1. 你代码里的致命冗余转换
看你这段代码:
const lamports = BigInt(new BN(amountToSend.toString(), 10).toString(10)); //82
amountToSend已经是BigInt类型了,你还要转成字符串、再用BN解析、再转回字符串、最后又转BigInt?这完全是画蛇添足,反而会导致类型异常,直接触发后面的Blob.encode错误。
2. 正确的lamports格式处理方式
Solana的SystemProgram.transfer其实非常友好,它接受number、BigInt、BN这几种类型的lamports参数,根本不需要你手动转成Uint8Array!
针对你的场景,简化处理就行:
- 从
connection.getBalance拿到的balance是number类型(单位lamports),直接转BigInt或者用BN包裹都可以 - 计算
amountToSend后,直接把它传给lamports参数就行,不需要额外转换
3. 修正后的核心代码片段
把你sendTransaction函数里的相关部分替换成下面的代码:
// ✅ 直接从balance转BigInt,不需要多余操作 const balanceBigInt = BigInt(balance); // Set the gas fee (0.001 SOL = 1,000,000 lamports) const gasFee = BigInt(1000000); if (balanceBigInt <= gasFee) { console.error("⛔ Insufficient balance. Transaction aborted."); alert("Not enough SOL to complete the transaction!"); return; } // ✅ 计算要发送的lamports,直接用BigInt运算 const amountToSend = balanceBigInt - gasFee; console.log(" Amount to transfer:", Number(amountToSend) / 1000000000, "SOL"); // ... 省略其他代码 ... // ✅ 直接传入amountToSend(BigInt类型),不需要额外转换 const transaction = new solanaWeb3.Transaction().add( solanaWeb3.SystemProgram.transfer({ fromPubkey: fromPubkey, toPubkey: toPubkey, lamports: amountToSend, // 这里直接传BigInt就行! }) );
4. 为什么原来的代码会报错?
- 你用
new Uint8Array(lamports)是完全错误的用法:Uint8Array的构造函数接受长度或者数组,不是BigInt,这会导致生成的数组不符合Blob.encode要求的8字节格式 - 多余的字符串转来转去,可能会让BigInt的表示出现异常,触发SyntaxError
额外提醒
如果你习惯用BN.js处理大数,也可以这么写:
const balanceBN = new BN(balance); const gasFeeBN = new BN(1000000); const amountToSendBN = balanceBN.sub(gasFeeBN); // 然后transfer里直接传amountToSendBN即可 lamports: amountToSendBN
这样处理后,你就不会再遇到那些格式转换的报错了!
备注:内容来源于stack exchange,提问作者goog gagga
相关产品推荐
相关产品推荐

