BCSkill (Block chain skill )
区块链中文技术社区

只讨论区块链底层技术
遵守一切相关法律政策!

nodeos 启动参数--checkpoint 作用

问题

看nodeos的启动参数的时候,看到这么一项: --checkpoint arg Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints.
这checkpoint是什么,主要用来干嘛的?
问题来自:eosfans

解答

查看config中的注释
Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin)
多对区块高度+区块id,用来作为检查点。默认注释掉,不设置检查点

大概的意思就是,接收区块时,根据区段的高度,查看当前区块的id与预期的一样不一样,防止数据出错。

撸一遍代码
eos\plugins\chain_plugin\chain_plugin.cpp

if( options.count("checkpoint") ) {
         auto cps = options.at("checkpoint").as<vector<string>>();
         my->loaded_checkpoints.reserve(cps.size());
         for( const auto& cp : cps ) {
            auto item = fc::json::from_string(cp).as<std::pair<uint32_t,block_id_type>>();
            auto itr = my->loaded_checkpoints.find(item.first);
            if( itr != my->loaded_checkpoints.end() ) {
               EOS_ASSERT( itr->second == item.second,
                           plugin_config_exception,
                          "redefining existing checkpoint at block number ${num}: original: ${orig} new: ${new}",
                          ("num", item.first)("orig", itr->second)("new", item.second)
               );
            } else {
               my->loaded_checkpoints[item.first] = item.second;
            }
         }
      }

先将config中配置的,或者命令行传入的,多对区块高度+区块id存入my->loaded_checkpoints,并去重。

接收区块时,进行对比验证

// relay signals to channels
      my->pre_accepted_block_connection = my->chain->pre_accepted_block.connect([this](const signed_block_ptr& blk) {
         auto itr = my->loaded_checkpoints.find( blk->block_num() );
         if( itr != my->loaded_checkpoints.end() ) {
            auto id = blk->id();
            EOS_ASSERT( itr->second == id, checkpoint_exception,
                        "Checkpoint does not match for block number ${num}: expected: ${expected} actual: ${actual}",
                        ("num", blk->block_num())("expected", itr->second)("actual", id)
            );
         }

         my->pre_accepted_block_channel.publish(blk);
      });

当接收的区块的高度与预定中的某高度一致,比较当前区块id与预定的id,如果不一致,则报错Checkpoint does not match for block number...

