从导致SMT被黑的transferProxy函数看EOS体系的安全解决方案

下面这段就是导致SMT被黑客攻击导致价值归零、以及各大交易所纷纷停止提币的核心代码

    /*
     * Proxy transfer SmartMesh token. When some users of the ethereum account has no ether,
     * he or she can authorize the agent for broadcast transactions, and agents may charge agency fees
     * @param _from
     * @param _to
     * @param _value
     * @param feeSmt
     * @param _v
     * @param _r
     * @param _s
     */
    function transferProxy(address _from, address _to, uint256 _value, uint256 _feeSmt,
        uint8 _v,bytes32 _r, bytes32 _s) public transferAllowed(_from) returns (bool){

        if(balances[_from] < _feeSmt + _value) revert();

        uint256 nonce = nonces[_from];
        bytes32 h = keccak256(_from,_to,_value,_feeSmt,nonce);
        if(_from != ecrecover(h,_v,_r,_s)) revert();

        if(balances[_to] + _value < balances[_to]
            || balances[msg.sender] + _feeSmt < balances[msg.sender]) revert();
        balances[_to] += _value;
        Transfer(_from, _to, _value);

        balances[msg.sender] += _feeSmt;
        Transfer(_from, msg.sender, _feeSmt);

        balances[_from] -= _value + _feeSmt;
        nonces[_from] = nonce + 1;
        return true;
    }

这是黑客利用漏洞完成SMT无限增发的合约调用
https://etherscan.io/tx/0x1abab4c8db9a30e703114528e31dee129a3a758f7f8abc3b6494aad3d304e43f

方法涉及的角色:
角色1 需要转SMT、但地址里面没有ETH的人 – 合约中的_from
角色2 帮助角色1来转SMT,并支付ETH的gas费用 – 合约中的msg.sender,也是调用这个合约的人
角色3 SMT接收方

方法的目的:
角色1想要转SMT给角色3,但自己又没有ETH来支付手续费,于是角色1找到有ETH的角色2说:我给你一些SMT当做手续费,你来通过调用transferProxy来把我的SMT转给角色3,因为你有ETH

方法的漏洞:
漏洞利用前几天导致BEC归零类似的uint256溢出,绕过了if的判断,所以解决这类问题还是需要使用SafeMath来做加减乘除。

EOS体系的解决方案:

1 关于转账手续费
虽然EOS主网还没有上,但根据EOS白皮书的说法,EOS体系转账是需要手续费的,但EOS允许收款人支付。这样角色1可以把中间人角色2排除,直接与角色3交易。

2 关于智能合约漏洞
当“势不可挡的应用程序”以不可预知的方式发挥作用时,使用EOS.IO软件的区块链允许区块生产者(超级节点)替换账户的代码,而不分叉整个区块链。这类似冻结账户的过程,这个代码的替换需要选出的15/21的区块生产者投票。

3 权限管理
proxyTransfer方法里的角色B获得角色授权进行资金操作的情况,在EOS中可以通过权限映射+多签名阈值来实现,虽然没有ETH上这么灵活,但从编程友好和安全的角度是有优势的。

以太坊的智能合约的灵活性是很高的,但也对智能合约开发者提出了很高的要求,而EOS有针对性对这些做了自己的结构设计。

《失控》中对EOS和ETH关系的预言

《失控》中的故事是这样的,哈佛大学有一个进化学者叫汤姆,这个汤姆做了一个很伟大的小实验,他用自己的电脑当了一回上帝,做了这么几件事:

1、在电脑里准备了一块专用空间,就好像画出了一个伊甸园。

2、汤姆他们写了一个80个字节的编码,就是一个可以自我复制的电脑程序,这就有点像上帝造人,所以就把这个80字节的编码给它起名叫亚当。然后把亚当放在了伊甸园里让它繁殖。

3、他们给伊甸园里还设定了一个叫收割者的程序,这个收割者吧会把这个空间里不能复制的或者疯狂复制的亚当全部都清除掉,换句话说,汤姆给这个世界引入了死亡的机制。

