You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python的Solders库从JSON钱包文件转移SOL时遇ValueError错误求助

使用Python的Solders库从JSON钱包文件转移SOL时遇ValueError错误求助

看起来你遇到的ValueError是因为处理私钥的方式不对,我们一步步来解决这个问题:

错误原因分析

你代码里的create_keypair函数用了bytes.fromhex(private_key)来转换私钥,但JSON里的私钥是Base58编码的Solana标准私钥格式,不是十六进制字符串。Solana的私钥默认是用Base58编码的,用十六进制解析肯定会遇到非0-9/a-f的字符,直接触发这个错误。

修复步骤

1. 替换私钥解码方式

首先需要安装base58库(如果没装的话),用Base58解码私钥,而不是十六进制:

pip install base58

然后修改create_keypair函数(其实不需要传入公钥,Keypair可以直接从私钥推导公钥):

import base58  # 新增导入

def create_keypair(private_key: str) -> Keypair:
    # 用Base58解码Solana私钥
    private_bytes = base58.b58decode(private_key)
    return Keypair.from_secret_key(private_bytes)

2. 修复接收方地址处理

你现在的代码里receiver是用户输入的字符串,直接用receiver.pubkey会报错,需要把它转换成solders.pubkey.Pubkey对象:

from solders.pubkey import Pubkey  # 新增导入

# 替换原来的receiver输入部分
receiver_addr = input(str("To which Address should be the SOL sent? \n --> "))
receiver = Pubkey.from_string(receiver_addr)

3. 修复交易创建与发送的细节

你的代码还有几个遗漏的问题:

  • MessageV0.try_compile里的sender.pubkey()是错误写法,应该用sender.pubkey(Keypair的pubkey是属性,不是方法)
  • 固定转2140000 lamports不合理,应该获取钱包余额后扣除手续费再转出
  • 你只创建了交易但没有发送到链上,需要补充发送和确认逻辑
  • Blockhash需要用返回值里的blockhash字段,还要注意它的过期时间

完整修复后的代码

from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solana.rpc.api import Client
from solana.rpc.types import TxOpts
from solders.system_program import transfer, TransferParams
from solders.transaction import VersionedTransaction
from solders.message import MessageV0
import json
import base58


SOLANA_RPC_URL = "https://api.mainnet-beta.solana.com"
client = Client(SOLANA_RPC_URL)

with open(r"C:\Users\Fabsen\Desktop\Coding\Python\Projekte\Volume Bot\wallets.json", "r") as file:
    wallets_data = json.load(file)
    
def create_keypair(private_key: str) -> Keypair:
    # 用Base58解码Solana私钥
    private_bytes = base58.b58decode(private_key)
    return Keypair.from_secret_key(private_bytes)

# 生成发送方Keypair列表(无需传入公钥,私钥可直接推导)
senders = [
    create_keypair(wallet['private key'])
    for wallet in wallets_data
]

# 处理接收方地址
receiver_addr = input(str("To which Address should be the SOL sent? \n --> "))
receiver = Pubkey.from_string(receiver_addr)

# 获取最新Blockhash
blockhash_resp = client.get_latest_blockhash()
blockhash = blockhash_resp.value.blockhash

# 逐个处理钱包转账
for idx, sender in enumerate(senders):
    print(f"正在处理钱包 {idx+1}: {sender.pubkey}")
    
    # 获取钱包当前余额(单位:lamports)
    balance_resp = client.get_balance(sender.pubkey)
    balance = balance_resp.value
    
    if balance <= 5000:  # 预留足够手续费,避免余额不足
        print(f"钱包 {sender.pubkey} 余额不足,跳过")
        continue
    
    # 计算可转账金额:余额减去手续费(这里留5000 lamports,可根据交易大小调整)
    transfer_lamports = balance - 5000
    
    # 构建转账指令
    ix = transfer(
        TransferParams(
            from_pubkey=sender.pubkey,
            to_pubkey=receiver,
            lamports=transfer_lamports,
        )
    )
    
    # 构建V0版本交易消息
    msg = MessageV0.try_compile(
        payer=sender.pubkey,
        instructions=[ix],
        address_lookup_table_accounts=[],
        recent_blockhash=blockhash,
    )
    
    # 签名交易
    tx = VersionedTransaction(msg, [sender])
    
    # 发送并确认交易
    try:
        send_resp = client.send_transaction(tx, opts=TxOpts(skip_preflight=True))
        tx_signature = send_resp.value
        print(f"交易已发送,签名: {tx_signature}")
        
        # 等待交易确认
        confirm_resp = client.confirm_transaction(tx_signature)
        if confirm_resp.value.err is None:
            print(f"交易 {tx_signature} 已成功确认")
        else:
            print(f"交易 {tx_signature} 失败: {confirm_resp.value.err}")
    except Exception as e:
        print(f"处理钱包 {sender.pubkey} 时出错: {str(e)}")

额外注意事项

  • 手续费预留:一定要给钱包留足够的手续费(至少5000 lamports),否则交易会因为余额不足失败。
  • Blockhash过期:Solana的Blockhash约2分钟后过期,如果处理大量钱包,建议每处理几个就重新获取一次最新Blockhash。
  • 测试建议:在主网操作前,务必先在Devnet测试代码,避免资金损失。
  • 冗余字段:JSON里的public key字段其实可以不用,Keypair能直接从私钥推导公钥,所以代码里我简化了这部分逻辑。

备注:内容来源于stack exchange,提问作者Fabiano_Pe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:38:01