什么是 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

如何进行自动的延迟EOS转账

transaction 里面有一个 delay_sec 的参数,默认是0,可以通过自定义实现延迟EOS转账。

具体代码可以查看 contracts/eosiolib/transaction.hpp

我们通过写一个新的合约,实现延时转账的 send 功能


void send(account_name from, account_name to, asset amount, string memo, uint64_t delay) {
eosio::transaction t{};
t.actions.emplace_back(
eosio::permission_level(from, N(active)), // with `from@active` permission
N(eosio.token), // You're sending this to `eosio.token`
N(transfer),   // to their `transfer` action
std::make_tuple(from, to, amount, memo));  // with the appropriate args
t.delay_sec = delay; // Set the delay
t.send(eosio::string_to_name(memo.c_str()), from); // Send the transaction with some ID derived from the memo
}
};

最后需要记得对发送者账户进行权限设置,让该合约有权限进行转账操作。

$ cleos set account permission <sender-account> active '{"threshold": 1,"keys": [{"key": "<sender-pubkey>","weight": 1}],"accounts": [{"permission":{"actor":"<contract-account>","permission":"eosio.code"},"weight":1}]}' owner -p <sender-account>

参考:https://eosio.stackexchange.com/questions/1900/how-to-transfer-eos-after-a-particular-delay

EOS合约权限(二)- 如何检查 EOS 合约的安全性

开源,并能够验证开源代码与链上部署代码一致

比如 EOS.win 的代码就能够在 EOSpark 上查到,并已被 EOSpark 验证与链上部署代码一致
https://eospark.com/MainNet/contract/eosluckygame

慢雾科技也推出 EOS 合约验证平台,也可以做相应的查询和确认
https://eos.slowmist.io

代码安全性

EOS 代码安全性审计需要比较专业的背景知识,在合约层面一般的问题包括数值溢出漏洞、代码逻辑错误等。

权限

合约账户的权限能够控制对账户内金额转账,以及对合约进行升级,是非常重要的安全环节。目前主要有三种方法对权限进行限制。

方法一(低安全):多重签名账户

通过EOS账户体系的Weight和Threshold控制账户权限,实现由多人共同管理一个账户。假设该账户owner权限由5个不同的公钥控制,每个公钥的Weight为1,Threshold为3,表示需要这5个人中的3人进行签名,才能转账或修改合约代码,从而提升账户安全性。

参看 eosio.prods 的权限设置,就是使用这种方式 https://eospark.com/MainNet/account/eosio.prods
当然 eosio.prods 的参与者是所有当选的超级节点,公信力更高。

方法二(高安全):移交智能合约权限

修改合约权限为 eosio.prods 账户,意味着将修改合约的权限交给21个超级节点,如果需要转移资金或修改合约,需要申请节点仲裁。
使用 updateauth 命令可以进行权限的修改:

$ cleos push action eosio updateauth '{"account": "eosio", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio.prods", "permission": "active"}}]}}' -p eosio@owner
$ cleos push action eosio updateauth '{"account": "eosio", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio.prods", "permission": "active"}}]}}' -p eosio@active

参看 eosio 的权限设置,就是使用这种方式 https://eospark.com/MainNet/account/eosio

方法三(高安全):设置账户权限到一个黑洞公钥

将owner和active权限设置为一个没有人知道私钥的公钥地址(黑洞),即可保证没有人可以获得账户的实际控制权。比如 EOS1111111111111111111111111111111114T1Anm,它的公钥是0值加检验数据生成,任何人都不知道它的私钥。

以下一些最近的热门游戏合约,供大家学习研究用:

狼人
https://eosflare.io/account/eosfoiowolfs

ITE
https://eosflare.io/account/itedeathstar

EOS Bet
https://eostracker.io/accounts/eosbetdice11

EOS核心仲裁庭收费标准

请注意: 本文由EMAC(EOS 华语治理社区)仲裁候选人Achilles原创翻译,保留该声明即可转载。

原文来源:https://steemit.com/ecaf/@ecaf/ecaf-s-fee-schedule

EOS核心仲裁庭费用表

本费用表适用于在EOS核心仲裁庭(ECAF)的争议解决机制(RDR)之下进行的仲裁,详情请参见此处https://eoscorearbitration.io/home/governance/

本费用表将会不定期的修订。ECAF的费用将以EOS的形式收取。如果需要从法币转换为EOS,操作过程在本备忘录末尾的货币转换部分做了详细说明。

该收费制度分为两部分,如下:

1.不可退还的诉讼费:在提交案件时支付。

2.仲裁费用:在案件结案时支付,用于补偿仲裁员、案件管理员、仲裁庭工作人员、外部专家等在案件上花费的时间成本。

