• java 调用合约使用nonce 可能会出现的问题


    热点账户
    所谓的热点账户就是频繁被使用的账户,在以太坊中比如交易所的统一出币账户,在短时间内频繁发起交易的账户,均可被称作热点账户。

    replacement transaction underpriced异常
    如果系统中的热点账户或普通账户发起交易时出现error: replacement transaction underpriced异常,那么就需要考虑nonce使用是否正确。

    引起此异常原因主要是当一个账户发起一笔交易,假设使用nonce为1,交易已经发送至节点中,但由于手续费不高或网络拥堵或nonce值过高,此交易处于queued中迟迟未被打包。

    同时此地址再发起一笔交易,如果通过eth_getTransactionCount获取的nonce值与上一个nonce值相同,用同样的nonce值再发出交易时,如果手续费高于原来的交易,那么第一笔交易将会被覆盖,如果手续费低于原来的交易就会发生上面的异常。

    通常发生此异常意味着:
    - 你的Ethereum客户端中已经有一币处于pending状态的交易。
    - 新的一笔交易拥有pending状态交易相同的nonce值。
    - 新的交易的gas price太小,无法覆盖pending状态的交易。

    通常情况下,覆盖掉一笔处于pending状态的交易gas price需要高于原交易的110%。

    解决方案
    针对此问题在不同的使用场景下有不同的解决方案。

    依赖钱包
    如果该热点账户的私钥信息等都存放在Ethereum客户端中,那么在发送交易的时候不传递nonce值,Ethereum客户端会帮你处理好此nonce值的排序。

    当然,此方案有两个弊端。第一个是安全性无法保障(未进行冷热账户分离),第二,在热点账户下如果想覆盖掉一笔交易,需要先查询一下该交易的信息,从中获取nonce值。

    自行管理nonce
    自行管理nonce适用于冷热账户模式,也就是适用sendRawTransaction发送已经签名好的交易时,此时nonce值已经存在于交易中,并且已经被签名。

    这种模式下,需要在业务系统中维护nonce的自增序列,适用一个nonce之后,在业务系统中对nonce进行加一处理。

    此种方案也有限制条件。第一,由于nonce统一进行维护,那么这个地址必须是内部地址,而且发起交易必须通过统一维护的nonce作为出口,否则在其他地方发起交易,原有维护的nonce将会出现混乱。第二,一旦已经发出的交易发生异常,异常交易的nonce未被使用,那么异常交易的nonce需要重新被使用之后它后面的nonce才会生效。

    总结一下:

    1、以太坊中有两种nonce,一种是在区块中的nonce,主要是调整挖矿难度;一种是每笔交易中nonce。
    2、每个外部账户(私钥控制的账户)都有一个nonce值,从0开始连续累加,每累加一次,代表一笔交易。
    3、某一地址的某一交易的nonce值如果大于当前的nonce,该交易会被放到交易池的queued列表中,直到缺失的nonce被提交到交易池中。
    4、地址的nonce值是一个连续的整数,设计的主要目的是防止双花。
    5、在发生一笔交易时,如果不指定nonce值时,节点会根据当前交易池的交易自动计算该笔交易的nonce。有可能会出现节点A和节点B计算的nonce值不一样的情况。
    6、当交易暂未上链时,可通过提高手续费的方式,覆盖同样nonce值的交易
    7、通常情况下,覆盖掉一笔处于pending状态的交易gas price需要高于原交易的110%。
     

  • 相关阅读:
    java计算机毕业设计重工教师职称管理系统源码+mysql数据库+系统+lw文档+部署
    Linux oracle 数据导出导入步骤:
    【C++】引用和指针
    CMake教程-第 3 步:添加库的使用要求
    R语言eventstudies
    Amazon Lambda 转 Container Image 方式部署
    Android 9.0 蓝牙功能之一:蓝牙设置
    Java(类和对象笔记)
    牛亚男:基于多Domain多任务学习框架和Transformer,搭建快精排模型
    Java版工程行业管理系统源码-专业的工程管理软件- 工程项目各模块及其功能点清单
  • 原文地址:https://blog.csdn.net/music0ant/article/details/133587534