如何检查当前的 EOS 是什么版本?

访问 http://127.0.0.1:8888/v1/chain/get_info

或者通过命令:
curl http://127.0.0.1:8888/v1/chain/get_info

或者:
./cleos -u http://127.0.0.1:8888 get info

获取到 chain basic info
Screen Shot 2018-09-29 at 17.51.18

找到
"server_version": "ef654aa3"

取前7位:ef654aa

然后到 https://github.com/EOSIO/eos/releases 搜索这个字符

Screen Shot 2018-09-29 at 17.47.49

即可找到当前的版本为 v1.0.9

像素游戏的开源代码(一)

竟然一天就投入了 10万柚子,比预料厉害很多,上周日投入5个EOS,现在已经有将近10个EOS的收入了。

网址:https://pixelmaster.io/

开源代码在此,开个系列来分析一下这个游戏的代码:
https://github.com/eosasia/eospixels

首先作为开篇,先了解下它的经济模型和发展历程。

经济模型
Screen Shot 2018-09-25 at 16.13.44

发展史
pixelposte

作图过程的重放动画:

https://www.eosvenus.com/analytics/pixelmaster/

什么是 URI

什么是 URI?
A:Universal Resource Inheritance 全体资源继承
简单来说,只要你能证明你是现实世界活着的一个人,你就可以定期拿到URI发放的代币。是一种“人即挖矿”的模式。

什么是UBI,它和 URI 的关系是什么?
A:Universal Basic Income (UBI) 普遍基本收入,美国在上世纪60年代曾经尝试过一个举措:民主党与共和党团结一致,要从根本上改革社会的安全保障制度,并进行了测试。美国投入了数千万美元来测试无条件基本收入的效果。

为什么需要 URI?
A:假设每一天都是新的一天,每一代人都应该平等地分配到宇宙中未获得的自然资源。基于这个假设可以把URI理解为每个人都可以参与挖矿且效率相等的数字货币。
历史上,芬兰和美国都尝试过类似的实验。但中心化来操作,毕竟没有去中心化来得好。比如很多非洲的捐款就被层层盘剥,到普通人手里已经非常少。

URI 的资金从哪里来?
A:增发。

如何确定哪些人能够获得URI资金?
A:目前没有答案。

目前看 URI 可能存在的问题?
A:
1 需要建立身份验证系统,防止薅羊毛。
2 是否会因此削弱人工作的动力?不得而知。

综上所述,目前看 URI 是 BM 的一个理想,但目前看实施并无可能,所以对 EOS 更是没有什么直接的影响。

BM原文:https://medium.com/@bytemaster/universal-resource-inheritance-505e7ca4d048

什么是 WPS

写两篇最近 EOS 社区特别热的新词:WPS 和 URI。

先来说说 WPS

什么是 WPF?
A:Worker Proposal System (WPS) ,一套基于去中心提案和公投的系统,通过使用部分增发来支持必要的项目,从而提高EOS的整体效用。

为什么需要WPS?
A:EOS.IO有一些需要改进的地方,一些功能仍然缺失。然而,由于EOS去中心化的特性,对于单个社区开发人员来说,没有足够的激励来花费他们的时间为高效和可扩展的升级贡献补丁和升级,来确保EOS.IO紧跟社区不断变化的需求。

WPS 的资金从哪里来?
A:EOS每年4%的增发

如何确定哪些WPS 能过获得资金?
A:通过WPS 系统(正在开发)进行公投,预计 9月/ 10月会进行第一次公投。

谁可以提交项目提案并申请资金?
A:目前并没有限制

到哪里查看提案并投票?
A:
https://workerproposal.com/

目前还在开发中,最新代码可以查看 https://github.com/EOS-BP-Developers/wps-backend

大概是下面这样的设计
1_JUeNBe7ZUv-7dxFXkznIKQ

白皮书中是怎么描述WPS 的?
A:根据基于EOS.IO软件的区块链,token持有人可以考虑选择一些WP有益社区的设计… 实施WP的系统合约可能不会在2018年6月启动时到位,但资金机制会。积累资金的同时,让BP开始收到奖励。由于工人提案系统将在WASM中实现,所以以后添加不需分叉。

举例来说提案的内容可以是什么?
A:核心仲裁、帐户密钥恢复、基于IPFS的存储、提交工具、和一个正常运行的WPS系统。

目前看 WPS 可能存在的问题?
A:
– 大户会为个人利益投票。
– 每年4%的增发是否过高。
– 避免成为另一个低效的中心化组织。
– BP或Block.one(而不是WPS)应该为这些项目付费。

WPS telegram channel:https://t.me/eosio_wps

Medium:https://medium.com/wps-working-group-eos

CryptoKylin EOS Testnet

除了 Jungle testnet,目前还比较推荐的是 Kylin 麒麟测试网,其相关信息如下,供参考:

官网
https://www.cryptokylin.io/

代码
https://github.com/cryptokylin/CryptoKylin-Testnet

RPC 入口:
https://api.kylin.alohaeos.com
https://api-kylin.eoslaomao.com

