区块链:智能合约

起因

希望完成一些合约(操作内容大于等于交易),但不借助第三方的力量。

Bitcoin

上文

如P2PKSH

Bitcoin都是直接使用Opcode来保证速度,他是图灵不完整的。不如直接有一个语言可以来编程。

Namecoin

Bitcoin的第一个分支,增加了三个Opcodes

  1. NAME_NEW: Hash(random_nonce, ‘your_domain_name’)
    记录你的域名,绑定你的域名和你的私钥
    • 加nonce是就是加salt
    • 加Hash是为了防止有人可以直接知道你的domain name进而顶替你update
  2. NAME_FIRST_UPDATE: random_nonce, ‘your_domain_name’, {‘ip’: ‘234.22.34.23’}
  3. NAME_UPDATE: random_nonce, ‘your_domain_name’, {‘ip’: “new ip address”}

问题:

  • 为什么要先有第一步而不可以直接做第二步:
    因为第二步中domain name是明文,这个transcation所有人都可以看到,那么别人就可以抢注你的域名(因为矿工会根据手续费的高低安排先后顺序)
    所以这么做就是commit-reveal的protocol
  • 在第一步和第二步之间有什么要考虑的?
    需要等待12个block来让矿工完成你的注册,以防止提前公布你的域名,而导致被抢注

出现的问题:
绑定但不注册的现象很严重,需要调整注册费

NameCoin提供给我们可以在区块链中实现账户的概念

Unspent Transcation Output

Bitcoin中有两种交易,一种是直接奖励给矿工的tx,另一种是普通用户之间的转账。因为一个BTC是不可分割的,引入UTXO来实现小额交易,同时也能防止双花攻击。即每一个交易的结果都是UTXO,一对一,一对多,多对一,多对多都可能发生。
其次,如同上文Transaction一节中所说的,当一个UTXO被花出去时,它自身也会变成一个新的UTXO。比如,在一个TX中,Alice知道自己有0.75BTC,想要给Bob交易0.5BTC,Bob会得到一个0.5BTC的UTXO,而剩下的0.15BTC就是在一个新的UTXO中属于Alice。

如果要验证这个tx是否合格,那么需要回溯到最早的UTXO即奖励矿工的UTXO,然后将其分化出的各个UTXO的input value(在每个UTXO中,找零给那个人的UTXO就是unspent)相加,再将所有的output value相加,如果两者相减大于等于手续费时则合格。

输入:

  1. 上一笔交易的输出方便回溯到之前的UTXO
  2. 解锁脚本是用私钥对上一笔交易的输出加密
  3. 并加上共钥,即构造成P2SH形式(同上),矿工可以验证上一笔交易的确属于发送者

优点是

  1. 计算是在链外的,交易本身既是结果也是证明。节点只做验证即可,不需要对交易进行额外的计算,也没有额外的状态存储。交易本身的输出 UTXO 的计算是在钱包完成的,这样交易的计算负担完全由钱包来承担,一定程度上减少了链的负担。
  2. 除 Coinbase 交易外,交易的 Input 始终是链接在某个 UTXO 后面。交易无法被重放,并且交易的先后顺序和依赖关系容易被验证,交易是否被消费也容易被举证。
    UTXO 模型是无状态的,更容易并发处理。
  3. 对于 P2SH 类型的交易,具有更好的隐私性。交易中的 Input 是互不相关联的,可以使用 CoinJoin 这样的技术,来增加一定的隐私性。

缺点:

  1. 无法实现一些比较复杂的逻辑,可编程性差。对于复杂逻辑,或者需要状态保存的合约,实现难度大,且状态空间利用率比较低。
  2. 当 Input 较多时,见证脚本也会增多。而签名本身是比较消耗 CPU 和存储空间的。

State Machines

因为在UTXO中我们要余额的话需要回溯整个交易链来计算,同时不支持余额使得每个用户没有账户可言,阻止了向可编程货币的发展。
EVM引入了状态机,即在每次transaction后记录state并commit,
比如上面的例子,

  1. A有4个BTC,那么起始阶段 state: {A:4}
  2. A给B 0.25个BTC,那么经过这个TX state: {A:3.75, B:0.25}

注意到我们没有了UTXO的回溯机制,如何防止双花攻击呢?
引入了nonce,在每次交易后nonce加1。矿工检验交易顺序,如果已有nonce=4,再再次出现nonce=4的交易则为双花。

这样做的好处:不用回溯所有交易,两个state之间的交易可以快速计算,light client可以快速同步了

Replicated State Machine

  • Set of possible states: S
  • Set of possible inputs: I
  • Set of possible outputs: O
  • Transition function $f: S \times I \rightarrow S \times O$
  • Start state s $\in$ S (genesis block)

Ethereum

细节

State是Account,包括以下信息

Input就是每个transcation,包括以下信息

最后的区块链如下

其中state root是state组成的merkle patricia tree,transaction root也是。即非满merkle tree,这是因为EVM允许smart contracct来做交易以外的其他操作。

在Ethereum中,有两种账户,account和contract,他们不同之处在于:

Account Contract
Address Hash(pubkey) Hash(creator,nounce)
Code $\emptyset$ EVM code
Storage $\emptyset$ Merkle Storage Root
Balance ETH Balance ETH Balance
Nonce 发送过的交易tx数量 发送过的交易tx数量

Transaction种类:

  • create: 创建合约
  • send: 发送以太币
  • call: 使用合约

以太币内存

  • Storage: ${\{0,1\}}^{256} —> {\{0,1\}}^{256}$ map (permanent)
  • Memory: ${\{0,1\}}^{256} —> {\{0,1\}}^{256}$ map (volatile)
  • Storage很贵,Memory限制在256bit

Gas

相当于Bitcoin的Transaction Fee

  • 根据opcode计算基本的gas cost
  • 限制计算量和防止DOS攻击
  • 矿工根据Gas Price选择做哪些交易
  • 较高优先
  • 每个Block的有Gas Limit上限
  • Gas不够会终止执行

如果GAS_LIMIT ⨉ GAS_PRICE > accounts[from].balance,那么终止

如果终止,state返回到最初,但是钱还是花了的