4、他们给这个亚当设定了一个微小的变化,就是这个亚当每一次自我复制的时候,都有10%的几率会产生一个非常微小的变异,但是变异的细节统统不管,这个就相当于赋予了亚当生物遗传变异的功能。

做完这几件事之后,Tom敲了一下回车,这个空间里的亚当就开始自我复制了起来。Tom等人就去休息了,等他们一觉醒来,发现这个空间里经历了一次史诗般的进化历程:

第一阶段:
80个字节的亚当疯狂的复制,一会就把整个空间给占满了;因为有突变的机制,进化就产生了,进化出了一个之后45字节的程序,然后这个45取代了亚当,成为了伊甸园的优势物种。查看这个45发现,它是一个寄生程序,靠吃掉80,也就是亚当来繁殖自己,随着亚当被消耗,45的数量也大幅下降。

第二阶段:
剩下的80进化成了79,变成79之后,就对45免疫了,所以原来的优势物种不行了,很快,又出现了一种51个字节的程序进化出来,以79为“食”,把“79”消灭到了几乎灭绝的程度。这个时候,又出现了一个神奇的事,就是在寄生程序45身上,又出现了一种“寄生虫”,它只有22个字节,它除了寄生在45身上复制自己的信息外,别的什么事都不做。最后22成为了“伊甸园”的主人。

Tom点开这个22发现它的内部非常简单,没有任何一个人类的电脑天才能写出这种天才代码。而这一切都是在Tom睡觉的时候发生的,这个例子说明了从下到上的系统有多强大。

ETH就是那个80,EOS就是那个45。

顺带提一句,这个例子也从一个角度说明了书名《失控》的意义,就是只有失控了才能产生多样性,进化体的天性就是喜欢钻常规的漏洞。

关于以太坊钱包区块数据删除的问题