chainID: 5fff1dae8dc8e2fc4d5b23b2c7665c97f9e9d8edf2b6485a86ba311c25639191

浏览器
http://tools.cryptokylin.io
https://kylin.bloks.io/
https://kylin.eosq.app/

在线钱包
https://kylin.bloks.io/wallet
https://eostoolkit.io/

什么是 Inline Action

默认的 Action 是有账户直接转账触发的,但是如果由智能合约交互转账导致触发后续的 Action (通常在另外一个智能合约中发生)则叫做 Inline Action

已 eosbet 为例子:

1 你给 eosbet 的合约地址(eosbetdice11)转账,其具体过程是你的钱包与 eosio.token 合约交互,发送 EOS 到 eosbetdice11 合约。
2 eosbetdice11 内会在相同的 transaction 内执行其自己定义的 Action

通过 get_blocks 命令,只能查询到第一个 eosio.token 合约转账 Action,而无法查到后续的 Inline Action。
不过通过 get_blocks 拿到 transactionid,然后通过 get_transaction 是可以查到 Inline Action 的数据的。

目前越来越多的区块链浏览器已经支持了 Inline Action 的查询,比如
https://eosq.app/tx/23a423b6c573bc4f5ca209162006ef84fee8fff189fd5830f773263c5675fb9d

Screen Shot 2018-09-25 at 17.03.02

关于 EOS 不可逆块

EOS 链的最新块和不可逆块之间,目前有 335 个块的差距,按照 EOS 每0.5秒出一个块,意味着他们的差距将近 167.5s,那么问题来了,一个交易进入了最新块,是否能够确认它已经成功?
本文来讨论下 EOS 不可逆块的概念到底指的是什么。

Screen Shot 2018-09-21 at 15.56.15

首先我们看 BFT 的确认机制

1_hmRTjiTdtuxonOGAWRDtCg

我们按目前 EOS 的 21 个节点来计算:

每个区块必须由 21 * (2/3 + 1) = 15 个节点确认;

每个节点连续生产12个区块再切换下一个记账人出块,就是 12 * 0.5s = 6s;

节点按确定的顺序记账;

每个节点出块前会等待上一次的块被至少 15 个节点在链上通过出块确认,也就是 90s;

基于BFT的逻辑分为 Pre Commitment 和 Commitment 阶段,各自需要 15 个节点确认,那么完成两个阶段需要 90 * 2 = 180s;

但 EOS 并没有用 BFT,而是用 DPOS + aBFT (异步BFT)

DPOS 机制其实已经能够保证在交易进入区块后 99.9% 的概率不可逆,而aBFT保证100%不可逆。
aBFT 大概意思是说可以提前完成其它节点的确认签名,而非等到这个节点出块才能完成签名,所以目前达到不可逆时间是小于 180s 的。

综合来说,当交易出现在一个区块中,并能够被区块浏览器查询到,那么99.9%这笔转账已经成功,剩下0.1%的概率需要等到不可逆块高度达到被打包区块高度是才能最终确认为100%不可逆。

更多细节可阅读 BM 写的文章:

https://medium.com/eosio/dpos-bft-pipelined-byzantine-fault-tolerance-8a0634a270ba

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

EOS 智能合约最佳安全开发指南

原文:https://github.com/slowmist/eos-smart-contract-security-best-practices

这篇文档旨在为 EOS 智能合约开发人员提供一些智能合约的安全准则已知漏洞分析。我们邀请社区对该文档提出修改或完善建议,欢迎各种合并请求(Pull Request)。若有相关的文章或博客的发表,也请将其加入到参考文献中。

目录

安全准则

EOS 处于早期阶段并且有很强的实验性质。因此,随着新的 bug 和安全漏洞被发现,新的功能不断被开发出来,其面临的安全威胁也是不断变化的。这篇文章对于开发人员编写安全的智能合约来说只是个开始。

开发智能合约需要一个全新的工程思维,它不同于我们以往项目的开发。因为它犯错的代价是巨大的,很难像中心化类型的软件那样,打上补丁就可以弥补损失。就像直接给硬件编程或金融服务类软件开发,相比于 Web 开发和移动开发都有更大的挑战。因此,仅仅防范已知的漏洞是不够的,还需要学习新的开发理念:

  • 对可能的错误有所准备。任何有意义的智能合约或多或少都存在错误,因此你的代码必须能够正确的处理出现的 bug 和漏洞。需始终保证以下规则:
    • 当智能合约出现错误时,停止合约
    • 管理账户的资金风险,如限制(转账)速率、最大(转账)额度
    • 有效的途径来进行 bug 修复和功能提升
  • 谨慎发布智能合约。 尽量在正式发布智能合约之前发现并修复可能的 bug。
    • 对智能合约进行彻底的测试,并在任何新的攻击手法被发现后及时的测试(包括已经发布的合约)
    • 从 alpha 版本在麒麟测试网(CryptoKylin-Testnet)上发布开始便邀请专业安全审计机构进行审计,并提供漏洞赏金计划(Bug Bounty)
    • 阶段性发布,每个阶段都提供足够的测试
  • 保持智能合约的简洁。复杂会增加出错的风险。
    • 确保智能合约逻辑简洁
    • 确保合约和函数模块化
    • 使用已经被广泛使用的合约或工具(比如,不要自己写一个随机数生成器)
    • 条件允许的话,清晰明了比性能更重要
    • 只在你系统的去中心化部分使用区块链
  • 保持更新。通过公开资源来确保获取到最新的安全进展。
    • 在任何新的漏洞被发现时检查你的智能合约
    • 尽可能快的将使用到的库或者工具更新到最新
    • 使用最新的安全技术
  • 清楚区块链的特性。尽管你先前所拥有的编程经验同样适用于智能合约开发,但这里仍然有些陷阱你需要留意:
    • require_recipient(account_name name) 可触发通知,调用name合约中的同名函数,官方文档