Error 3200006: invalid http request (please contact the RPC server administrator for 127.0.0.1!)

  • 执行cleos get transaction出现以下错误

    root@iZj6cbx3duprxf6dasczbpZ:~/eosio-wallet# cleos get transaction 17b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a72
    Error 3200006: invalid http request
    Error Details:
    The server has rejected the request as invalid!
    Please verify this url is valid: http://127.0.0.1:8888/v1/history/get_transaction
    If the condition persists, please contact the RPC server administrator for 127.0.0.1!
  • 换在eosjs下执行

      const wif = '私钥'
      eos = Eos({
              httpEndpoint: '上面cleos所在服务器提供的Rpc地址',
              chainId: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
              keyProvider: wif,
              verbose: true
            })
      eos.getTransaction("17b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a72").then(result => {
          console.log(result);
      })
  • 返回结果如下

    {
      "code": 400, 
      "message": "Bad Request", 
      "error": {
          "code": 3040011, 
          "name": "tx_not_found", 
          "what": "The transaction can not be found", 
          "details": [
              {
                  "message": "Transaction 17b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a72 not found in history and no block hint was given", 
                  "file": "history_plugin.cpp", 
                  "line_number": 396, 
                  "method": "get_transaction"
              }
          ]
      }
    }

    这个17b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a72并不存在。

  • 在eosjs中执行

    eos.getActions("bcskillsurou").then(result => {
      console.log(result);
    })
  • 再返回的数据中

    {"actions":[{"global_action_seq":2569366,"account_action_seq":304,"block_num":2568738,"block_time":"2018-08-02T10:32:46.500","action_trace":{"receipt":{"receiver":"dapp.exec","act_digest":"b6902e4919fe2e03e5be0bd8dd01659a5e6dca58fc4d6c9e873de56c54f75a36","global_sequence":2569366,"recv_sequence":101,"auth_sequence":[["dapp.exec",288]],"code_sequence":1,"abi_sequence":1},"act":{"account":"eosio.token","name":"transfer","authorization":[{"actor":"dapp.exec","permission":"active"}],"data":{"from":"dapp.exec","to":"eosio.ram","quantity":"0.9950 EOS","memo":"buy ram"},"hex_data":"000040aa2b50ab49000090e602ea3055de2600000000000004454f5300000000076275792072616d"},"elapsed":62,"cpu_usage":0,"console":"","total_cpu_usage":0,"trx_id":"c7b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a7d","inline_traces":[]}},
  • 随便找一个trx_id

    "trx_id":"c7b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a7d"
  • 然后在终端执行

    root@iZj6cbx3duprxf6dasczbpZ:~/eosio-wallet# cleos get transaction c7b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a7d
    {
    "id": "c7b8e633dbdc3988fcec671b96ae1ce473bc432568a417a416901b9c01184a7d",
    "trx": {
      "receipt": {
        "status": "executed",
        "cpu_usage_us": 3077,
        "net_usage_words": 16,
        "trx": [
          1,{
            "signatures": [
              "SIG_K1_KbeYYa3kW3izWvmHoRjUSCSSckGWzwuRi3ZJ8pPKnjJigGsUSE3aRKnmZDNhgULCou7aYTgyYeTs95f9RMKik7LTMPHX3p"
            ],
            "compression": "none",
            "packed_context_free_data": "",
            "packed_trx": "08de625bf43153f4344400000000010000000000ea3055000000004873bd3e01000040aa2b50ab4900000000a8ed323220000040aa2b50ab49000040aa2b50ab49102700000000000004454f530000000000"
          }
        ]
      },
      "trx": {

    正确返回交易信息。

结论

至此得出结论,在终端中cleos get transaction 本地数据不存在的trx_id,出现Error 3200006 错误,
此错误信息并不准确,建议EOSIO能和eosjs返回的错误一致,方便分析问题。

EOS修改非owner私钥

本文只为简单的描述下当非owner私钥丢失后,如何重置

一般利用三方App创建账号,为了程序内好处理,并且减少用户的记录成本,都是owner和active共用一对公钥和私钥,这种只能第一时间赶紧将剩余的EOS转走,减少损失。并第一时间找社区提交仲裁。
所以建议用一些支持owner和active 单独设置公钥私钥的程序创建账号(在此不做推荐,避免不必要的风险)。在不需要owner的情况下,单独冷备份,平时只用active权限的账号进行操作。

下面开始演示,如何更换active私钥

查询账户
root@iZj6c1ho98e6b4nz3ulirvZ:~# cleos -u https://api.eosnewyork.io get account bcskillsurou

permissions: 
     owner     1:    1 EOS8Sq9MXKiop4J1PX3xfyDkzqaRpWp2tEqkBL4LiT3cvXmtc2yh4
     active     1:    1 EOS72Uoinz7Dgm4GpdhfoPUQx6NfosoyacvLsk7z2E9Y7z5DBsKjv
提前已创建好一对新的公钥私钥
5J4MbkkZHtroTW3FZQa3cEZFFr9EFPDm75yPFTuuS2B
EOS6zxf2t9qkgYYpjNWXy91edeVFjeWmaH7JQeQAn9SRiRefqMQ6W
开始更换active 公钥
root@iZj6c1ho98e6b4nz3ulirvZ:~# cleos -u https://api.eosnewyork.io set account permission bcskillsurou active '{"threshold": 1, "keys": [{"key": "EOS6zxf2t9qkgYYpjNWXy91edeVFjeWmaH7JQeQAn9SRiRefqMQ6W", "weight": 1}], "accounts": []}' active
Error 3050000: Action validate exception
Error Details:
Cannot set an authority as its own parent
pending console output:
需要active的父级权限
cleos wallet import
输入 EOS8Sq9MXKiop4J1PX3xfyDkzqaRpWp2tEqkBL4LiT3cvXmtc2yh4 的私钥
更换owner 权限,重新执行
root@iZj6c1ho98e6b4nz3ulirvZ:~# cleos -u https://api.eosnewyork.io set account permission bcskillsurou active '{"threshold": 1, "keys": [{"key": "EOS6zxf2t9qkgYYpjNWXy91edeVFjeWmaH7JQeQAn9SRiRefqMQ6W", "weight": 1}], "accounts": []}' owner
executed transaction: 31a9bf9448b3d9882f27767c427a6ece406319036b3d62e7a04d001f272365a2  160 bytes  1254 us
#         eosio <= eosio::updateauth            {"account":"bcskillsurou","permission":"active","parent":"owner","auth":{"threshold":1,"keys":[{"key...
再次查看账户
root@iZj6c1ho98e6b4nz3ulirvZ:~# cleos -u https://api.eosnewyork.io get account bcskillsurou

permissions: 
     owner     1:    1 EOS8Sq9MXKiop4J1PX3xfyDkzqaRpWp2tEqkBL4LiT3cvXmtc2yh4
     active     1:    1 EOS6zxf2t9qkgYYpjNWXy91edeVFjeWmaH7JQeQAn9SRiRefqMQ6W

active权限已更改

参考

EOS账户权限介绍以及增删改查

EOS 主网数据更新,离线数据包

数据下载地址

使用方法

下载最新的数据包

wget https://s3-ap-northeast-1.amazonaws.com/eosstorebp/xxx.tar.gz

解压下载好的数据包

tar -zxvf xxx.tar.gz

解压后会发现数据包中有两个文件blocks,state
将两个文件夹,放到~/.local/share/eosio/nodeos/data,(提前清空目录)
或者自定义data的位置,nodeos启动时添加参数--data-dir 自定义的data目录路径 (注意每次重新启动nodeos,都需要加此参数)
重新启动 nodeos
eosstore提供

RPC获取常见资源数据

实例化EOS对象

const wif = '私钥'
eos = Eos({
        httpEndpoint: 'https://api.eosnewyork.io',
        chainId: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
        keyProvider: wif,
        verbose: true
    })

RAM

  • 获取总网RAM (GB)

    eos.getTableRows(true,"eosio","eosio","global",10).then(result => {
      console.log(result.rows[0].max_ram_size/(1024*1024*1024));
    })
  • 获取RAM当前价格
    参考(获取RAM实时价格)

  • 获取总网RAM使用量

    eos.getTableRows(true,"eosio", "eosio", "rammarket").then(result => {
      var ramBaseBalance = result.rows[0].base.balance; // Amount of RAM bytes in use
      ramBaseBalance = ramBaseBalance.substr(0,ramBaseBalance.indexOf(' '));
      console.log(ramBaseBalance);
    })
  • 获取总网已购买RAM的EOS总数

    eos.getTableRows(true,"eosio", "eosio", "rammarket").then(result => {
      var ramQuoteBalance = result.rows[0].quote.balance; // Amount of EOS in the RAM collector
      ramQuoteBalance = ramQuoteBalance.substr(0,ramQuoteBalance.indexOf(' '));
      console.log(ramQuoteBalance);
    })

NET

  • 获取当前NET价格(EOS/KiB/Day)
    eos.getAccount("eosnewyorkio").then(result => {
      var netStaked = result.total_resources.net_weight.substr(0,result.total_resources.net_weight.indexOf(' '));
      var netAvailable = result.net_limit.max / 1024; //~ convert bytes to kilobytes
      netPriceEos = ((netStaked / netAvailable)/3).toFixed(8); //~ divide by 3 to get average per day from 3 day avg
      console.log(netPriceEos);
    })

CPU

  • 获取当前CPU价格(EOS/ms/Day)
    eos.getAccount("eosnewyorkio").then(result => {
      var cpuStaked = result.total_resources.cpu_weight.substr(0,result.total_resources.cpu_weight.indexOf(' '));
      var cpuAvailable = result.cpu_limit.max / 1000; // convert microseconds to milliseconds
      cpuPriceEos = ((cpuStaked / cpuAvailable)/3).toFixed(8); //~ divide by 3 to get average per day from 3 day avg
      console.log(cpuPriceEos);
    })

    科普

    什么是RAM?

    RAM需要在区块链上存储数据,必须购买。 您可以根据当前的RAM市场价格获得一定数量的存储字节数。 价格会根据买卖行为自动调整。 当您释放存储空间时,您可以以当前的市场价格出售RAM以恢复EOS。

    什么是网络带宽?

    网络带宽的测量值是过去3天内的平均消耗量(以字节为单位)。 每次发送操作或事务时都会暂时消耗净带宽,但会随着时间的推移而减少返回0.净带宽所占用的令牌越多,您使用的越多。 您可以随时取消收回您的EOS令牌。

    什么是CPU带宽?

    CPU带宽测量为过去3天内的平均消耗量(以微秒为单位)。 发送操作或事务时临时消耗CPU带宽,但随着时间的推移逐渐减少,返回0.事务运行的时间越长,消耗的CPU带宽就越多。 您可以随时取消收回您的EOS令牌。

数据来自:github erp