注:费用与仲裁员针对潜在的判决可能要求当事人作为担保缴纳的任何保证金是分开的。

诉讼费:

当提交仲裁申请时,申请人应支付不可退还的诉讼费,该费用取决于索赔金额,具体如下:

ecaf001

仲裁费用

根据RDR第5.9节https://eoscorearbitration.io/home/governance/ :当仲裁程序开始,仲裁员将在切实可行的范围内尽快的提交一份仲裁费用的估算。

该仲裁费用将固定使用在仲裁上并且将被支付到本法庭账户。

这样的花费可能包括:

1、仲裁员的报酬;

2、仲裁员的花费;

3、专家和翻译的成本;

4、其它与本法庭审理该案件相关的报酬和花费;

5、当事人引发的合理的法律费用和其它花费;

6、由于消极的行动或行为被仲裁员征收的罚金;

7、任何与临时或者紧急救济通知有关的费用;

8、任何与请求合并仲裁有关的费用;

仲裁费用应参照仲裁庭成员的工作量计算。费率将取决于案件的具体情况,包括其复杂性和仲裁员可能具有的任何特殊资质。

费用将按小时收取,如下文(数字以美元报价,但以EOS收取,见后文关于货币兑换的部分)。适用的费率将取决于经验水平和本人对问题的专业程度。

ecaf002

保证金

仲裁员可指示当事人按其认为适当的比例和时间提交两种类型的保证金:

1.仲裁费用的预付款。根据ECAF规则,此类由当事人预付的保证金可以由ECAF用来支付任何此类仲裁费用(包括ECAF自己的费用和开支)。

2.占争议总金额一定百分比的保证金,作为对潜在判决的担保。

如果一方当事人未能或者拒绝支付任何款项到仲裁员指示的仲裁费用的账号,仲裁员可指示另一方或多方代为支付以允许仲裁继续进行(基于任何针对仲裁费用的仲裁令或裁定)。在这种情况下,代为付款的一方可以要求仲裁员给出一个命令或裁决,以便将该金额作为违约方的一笔立即到期债务和应付账款,来进行收回。

一方当事人申请紧急救济时,除了支付不可退还的诉讼费之外,还应支付相当于750美元的EOS的保证金(见后文关于货币兑换的说明)作为紧急救济程序的预付费用。如果没有同时支付诉讼费和保证金,ECAF将不会以紧急救济程序进行处理。

临时付款

随着仲裁程序的进行,由ECAF和仲裁员批准,部分保证金可能会不时地被释放,以覆盖仲裁费用的任何部分。

如果在需要临时付款时没有或欠缺资金,付款通知可以被提交给当事人直接进行付款。

支付方式

ECAF只会要求您将资金转入以下两个账户之一:

ecafeewallet
ecafescrowww

警告:不要将资金转移到任何其他帐户!任何向其他EOS帐户或交易所帐户付款的请求都是欺诈性请求! ECAF不会对转入其它账户的资金承担责任。

诉讼费的收取

申请人将通过ECAF官方网址的诉讼提交页面提起一个诉讼:https://eoscorearbitration.io/file-a-claim/

ECAF的案例经理随后将审核该诉讼。一旦案件经理确信不需要其他补充信息,他们将联系申请人提交诉讼费并附上适当的备注到以下地址:

Ecafeewallet

一旦成功收到诉讼费,该案件将被标记为已被仲裁庭接受,并等待分配给具体的一个仲裁员。

保证金的收取

当仲裁员被分配到一个案件时,他们将对仲裁费用进行初步估计。 (该估计将在结案时最终确定。)

仲裁员可以随后指示案件管理员将本案件的这些费用通知当事人。仲裁员还将确定是否需要要求一笔保证金来覆盖部分仲裁费用以及作为争议金额的保证金。

保证金将由案件经理负责征收,并将存入ECAF的托管账户,同时附有将提供给当事人的备注。保证金必须只能发送到以下这个账户:

Ecafescrowww

货币兑换

金额必须以EOS的形式支付。

如果任何到期金额没有以EOS为单位报价,则应按保证金和/或裁定的付款通知发出之日前一天的兑换率进行兑换。
EOS转换为美元使用的利率引用自CoinMarketCap https://coinmarketcap.com/currencies/eos/historical-data/ 在指定日期的收盘价。

如果该金额以美元以外的法定货币表示,则该金额应首先使用引用自OandA https://www.oanda.com/lang/cns/currency/converter/ 的在指定日期的平均卖出价,来转换为美元。然后再将其转换为如上所述的EOS单位。

全文完。