已知漏洞

数值溢出

在进行算术运算时,未进行边界检查可能导致数值上下溢,引起智能合约用户资产受损。

漏洞示例

存在缺陷的代码:batchTransfer 批量转账

typedef struct acnts {
    account_name name0;
    account_name name1;
    account_name name2;
    account_name name3;
} account_names;

void transfer(symbol_name symbol, account_name from, account_names to, uint64_t balance)
{
    require_auth(from);
    account fromaccount;

    require_recipient(from);
    require_recipient(to.name0);
    require_recipient(to.name1);
    require_recipient(to.name2);
    require_recipient(to.name3);

    eosio_assert(is_balance_within_range(balance), "invalid balance");
    eosio_assert(balance > 0, "must transfer positive balance");

    uint64_t amount = balance * 4; //乘法溢出

    int itr = db_find_i64(_self, symbol, N(table), from);
    eosio_assert(itr >= 0, "Sub-- wrong name");
    db_get_i64(itr, &fromaccount, (account));
    eosio_assert(fromaccount.balance >= amount, "overdrawn balance");

    sub_balance(symbol, from, amount);

    add_balance(symbol, to.name0, balance);
    add_balance(symbol, to.name1, balance);
    add_balance(symbol, to.name2, balance);
    add_balance(symbol, to.name3, balance);
}

防御方法

尽可能使用 asset 结构体进行运算,而不是把 balance 提取出来进行运算。

真实案例

权限校验

在进行相关操作时,应严格判断函数入参和实际调用者是否一致,使用require_auth进行校验。

漏洞示例

存在缺陷的代码:transfer 转账

void token::transfer( account_name from,
                      account_name to,
                      asset        quantity,
                      string       memo )
{
    eosio_assert( from != to, "cannot transfer to self" );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );

    require_recipient( from );
    require_recipient( to );

    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );

    auto payer = has_auth( to ) ? to : from;

    sub_balance( from, quantity );
    add_balance( to, quantity, payer );
}

防御方法

使用require_auth( from )校验资产转出账户与调用账户是否一致。

真实案例

暂无

apply 校验

在处理合约调用时,应确保每个 action 与 code 均满足关联要求。

漏洞示例

存在缺陷的代码:

// extend from EOSIO_ABI
#define EOSIO_ABI_EX( TYPE, MEMBERS ) \
extern "C" { \
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
      auto self = receiver; \
      if( action == N(onerror)) { \
         /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ \
         eosio_assert(code == N(eosio), "onerror action's are only valid from the \"eosio\" system account"); \
      } \
      if( code == self || code == N(eosio.token) || action == N(onerror) ) { \
         TYPE thiscontract( self ); \
         switch( action ) { \
            EOSIO_API( TYPE, MEMBERS ) \
         } \
         /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
      } \
   } \
}

EOSIO_ABI_EX(eosio::charity, (hi)(transfer))

防御方法

使用

if( ((code == self  && action != N(transfer) ) || (code == N(eosio.token) && action == N(transfer)) || action == N(onerror)) ) { }

绑定每个关键 action 与 code 是否满足要求,避免异常调用。

真实案例

参考文献

致谢

  • 麒麟工作组
  • eosiofans
  • 荆凯(EOS42)
  • 星魂
  • 岛娘
  • 赵余(EOSLaoMao)
  • 字符

在麦子钱包发布了一个叫【EOS子弹消息】的DAPP

WechatIMG6301

花了1小时基于麦子钱包的 API 做的一个 DAPP

DAPP介绍

把一段内容写在备注里面,通过一次转账发送给多个好友,每条消息通过给好友转 0.0001 EOS 完成。

为什么做这个DAPP?

之前看到不少机构在通过这种方式做推广,普通用户还没有比较好用的工具,所以就在麦子上做了一个。
另外这种方式挺“区块链”的,第一、相比短信推广它的费用更低;第二、它的收益方是接受消息的用户而非中间商。

对接麦子钱包的心得体会

简单研究了一下麦子钱包的API,发现可以基于现成开源的【小协议】代码做修改,前端都没自己写,还是很方便的。

主要用到 EOS 支持一个 transaction 可以包含多个 action 的特点,具体代码已开源,有兴趣的可以访问 https://github.com/MediShares/mds-eosjs/tree/master/eos/sample06

WechatIMG2471