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

EOS 如何设置付款人

nodeos v2.2 发布后,可以使用资源支付者功能来赞助交易的资源。要设置一个事务相关的资源单独付款人,一个添加resource_payer对象到您的交易指定payer,max_net_bytes,max_cpu_us,和max_memory_bytes。此功能需要RESOURCE_PAYER在链上启用协议功能。

此功能的典型用例是服务或应用程序为交易的资源而不是其用户付费。由于交易中的用户和付款人都需要授权,因此可能的工作流程是交易由用户的钱包应用程序签名,然后在发送到 nodeos 之前也由服务/应用程序签名。

{
    resource_payer: {
        payer: 'alice',
        max_net_bytes: 4096,
        max_cpu_us: 400,
        max_memory_bytes: 0
    },
    actions: [{
        account: 'eosio.token',
        name: 'transfer',
        authorization: [{
            actor: 'bob',
            permission: 'active',
        }, {
            actor: 'alice',
            permission: 'active',
        }],
        data: {
            from: 'bob',
            to: 'alice',
            quantity: '0.0001 SYS',
            memo: 'resource payer',
        },
    }]
}

使用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