比特币中是用的基于交易的账本,这种模式下,系统中并没有显示的记录每个账户上有多少钱,要根据UTXO里的信息推算,包括想知道这个人一共总资产有多少个比特币,就算一下这个人的所有账户,就他有私钥的那些账户在UTXO里面一共有多少个币就可以了,好处是隐私保护比较好,你有多少钱,可能连你自己都说不清楚,那别人就更不清楚了。
但是这样就带来一个问题,就他使用上比较别扭,跟我们的日常体验不太一样,像转帐的时候,A要转给B10BTC,A要说明这10个币的来源,其中七个币是前面这个交易中收到的,另外三个币是之前另外一个交易收到的,证明币的来源的合法性,和我们平时去银行的体验是不太一样的,银行是你存钱的时候要说明钱的来源,下次花钱的时候是不用说明每一笔钱是从哪儿来的。另外一个比较别扭的地方,你在前面交易中收到一笔输出,收到一些币,将来要花的时候,必须要一次性都花出去,不能只花一部分,如果只花一部分,会出现什么情况
剩下的7个比特币会当做交易费给花出去了,这个时候,矿工就会很高兴了,但是你不高兴,这个时候应该转回给自己,如下图
很多比特币钱包可以自动生成接收余额的地址,每次交易换一个新地址,也是有利于隐私保护的,但同样跟我们的日常生活习惯不太一样,比如说,银行当中,别人转给你十万块钱,你要把三万块钱转出去,剩下七万块钱就不用管,就放在账户上就行了,问题在于比特币系统当中没有显示的维护账户的交易概念。
以太坊采用的是基于账户的模型(account-based ledger),这种模型跟银行账户是比较相似的,系统中要显示的记录,每个账户上有多少个以太币。
比如A转给B10ETH,这个交易的合法性只要检查一下A账户上有没有足够的钱就行了,比如A账户上有一百个以太币,要转10个给B,这就没问题,不用说明这100个以太币中是具体把哪十个转给了B,不用说明币的来源,是来自之前哪个交易,将来B要转给C三个以太币也是可以的,不用把剩下的转给他自己,因为有显示的这种余额的概念,所以剩下的币就直接发到账户上就行了,哈希指针也不用,不用说明币的来源。这样做的好处是对double spending attack有天然的防御作用,因为不用管币的来源,每花掉一次钱,就从你的账户上扣掉,花两次就扣两次。
replay attack (重放攻击):A->B(10ETH)发布到网络上,过一段时间之后,这个交易被写到区块链里了,A就以为转账交易完成了,假设B是有恶意的,把这个交易在网上重新广播一遍,其他节点一看是个新的转账就把A的钱扣掉了。
解决方案:
加一个计数器nonce,记录一下这个账户有史以来一共发布过多少交易,然后转账的时候,交易次数要成为交易内容的一部分,一起包含进去,都是受到发布交易的签名的保护的。
比如A->B(10ETH),A一共发布过20个交易,这是是21个,所以写上nonce=21,然后整个内容写上A的签名,如下图
然后把上图这个交易发布到网上,因为有签名的保护,所以nonce的值,别人是改不了的,然后系统中的每个节点维护A这个状态,不仅要维护A账户上的钱,还要维护nonce的值,一开始nonce=0,每次收到A发布的一个交易,nonce+1。
比如一开始的时候,A这个节点一开始的nonce=20,然后现在发布一个交易,这个节点一看,这个交易来了,是合法的,这个交易是可以执行的,同时更新一下,nonce=21,以后如果有人重放这个交易,这个节点一看,这个nonce已经是21了,已经被执行过了,就不会再执行一遍了。
定义:前面比特币说的那个账户,公私钥控制的,本地产生一个公私钥对,私钥掌握账户的控制权,也叫普通账户。
状态:balance(账户余额),nonce(计数器)
合约账户不是通过公私钥对控制的,除了balance和nonce之外还有code(代码),storage(相关状态-存储,包括每个状态的取值),一个合约可以调用另外一个合约,所以要通过nonce值记录一下调用的次数,但是合约账户不能主动发起一个交易,以太坊中的一个规定,所有的交易只能由外部账户发起,外部账户发起一个交易如果调用了一个合约账户,这个合约账户可以发送一个message调用另外一个合约,但是他不能自己品平白发起一个交易。
创建一个合约会返回一个地址,知道这个合约的地址,就可以调用这个合约,调用的过程当中状态会发生变化,所以存储(storage)就会变。
以太坊的创始人叫Vitalik,是个19岁的小孩,他当初创建以太坊的时候,比特币已经有比较成熟的代码可以作为参考,他为什么不用比特币已有的代码,而要另弄一套。
系统设计上可以改进,改出块时间,mining puzzlem,不一定一定要改账户系统,比特币基于交易模型的一个好处是隐私保护,但是以太坊要支持的智能合约,智能合约要求参与者有比较稳定的身份,这跟日常生活当中是比较类似的,比如说,你跟某个人签个合同,如果说你跟他签合同的时候,他是一个身份,签完之后,他身份变了,你找不到了,那这就有问题了,也有可能突然冒出了另外一个人,说他当初就是跟你一块签合同的,只不过换了一个身份,这就给合同的执行带来一些困难,包括将来出现纠纷的时候,你也是需要知道这个合同当初是跟谁签的。
现在有人提出来用智能合约实现一些金融衍生品,就所谓的叫financial derivative,比如说像期权期货,往合约里投一笔钱,预测未来的价格走势,如果预测正确,给你一些收益,把钱还给你,但问题是,如果你投钱的这个账户,投完钱就变了,那到时候怎么把钱还给你呢,这个不光是对于外部账户有这个问题。合约账户的问题就更严重了,如果你投钱投到一个合约账户,投完之后地址变了,找不到就麻烦了,所以以太坊创建这个系统的时候,考虑了过去的一些已有的模型的利弊得失,最终没有采用比特币中基于交易的账户模型,而是采用了基于account的账户模式,这个从目前的状况来看,还是比较合适的一个决策,就以太坊的账户是希望保持稳定的,无论是个人账户还是合约账户,如果你有隐私保护的需要,同样可以创建很多个账户,根据情况使用不同的账户进行不同的交易。