You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Pulsechain上程序化执行ERC20代币转账与交易的问题排查

Pulsechain上程序化执行ERC20代币转账与交易的问题排查

遇到交易返回哈希却迟迟不上链的情况确实让人头疼——明明节点返回了成功,结果交易就像石沉大海一样,既没出现在区块浏览器,也没在钱包里有任何变动。结合你的描述和代码,我来帮你一步步排查可能的原因:

首先明确核心问题:交易根本没进入链上内存池

RPC节点返回交易哈希,只代表它收到了你的交易请求,但不代表它会把交易广播到网络或者放进内存池(mempool)。如果交易没进内存池,矿工就根本看不到它,自然不会被打包进区块。

具体排查方向

1. Gas参数设置不合理(最常见原因)

Pulsechain网络有最低gas价格要求,如果你的交易gas price低于节点的最低阈值,节点会直接丢弃交易,不会广播。

  • 检查你的初始gasPrice来源:代码里的send_tx_with_nonce_adjustment函数里,txn的gasPrice是怎么设置的?如果只是用了w3.eth.gas_price,这个值是节点返回的"建议价",有时候可能低于实际网络的最低要求,尤其是在网络拥堵的时候。
  • 建议修改:在构建交易时,直接把gasPrice设置为int(w3.eth.gas_price * 1.2)(比建议价高20%),确保能被节点接收。
  • 同时要确认gas limit足够:比如转账交易可以用w3.eth.estimate_gas()估算,swap交易也要用build_transaction时正确估算gas,避免gas不足导致交易被拒绝。

2. Nonce计算错误

你的代码里有nonce调整逻辑,但可能存在以下问题:

  • 如果你之前提交过未确认的交易(同样没上链的),w3.eth.get_transaction_count(from_addr, "pending")返回的nonce可能包含这些无效交易的计数,导致新交易的nonce依然错误。
  • 建议:手动查询钱包地址在Pulsescan上的最新已确认交易的nonce,然后用这个值+1作为新交易的nonce,而不是依赖pending状态的计数。

3. RPC节点可靠性问题

你使用的https://pulsechain-rpc.publicnode.com可能存在广播故障,或者本身不支持交易广播。

  • 测试方法:换成Pulsechain官方RPC节点https://rpc.pulsechain.com,或者其他可靠的公共节点,重新提交交易,看是否能上链。
  • 验证交易是否被节点接收:提交交易后,调用w3.eth.get_transaction(tx_hash),如果返回None,说明节点根本没存储这个交易,问题肯定出在节点或者提交环节。

4. 交易签名或参数错误

虽然代码里用了Web3的签名工具,但还是可能存在细微错误:

  • 验证chainId:你设置的CHAIN_ID = 369是对的(Pulsechain主网链ID),但要确保构建交易时chainId参数正确传递到txn里。
  • 解码交易验证:把签名后的交易原始数据(signed_txn.raw_transaction.hex())拿到Pulsescan的"Decode Transaction"工具里解码,检查交易的to地址、value、gas、chainId等参数是否符合预期。

5. Swap交易的额外注意点

对于swapExactETHForTokens交易,除了上面的问题,还要检查:

  • Path参数是否正确:必须是[WPLS地址, 目标代币地址],因为PULSEX的Router需要先把原生PLS转换成WPLS再进行兑换。
  • 滑点设置:你当前代码里amountOutMin=0,虽然不会导致交易不上链,但如果价格波动大,交易打包后会失败,建议设置合理的滑点(比如基于当前价格乘以0.95,确保小波动下能完成交易)。

代码修改建议

转账交易构建(确保gas参数正确)

# 示例:构建转账交易
def build_transfer_txn(amount):
    txn = {
        'from': from_address,
        'to': to_address,
        'value': w3.to_wei(amount, 'ether'),
        # 估算gas limit
        'gas': w3.eth.estimate_gas({'from': from_address, 'to': to_address, 'value': w3.to_wei(amount, 'ether')}),
        # gasPrice比建议价高20%
        'gasPrice': int(w3.eth.gas_price * 1.2),
        # 用已确认的nonce,避免pending计数错误
        'nonce': w3.eth.get_transaction_count(from_address, 'latest'),
        'chainId': CHAIN_ID
    }
    return txn

Swap交易构建(确保path和参数正确)

def build_swap_txn(token_to_buy, pls_amount):
    token_to_buy_address = Web3.to_checksum_address(token_to_buy)
    # 正确的path:WPLS -> 目标代币
    path = [wpls_address, token_to_buy_address]
    # 设置10分钟过期时间
    deadline = int(time.time()) + 60 * 10
    # 估算最小输出(这里简单设置为当前价格的95%,实际可以用价格预言机获取)
    # 先获取代币价格,再计算amountOutMin
    amountOutMin = 0  # 建议替换为合理值
    swap_txn = swap_router.functions.swapExactETHForTokens(
        amountOutMin=amountOutMin,
        path=path,
        to=from_address,
        deadline=deadline
    ).build_transaction({
        'from': from_address,
        'value': w3.to_wei(pls_amount, 'ether'),
        'gas': w3.eth.estimate_gas({
            'from': from_address,
            'to': swap_router_address,
            'value': w3.to_wei(pls_amount, 'ether'),
            'data': swap_router.encodeABI(fn_name='swapExactETHForTokens', args=[amountOutMin, path, from_address, deadline])
        }),
        'gasPrice': int(w3.eth.gas_price * 1.2),
        'nonce': w3.eth.get_transaction_count(from_address, 'latest'),
        'chainId': CHAIN_ID
    })
    return swap_txn

快速验证步骤

  1. 先用w3.eth.get_transaction(tx_hash)查询你之前的交易哈希,如果返回None,说明交易没被节点接收,直接从gas参数或节点入手排查。
  2. 换官方RPC节点,用修改后的gasPrice重新提交一笔小额测试交易,看是否能上链。
  3. 手动确认钱包的nonce,确保交易的nonce是已确认交易的nonce+1。

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

火山引擎 最新活动