您正在查看: EOS 分类下的文章

使用eosio-java计算transaction_id

开源地址:https://github.com/EOSIO/eosio-java

计算方法

Hex.toHexString(Sha256Hash.hash(Hex.decode(processor.getSerializedTransaction())));

参考:https://github.com/EOSIO/eosio-java/issues/96

EOS链的RAM资源扩增

背景

某个基于EOS开发的链,提供了免费的账户注册接口,执行调用后,空投账户免费为其抵押CPU NET和购买RAM。由于接口没有做严格有效的防刷处理,导致账户注册严重超过预期,导致链内系统资源浪费严重,以及空投部分系统代币占用过多

逻辑处理

  1. 增加注册接口的防范级别,比如增加IP注册次数,相同公钥,App机器码统计。三方有效的验证码验证,App内核心校验参数加密,增加对方破解成本。
  2. 对于已经刷入的账户做筛选,以及资源回收,比如,注册多长时间内从未使用
  3. 增加付费和邀请注册逻辑。提供与EOS目前主流钱包一样的逻辑,由三方账户进行代为抵押购买,或者直接RMB支付
  4. 由项目方提供投抵押的系统代币。提供空投服务程序给项目方,项目方账户持续为自己项目内账户补充所需的空投代币,服务程序也可以支持邀请码注册,项目方生成邀请码赠送或者出售给自己的用户

链处理

  1. 一次性扩增RAM容量。(eosio->setram)

    void system_contract::setram( uint64_t max_ram_size ) {
       require_auth( get_self() );
    
       check( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues
       check( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" );
       check( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" );
    
       auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size);
       auto itr = _rammarket.find(ramcore_symbol.raw());
    
       /**
        *  Increase the amount of ram for sale based upon the change in max ram size.
        */
       _rammarket.modify( itr, same_payer, [&]( auto& m ) {
          m.base.balance.amount += delta;
       });
    
       _gstate.max_ram_size = max_ram_size;
    }
  2. 每块持续新增。(eosio->setramrate)
    设置完每块新增量后

    void system_contract::setramrate( uint16_t bytes_per_block ) {
       require_auth( get_self() );
    
       update_ram_supply();
       _gstate2.new_ram_per_block = bytes_per_block;
    }

    当下次有购买内存的操作时,执行时间差内的容量扩增

    void system_contract::buyram( const name& payer, const name& receiver, const asset& quant )
    {
       require_auth( payer );
       update_ram_supply();

参考

https://github.com/EOSIO/eosio.contracts/blob/d7bc0a5cc8c0c2edd4dc61b0126517d0cb46fd94/contracts/eosio.system/src/eosio.system.cpp#L67

https://github.com/EOSIO/eosio.contracts/blob/d7bc0a5cc8c0c2edd4dc61b0126517d0cb46fd94/contracts/eosio.system/src/eosio.system.cpp#L105

https://github.com/EOSIO/eosio.contracts/blob/d7bc0a5cc8c0c2edd4dc61b0126517d0cb46fd94/contracts/eosio.system/src/delegate_bandwidth.cpp#L46

https://developers.eos.io/manuals/eosio.contracts/latest/key-concepts/ram

eos 链改 2.0.x 升级2.1.x的修改点

  1. eosio::name 声明变量的N() 取消了,统一用 ""_n
  2. fc::optional替换成 std::optional
  3. t->packed_trx()->get_signed_transaction() 改成v0 获取,修改为
    t->packed_trx()->to_packed_transaction_v0()->get_signed_transaction()
  4. mongo_db_plugin 相关被删除,包括mongo异常信息类型
  5. bs->block->id(); 使用V0
    bs->block->to_signed_block_v0()->id();

持续总结

dfuse-eosio 常用GraphQL API接口整理

测试例子

https://github.com/dfuse-io/docs/tree/master/quickstarts

@ dfuse/client使用例子

global.fetch = require('node-fetch');
global.WebSocket = require('ws');

// CODE:BEGIN:quickstarts_javascript_node_eos_section1
const { createDfuseClient } = require('@dfuse/client');

const client = createDfuseClient({
  network: '39.106.103.152:8080',
  authentication: false,
  secure: false,
});
// CODE:END:quickstarts_javascript_node_eos_section1
// CODE:BEGIN:quickstarts_javascript_node_eos_section2
// You must use a `$cursor` variable so stream starts back at last marked cursor on reconnect!
const operation = `subscription($cursor: String!) {
  searchTransactionsForward(query:"receiver:eosio.token action:transfer -data.quantity:'0.0001 EOS'", cursor: $cursor) {
    undo cursor
    trace { id matchingActions { json } }
  }
}`;
// CODE:END:quickstarts_javascript_node_eos_section2
// CODE:BEGIN:quickstarts_javascript_node_eos_section3
async function main() {
  const stream = await client.graphql(operation, message => {
    if (message.type === 'data') {
      const {
        undo,
        cursor,
        trace: { id, matchingActions }
      } = message.data.searchTransactionsForward;
      matchingActions.forEach(({ json: { from, to, quantity } }) => {
        console.log(
          `Transfer ${from} -> ${to} [${quantity}]${undo ? ' REVERTED' : ''}`
        );
      });

      // Mark stream at cursor location, on re-connect, we will start back at cursor
      stream.mark({ cursor });
    }

    if (message.type === 'error') {
      console.log('An error occurred', message.errors, message.terminal);
    }

    if (message.type === 'complete') {
      console.log('Completed');
    }
  });

  // Waits until the stream completes, or forever
  await stream.join();
  await client.release();
}
// CODE:END:quickstarts_javascript_node_eos_section3
// CODE:BEGIN:quickstarts_javascript_node_eos_section4
main().catch(error => console.log('Unexpected error', error));
// CODE:END:quickstarts_javascript_node_eos_section4

接口文档

https://docs.dfuse.io/eosio/public-apis/reference/graphql-api/

常用接口整理

稍后补充

GraphQL 与 REST 相比的优势和短板

https://zhuanlan.zhihu.com/p/95521039

dfuse/client 如何配置访问权限

如何在我自己构建和运行的@dfuse/client中配置apiKey
由于dfuse官方权限这块并没有开源,可以先把权限相关关闭
可以只用测试例子演示

const client = createDfuseClient({
  network: '39.106.103.152:8080',
  authentication: false,
  secure: false,
});

参考

https://github.com/dfuse-io/dfuse-eosio/issues/206

https://github.com/dfuse-io/client-js/blob/e86735957d348ced88f141720979dec8516db5ef/examples/basic/dfuse-for-eosio.ts#L13