您正在查看: EOS-新手教程 分类下的文章

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) // 直接获取返回值

符合标准的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

EOS 根据链Mongo数据判断交易状态

根据几个测试交易对比

  1. 正常发起普通交易(余额充足,非延迟)
  2. 正常发起延迟交易(余额充足,延迟)
  3. 正常发起延迟交易,交易到期前,将转出账户的余额转空(余额不足,延迟)

对比链Mongo表transactionstransaction_traces

对于transactions体现了交易所在块是否不可逆irreversible,而transaction_traces

 "receipt" : {
        "status" : "hard_fail",
        ...
    },

status状态来判断交易状态。
对于交易对比的1和2对于数据来说只是delay_sec数量问题,并且交易到期前,数据库中无法查到延迟交易。
1或2与3进行比较,transactions无关键差别,transaction_tracesstatus状态存在差别。

清洗数据

为了方便数据的使用,最好还是需要单独新洗出一个交易状态表,此表中关键包含,

  1. 交易id
  2. 所在块号
  3. 交易状态
  4. 是否不可逆

测试数据如下

库名:trx_status

{
    "_id" : ObjectId("5fbb8ef5349bfe65ef744506"),
    "trx_id" : "c1811e16a77288e3f374faf2eb2b0308d2f480b3414a07357d6e45cf29ffe56e",
    "block_num" : 11414152,
    "status" : 0,
    "irreversible" : true,
    "block_time" : ISODate("2020-11-23T10:29:10.000Z"),
    "block_timestamp" : NumberLong(1606127350000),
    "createdAt" : ISODate("2020-11-23T10:29:09.952Z"),
    "updatedAt" : ISODate("2020-11-23T10:31:05.985Z"),
    "block_id" : "00ae2a8818a6bd8cd33e9873419ac7258813ea9578dde95c8e0771397351b952"
}

交易等待不可逆

status==0 && irreversible == fasle

交易丢失(丢块)

status==0 && irreversible == fasle && ((current_time - block_time) >((head_block_num - last_irreversible_block_num) * 0.5 + 容差值))
// current_time - block_time 为当前时间与交易创建时间的秒数
// 容差值是为了避免误判,通常为 1-2分钟即可

交易失败

status!=0

因为交易到执行时间前,数据库中没有插入数据,所以没有delayed事件

当交易不可逆

status==0 && irreversible == true

备注

status的状态

status_enum {
    // 这个表示执行成功(所以不需要执行出错逻辑)
    executed  = 0,
    // 客观的来说,执行失败了(或者没有执行),某一个出错逻辑执行了
    soft_fail = 1,
    // 执行失败了,并且执行的出错逻辑也失败了,所以并没有状态改变
    hard_fail = 2,
    // 交易被延迟了,计划到未来的某个时间执行
    delayed   = 3,
    // 交易过期了,并且存储空间返还给用户
    expired   = 4  ///< transaction expired and storage space refuned to user
};

修改配置

config.ini配置中,去掉onblock交易,较少垃圾数据

mongodb-filter-out = eosio:onblock:

参考

https://www.bcskill.com/index.php/archives/621.html

EOS js name To Uint64 OR Uint64 to name

源代码仓库地址:
https://github.com/bcskill/eosjs-name

演示地址
Try on run-kit https://npm.runkit.com/eosjs-account-name

测试代码
// name To Uint64

const eosjsAccountName = require("eosjs-account-name")
const n = eosjsAccountName.nameToUint64('eosio');
console.log('eosio to uint64: ' + n);
console.log('uint64 to name: ' + eosjsAccountName.uint64ToName(n));

// Uint64 to name

const uint64 = '6138663577826885632';
const name = eosjsAccountName.uint64ToName(uint64);

基于Bancor 算法两种资源互换的算法讲解

场景

BCS Token 购买 FF 资源

算法文字描述

FF Bancor 算法过程中,并不是将 BCS 和 FF 直接用价格曲线进行兑换,而是引入了中间 token——FFCORE,对应于 Bancor 中的 Smart Token。

BCS 到 FF 的兑换过程就涉及了两个公式,所以上文中用一个公式来举例就很不严谨,只是为了定性的说明价格特性。

从代码中可看到BCS与FFCORE的兑换公式为:

其中,E为BCS到FFCORE所能兑换的数量,R是FFCORE的初始发行总量,C1为当前BCS余量,T1为用于购买的FF数量,F为常量参数

将上述公式的进行反向整理设计,即可得到FFCORE与交易额的兑换公式为:

其中,T2是准备购入的FF数量;C2为可分配的FF余量。将中间变量E代入即可得出用于购买的BCS数量(T1)与可兑换到的FF数量(T2)之间的关系。

为方便直观的理解,可以对公式进行简化,得到:

可以看到随着可买FF余量(C2)的降低或者BCS数量(C1)的增多,FF的价格会加速增长(即同样付出T1的BCS下,可换取到的FF数量T2变少了)