您正在查看: Surou 发布的文章

get_table对于time_point类型得定位查询

根据场景需求需要对已存储得数据做更新查询,所以需要对update_timepoint做查询索引

struct [[eosio::table, eosio::contract("bcskill.com")]] xxxx_info {
        uint64_t id;                                        // 记录id
        eosio::checksum256 trx_id;                          // 交易id
        ....
        time_point create_timepoint;                        // 创建时间
        time_point update_timepoint;                        // 更新时间

        uint64_t primary_key() const { return id; }
        eosio::checksum256 second_key() const { return trx_id; }
        uint64_t third_key() const { return update_timepoint.time_since_epoch().count();} // 把time_point类型转换成微妙(1/1000000 秒)
    };

table中测试数据如下

{
  "rows": [{
      "id": 0,
      "trx_id": "d78c4da408a4d9c75ba03af4a481d79fa80e2b8e215e68a1fe1865fd866cc7bc",
      ...
      "create_timepoint": "2020-12-17T11:24:07.500",
      "update_timepoint": "2020-12-17T11:27:18.500"
    },{
      "id": 1,
      "trx_id": "7bb0038be49b171f8a394bfdd7da15f9a005908b25ca1b6aed31b2975d721730",
      ...
      "create_timepoint": "2020-12-17T11:29:01.500",
      "update_timepoint": "2020-12-17T11:30:01.500"
    },{
      "id": 2,
      "trx_id": "8cf1c32d38692dd93870c7a2376d617f85efa4f093588dbce94f9981d4e1818e",
      ...
      "create_timepoint": "2020-12-17T11:30:01.500",
      "update_timepoint": "2020-12-17T11:30:01.500"
    }
  ],
  "more": false
}

UTC时间转时间戳,目前没有找到现成的工具可以直接转换,
https://tool.lu/timestamp/ 只找到这个北京时间转时间戳的工具(稍后找到其他直接工具,或者单独开发个工具再做文章更新)

UTC 转北京时间(+8)

暂时先将UTC时间加8小时转换成本地时间,测试的UTC时间为2020-12-17T11:27:18.500,转换为本地时间为2020-12-17 19:27:18 其中的.500为0.5秒,后面再单独加上。

北京时间转时间戳

利用上面的在线工具2020-12-17 19:27:18得到1608204438,加上上面的0.500得到1608204438.5

根据合约类型需要转换为微妙

1608204438.5 * 1000000 得到 1608204438500000

根据测试数据演示下查询

cleos get table bcskillsurou bcskillsurou ammtb --index 3 --key-type i64 -L 1608204438500000 -U 1608204438500000

得到指定的记录

{
  "rows": [{
      "id": 0,
      "trx_id": "d78c4da408a4d9c75ba03af4a481d79fa80e2b8e215e68a1fe1865fd866cc7bc",
      ...
      "create_timepoint": "2020-12-17T11:24:07.500",
      "update_timepoint": "2020-12-17T11:27:18.500"
    }
  ],
  "more": false
}

EOSIO v2.1.0 动作返回值

昨晚期待已久的2.1.0 rc 版本终于发版了,
https://github.com/EOSIO/eos/releases/tag/v2.1.0-rc1
新的协议功能:ACTION_RETURN_VALUE。
https://github.com/EOSIO/eos/pull/8327
激活后,此功能提供了一种方法,该方法可以将返回的值在操作中的块头中严格落实到外部进程中,而不必依赖get_table或通过print语句使用调试控制台。这使智能合约开发人员能够直接处理操作的返回值。进一步简化智能合约开发流程。一个例子可以在这里看到。

演示例子

合约代码

[[eosio::action]]
int sum(int valueA, int valueB) {
    return valueA + valueB; // 合约返回结果
}

前端推送完交易后,直接获取返回值

 const transactionResult = await api.transact({
        actions: [{
          account: 'returnvalue',
          name: 'sum',
          authorization: [{
            actor: 'returnvalue',
            permission: 'active',
          }],
          data: {
            valueA: numbers.first,
            valueB: numbers.second
          }
        }]
      }, {
        blocksBehind: 3,
        expireSeconds: 30
      }) as any
      setResult(transactionResult.processed.action_traces[0].return_value_data) // 直接获取返回值

ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?

sudo gpasswd -a ${USER} docker
sudo su
su 当前账户
docker-compose up -d

EOS 合约 hex 字符串与checksum256互转

hex to checksum256