之前写了一篇关于清理以太坊钱包区块数据的文章( http://blog.eosdata.io/index.php/2017/08/ ),收到一封反馈邮件,所以答复一下

Q 您的文章指出整体删除chaindata文件夹,那么删除以后钱包还能正常工作吗?还是会自动重新同步区块数据?同步下来是不是还是那么大的数据量?
A 删除后如果再次打开 Ethereum Wallet,软件会重新同步节点数据。我自己的观察是新版的 Ethereum Wallet 同步下来的数据比以前的老版本小很多,应该也做了优化,不过重新同步的时间非常长,国内网络一般电脑开24小时才能完成。

Q 另外可不可以只删除文件夹中早期的IDB文件呢?删除后影响钱包工作吗?如果可以,多久之前的才是可以删除的呢?
A 不行。完整节点钱包,chaindata是不能删的。

Q 再一个问题wallet钱包和parity钱包哪个更好用呢?parity可以用来创建合约吗?
A 总体来说 Parity 更好用,同步速度快,针对开发合约更友好。不过Parity也有问题,首先就是没有官方钱包安全性高,之前内置Multi-Sign钱包智能合约出过漏洞,另外目前的版本对ERC20代币的操作比较复杂。

如何检查你保存EOS的以太坊钱包被正确的设置了EOS公钥

背景:目前EOS的代币是基于以太坊的ERC20的代币,其在ICO结束后48小时会被冻结,并映射到EOS公链上。所以上一篇文章介绍了如何建立映射的方法,此文讲讲如何确认你的公钥被正确映射了。

打开 MEW 在线钱包:
https://www.myetherwallet.com/#contracts

‘Select Existing Contract’ 中选择 ‘EOS Contribution’

然后选择"Keys"

输入你保存EOS的以太坊地址

点击‘Read’

检查输出的 EOS公钥地址是否正确。

如何生成以及注册eos公钥

ERC: EOS在完成ICO后是会将目前在以太坊网络的ERC20代币转到EOS自己的区块链网络的,所以以下操作的意义就是为了将目前你以太坊钱包里的EOS,映射到将来的EOS网络中做的准备,而且在EOS ICO结束前是必须完成的操作。

原文链接:https://steemit.com/eos/@peterchen145/39yu5j-eos

公钥映射只需要在2018 年 7月3号之前完成就可以了。

大家不要紧张。

第一步:生成eos密钥对(key-pair)

1.访问EOS Token Generator,

看到如下界面

这个页面是由@nadejde基于eos官方源码开发的,他只保留了生产密钥的功能,其他的都去除了。感兴趣的,可以看他的原始文章:https://steemit.com/eos/@nadejde/eos-key-generator,

代码在这:https://github.com/Nadejde/eos-token-sale

官方代码在这:https://github.com/EOSIO/eos-token-distribution

2.点击 Generate EOS key

过一会就会生成你的密钥对:

一定把你的私钥(private key)保存好了,私钥是没办法恢复的,切记切记。

第二步:注册/映射eos密钥

注册eos密钥就是把刚才生成的密钥对建立映射关系,把公钥映射到以太坊地址上。在整个代币分发过程结束后的48小时后,erc20 代币将不能转移,而是根据映射的密钥重新生成eos区块链。

这么说好像挺复杂,简单来说就是这个过程很重要,记住这点就行了。

不过也请放松,2018年7月3号还很遥远,你有大把时间把这事情搞清楚。

注册/映射你的eos密钥对只需要在整个ico完成前进行就可以了。

你只需要注册/映射eos密钥一次就行了,注册多次只是浪费钱,除非你想更新密钥映射。

下面就是注册/映射eos密钥的步骤:

1 访问这个地址https://www.myetherwallet.com/#contracts

2 在Select Existing Contract下拉列表中选择eos contribution

3 点击access

4 这时会在access下出现这些内容:

在select a function下拉框中选择register

5 然后会出现新的内容:

在key 这栏输入你的公钥,注意是公钥。

6 然后解锁你的钱包:

7 点击解锁

8

然后,点击write

9 这时弹出一个提示框

转账数额 设为0,gas limit用默认的就行,如果钱包没有帮你自动生成gas limit,就写:90000;如果交易失败了,就提高gas limit。

10 点击生成交易。

11

点击“是的,我确定!发送交易”

12 如果一切顺利,会在页面底部出现一个绿色条,包含着一链接。

V神对于EOS能实现高并发的回复

V神最近在深圳讲座时的观点

  1. EOS是中心化应用,实际上只有100个加点参与,如果他们能实现去中心化并发,ETH也可以
  2. 使用DPOS只有100个节点参与验证,而且它们并没有merkle tree技术,所以这100个节点必然是算力很强的超级计算机。同时代理人节点容易被DDOS攻击

ERC注:

这回复很像3年前两人单挑的续集,只不过这会BM搞出了EOS,已经对ETH正面开战了

关于DPOS是中心化还是去中心化的观点很有意思,我比较认可的定义是Matthew Wampler-Doty提出了一个关于去中心化的有趣的定义:

判断一个协议是不是去中心化的,是看这个协议能不能在全部节点都永久性删除后,仅依靠一个节点仍然能够恢复过来正常运作。

这一项定义是深受生物学所启发的,就如同菌丝体借助一个单细胞就能恢复过来一样。这个观点十分的有意思,因为它引导我们注意到Tendermint是不如传统的区块链协议(比如说工作量证明协议、或者是PPC亦或是NXT中的权益证明协议)那么去中心化的。

BM挑战V神的相关内容

BM: 人人都在讨论以太坊,现在我已经收集累了很多关于以太坊的问题。正好在会议上,有机会向以太坊的主要开发者Vitalik提问。

BM提问 :(1)如何处理所有应用链集中建立在一条区块链上的问题,而你只关心区块链的名称、智能合约及博弈的问题。(2)为什么要处理纽约证交所的所有交易。

V: 我们能从几个不同的层来处理这个问题,可使你的去中心化应用整合到以太坊当中,第一层,是让整个数据库放进合约,同时能够在智能合约内体现计算。所以只要数据存在,计算也在里面。
第二层是让数据保持在链外,只是将默克尔根放到区块链上。假如你想要升级,合约能够自己询问新的默克尔树桥(merkle tree bridge)。

就像“div”能自己认证成“div”,这个想法能使数据在链外运行,计算则在链上进行。

第三种选择,是选择一些链外(off-chain)解决方案,但使用以太坊的脚本语言执行,信任交易和跨链交易同时可以以这些方式进行。

BM评论:我的第一个问题是关于以太坊的可扩展性,如何处理所有去中心化应用链集中建立在一条区块链上,而你只关心区块链的名称、智能合约和博弈的问题。为什么要处理纽约证交所的所有交易。

我不满意Vitalik的回答,因为他没有真正回答这个问题。具体来说,他提到了链外的数据存储方式,和默克尔树作为一种将数据保持链外存储,验证数据保持链上的一种方式,但问题是,你实际上不能做到这一点,将所有的数据都放在链外,即使不是存储在区块链中,只是merkel根在区块链中,数据仍然必须存在网络中的每个节点中,为了验证,区块链将不得不查询外部数据源,如果数据源错误或不可用,这将是不可持续、中心化的。那么将导致网络实际上不能被验证,第二种可能性是使用交叉链交易,这是我们推广使用的比特股(BitShares)是一样的,也是很多不同的区块链所用的,这个与比特币和莱特币的交易方式没有什么不同,而且真正的问题是为什么需要以太坊,如果你已经拥有所有这些不同的链,实际上,你并没有使用以太坊解决你的问题,我想你可以有多个克隆版的以太坊,每条链都做自己的事情,但另一个问题是为什么我要建在以太坊之上,如果实际上我并不是在同一个链上,毕竟在以太坊上,你必须做的计算将产生很多的开销,你必须把你的脚本存储在区块链当中,你必须将数据存储在区块链当中,不仅如此,每个计算和每个数据块都要收取交易费用,如果你将固定数量的带宽定义为一个去中心化的标准,在以太坊上的这些操作会更昂贵。所以在我看来,如果你想建立一个基于以太坊的去中心化应用程序,根本就没有理由使用以太坊,因为你将采用的是与Bitcoin跨链交易相同的方式进行交互。

BM提问:假如使用线下的脱链服务,如何让离开数据库的节点,验证智能合约是否执行正确,

V:假如是使用脱链服务(线下的数据),并不是每个人都能够看到单个的合约,所以当整个网络有不同级别的分离情况发生,但这个连接依然还是会形成,因为你可以使用以太坊的智能合约,这实际上就能使线下的数据能够在其他合约上流通执行,所以这个想法是成立的。
BM提问:另一个与工作量证明机制(POW)有关的问题,工作量证明机制在扩容经济方面看起来像中心化的,所以,无论谁垄断,最终仍由工作量证明机制控制这个网络。

V:这是很好的观点,我们正在研究两种独立的解决方案,一种方案是抵抗ASIC矿机的工作量证明算法,这种算法我们称之为“Dagger”算法,我们即将开始公开竞赛,做一些更有意义的研究,使用到工作量证明的算法当中,第二种则是权益证明(POS),权益证明(POS)与工作量证明(POW)相比更去中心化,我们会采取两种机制混合的策略,而工作量证明是能够允许CPU计算友好的挖矿模式。

BM评论:我问他的第二个问题是关于工作量证明机制,以及以太坊是如何使用基于安全模型的工作量证明机制,Vitalik回答说,他们可能会将工作量证明机制与权益证明机制混合起来使用,这种方法与我们将使用的方法非常类似,差异在于他们仍然试图专注于开发一个只兼容cpu的工作量证明机制, 或者一种新的让工作量证明可行的算法,但是这种并没什么用,和工作量证明机制没有太大关系,设想一下,如果它在一个cpu上工作,你最终拥有的大规模服务器集群和网络,将让你拥有大部分的哈希算力,没有什么可以让其停止的,它最终将被集中化、被控制,所以最重要的是你需要问自己,当你看这些证明的工作量或混合代币时,最重要的安全保障来自哪里。如果它来自工作量证明机制中,那么很有可能它最终将被中心化,你不能在任何形式的保障网络安全工作中采用工作量证明机制,这意味着你需要一个有100% POS机制的代币,但这个事情有一个关键点,在挖矿安全和挖矿共识之间存在差异性。当我提到挖矿共识时,我的意思是无论如何你必须决定谁创造下一个区块, 这可能是任何人,只要它不是所有人马上一起即可,如果你挖矿的唯一目的是确定下一个区块的创造者,而不是以任何形式保障安全,那么无论您是采用CPU的证明机制还是GPU的工作量证明机制都不重要。甚至使用具有工作量系统证明机制的ASIC完成。我们目前的做法是,我们对相应工作使用相同的动量,但不能保障网络安全,只是决定谁来生产下一个区块,比特股(BitShares)100%的安全性来自于它的权益证明机制,每一个区块都必须有一定的权益来保障出块,在没有和适量的权益证明的基础上,任何人都不可能产生一个新的区块,关于工作量证明机制和挖矿,很多人关注的另一个方面是代币或货币是如何发行的,这是一个糟糕的经济学例子,一个区块链应该尽量使拥有者的价值最大化,如果你付钱给人们去挖掘他的洞然后再填补它们,那么你以安全的名义付钱让人们给你做无意义的事情,降低你到整个货币供应量以免出现下列问题,他们目前的计划导致持续的通货膨胀必将存在,虽然随着时间的推移,它可能会不断下降,这表明安全是通过工作量证明机制在保障的,而不是仅仅使用工作量证明机制作为决定下一个出块者的手段。

ERC注:这还是2014年的事情,2014年以太坊刚完成ICO和几个早期POC,可以看出大神级别的人物看问题的超前性,看到了3年后的问题,不过也是现在EOS挑战ETH的发端,因为这些问题目前在ETH上的确爆发出来了。

以太币的经济模型

作用

  1. 建立在以太坊(公链)上应用的每一个操作需要支付以太币,包括转账、智能合约中每一步操作,同时也防止了恶意程序的攻击
  2. 作为对矿工的奖励

Gas

  1. GasPrice: 用户可以自定义的Gas单价,一般用Gwei作单位
  2. GasAmount: 每一步操作消耗多少Gas的量由系统定义
  3. 两者相乘得到总共会消耗的以太币
  4. 消耗的以太币一部分发送到不可提现地址0x00销毁,一部分作为旷工奖励

调用合约方法所需要的Gas

  1. estimateGas 可以获得所需的gas数量
  2. 普通的转账交易所需要的gas是固定的21000
  3. 调用合约方法所需要的gas根据占用的资源(计算量、内存等)确定
  4. getTransactionReceipt返回gasUsed显示消耗的Gas

思考

  1. 以太坊具有交易系统的价值
  2. 以太币可通过以太坊进行二级市场交易
  3. 以太币的消耗(销毁)和增发(挖矿)使其成为一个流动的经济系统
  4. 围绕着这个经济系统,以太坊本身也可看做是一个去中心化的公司

参考

Gas气象站:http://ethgasstation.info/
发布矿工会打包的安全 gas price 的最低价格

以太币单位
wei 1
Kwei/ada/femto 103
Mwei/babbage/pico 106
Gwei/shannon/nano 109
szabo/micro 1012
finny/milli 1015
ether 1018

每个指令的 Gas 费用
操作名称 费用(单位:gas) 描述
step 1 为了支付一个执行周期的默认瓦斯量
stop 0 停止操作不需要任何费用
suicide 0 自杀操作不需要任何费用
sha3 20 一次SHA3操作的费用
sload 20 一次加载操作的费用
sstore 100 一次普通的存储操作所需的费用 (有时候会加倍或者免除)
balance 20 一次余额查询操作所需的费用
create 100 一次创建操作所需费用
call 20 一次调用操作所需费用
memory 1 在扩展存储时每增加一个单词所需费用
txdata 5 交易时每个字节的数据或者数据所需费用
transaction 500 每次交易所需费用

以太坊的问题和EOS的解决方案(一)

这篇先写写以太坊的问题

  1. 以太坊的性能不能支撑普通商业应用
  2. 以太坊需要用户先购买以太币,而购买虚拟货币的操作门槛太高
  3. 以太坊系统设计太复杂,导致它难以按计划切换POS,并经常发生相关的安全性问题
  4. 以太坊的开发生态太复杂,搞出了一大堆语言和实现
  5. 以太坊目前的POW共识机制成本太高(占到新币价值的11%)