eosio::checksum256 hex_to_checksum256(const std::string& in) {
    eosio::check(in.length() == 64, "checksum size is error");
    std::string hex{"0123456789abcdef"};
    eosio::checksum256 out;
    for (int i = 0; i < 32; i++) {
      auto d1 = hex.find(in[2 * i]);
      auto d2 = hex.find(in[2 * i + 1]);
      eosio::check(d1 != std::string::npos || d2 != std::string::npos,
                  "invalid sha256");

      // checksum256 is composed of little endian int128_t
      reinterpret_cast<char*>(out.data())[i / 16 * 16 + 15 - (i % 16)] =
          (d1 << 4) + d2;
    }
    return out;
}

checksum256 to hex string

static string to_hex(const checksum256 &hashed) {
    // Construct variables
    string result;
    const char *hex_chars = "0123456789abcdef";
    const auto bytes = hashed.extract_as_byte_array();
    // Iterate hash and build result
    for (uint32_t i = 0; i < bytes.size(); ++i) {
        (result += hex_chars[(bytes.at(i) >> 4)]) += hex_chars[(bytes.at(i) & 0x0f)];
    }
    // Return string
    return result;
}

参考

https://github.com/EOSIO/eos/issues/4012

符合标准的EOS助记词生成私钥

最近要对接HD钱包,测试得到EOS的
eosjs-ecc 不符合标准的BIP44

m/44'/194'/0'/0/0

修正方法为

const hdkey = require('hdkey')
const wif = require('wif')
const ecc = require('eosjs-ecc')
const bip39 = require('bip39')
const mnemonic = 'real flame win provide layer trigger soda erode upset rate beef wrist fame design merit'
const seed = bip39.mnemonicToSeedSync(mnemonic)
const master = hdkey.fromMasterSeed(Buffer(seed, 'hex'))
const node = master.derive("m/44'/194'/0'/0/0")
console.log("publicKey: "+ecc.PublicKey(node._publicKey).toString())
console.log("privateKey: "+wif.encode(128, node._privateKey, false))

根据测试例子,修改eosjs-ecc支持扩展方法

package.json 增加新依赖

npm i bip39
npm i hdkey
npm i wif

修改api_common.js 增加bip44参数

默认false兼容之前版本

seedPrivate: (seed, bip44 = false) => PrivateKey.fromSeed(seed, bip44).toString(),

修改 key_private.js

增加新依赖

const hdkey = require('hdkey')
const WIFReturn = require('wif')
const bip39 = require('bip39')

修改fromSeed支持新实现

PrivateKey.fromSeed = function(seed, bip44) { // generate_private_key
    if (!(typeof seed === 'string')) {
        throw new Error('seed must be of type string');
    }
    if(bip44) {
      const seedString = bip39.mnemonicToSeedSync(seed)
      const master = hdkey.fromMasterSeed(Buffer(seedString, 'hex'))
      const node = master.derive("m/44'/194'/0'/0/0")
      return WIFReturn.encode(128, node._privateKey, false)
    }
    return PrivateKey.fromBuffer(hash.sha256(seed));
}

测试

测试助记词

real flame win provide layer trigger soda erode upset rate beef wrist fame design merit

原版eosjs-ecc

<script src="./dist-web/eosjs-ecc.js"></script>
    <script>
   (async () => {
    let wif = eosjs_ecc.seedPrivate('real flame win provide layer trigger soda erode upset rate beef wrist fame design merit');
    console.log(wif + '\n');
    let pubKey = eosjs_ecc.privateToPublic(wif);
    console.log(pubKey + '\n');
   })();
  </script>

生成结果为

5JX94izH6NMZkGqq9VvrmSTWux28HKRyns5mBwujzB9p48XSgNQ
EOS6j4E5ksFkDBAP32XXYseTaUkGqBKqPzYjcwUVeBV4JY8UbS1N5

使用修改后得标准BIP44

<script src="./dist-web/eosjs-ecc.js"></script>
    <script>
   (async () => {
    let wif = eosjs_ecc.seedPrivate('real flame win provide layer trigger soda erode upset rate beef wrist fame design merit',true);
    console.log(wif + '\n');
    let pubKey = eosjs_ecc.privateToPublic(wif);
    console.log(pubKey + '\n');
   })();
  </script>

结果为

5KX4T16FtxG9LvRJukA31TP9BKq3jYve3xQ3Px3ui8mzuJ7nUYE
EOS61oRAVkx1rqPM8mEsBZxPAFAa9Nm6kLa7mQs6mRKTsRTFQaad7

参考

https://github.com/satoshilabs/slips/blob/master/slip-0044.md
https://iancoleman.io/bip39/

备注

eosjs编译时需要先

npm run build

不能直接

npm run build_browser

如果测试自定义得bip44中得 coin type,可以在https://iancoleman.io/bip39/ 中得Derivation Path 选项中,选择BIP32,并去掉最后一层,例如,自定义coin type为9527

m/44'/9527'/0'/0