-
概述:
- BTC系统的挖矿算法存在⼀定问题,其中最为突出的就是导致了挖矿设备的专业化,普通计算机⽤户难以参与,进⽽导致挖矿趋于中⼼化,这与“去中⼼化”这⼀理念相违背。因此,在⽐特币之后包括以太坊在内的许多加密货币针对该缺陷进⾏改进,希望做到
ASIC Resistance。由于ASIC芯⽚相对普通计算机来说,算⼒强但访问内存性能差距不⼤,因此常⽤的⽅法为Memory Hard Mining Puzzle,即增加对内存访问的需求
- BTC系统的挖矿算法存在⼀定问题,其中最为突出的就是导致了挖矿设备的专业化,普通计算机⽤户难以参与,进⽽导致挖矿趋于中⼼化,这与“去中⼼化”这⼀理念相违背。因此,在⽐特币之后包括以太坊在内的许多加密货币针对该缺陷进⾏改进,希望做到
-
LiteCoin(莱特币)
- 莱特币曾⼀度成为市值仅次于⽐特币的第⼆⼤加密货币,其基本设计⼤体上和⽐特币⼀致,其主要针对挖矿算法进⾏了修改
- 莱特币的puzzle基于
Scrypt:⼀个对内存性能要求较⾼的哈希函数,之前多⽤于计算机安全密码学领域 - 基本思想:
- 设置⼀个很⼤的数组,按照顺序填充伪随机数
- 因为哈希函数的输出并不能提前预料,所以看上去就像是⼀⼤堆随机的数据,因此称其为“伪随机数”
- Seed为种⼦节点,通过Seed进⾏⼀些运算获得第⼀个数,之后每个数字都由前⼀个位置的值取哈希得到,这样的数组中取值存在前后依赖关系
- 在需要求解Puzzle时,按照伪随机顺序,从数组中读取⼀些数,每次读取位置与前⼀个数相关
- 例如第⼀次,从A位置读取其中数据,根据A中数据计算获得下⼀次读取位置B
- 第⼆次,从B位置读取其中数据,根据B中数据计算获得下⼀次读取位置C
- 设置⼀个很⼤的数组,按照顺序填充伪随机数
- 如果数组⾜够⼤,对于矿⼯来说必须保存该数组以便查询,否则每次不仅计算位置,还要根据Seed计算整个数组数据,才能查询到对应位置的数据,这对于矿⼯来说计算复杂度⼤幅度上升
- 矿⼯可以选择只保存⼀部分数据,例如:只保存奇数位置数据,偶数位置数据根据前⼀个奇数位置数据计 算即可,从⽽内存空间⼤⼩减少了⼀半(计算复杂度提⾼⼀些,但内存减少⼀半)
- 核⼼思想:挖矿过程不能仅仅进⾏运算,⽽是要增加对内存的访问,从⽽实现对ASIC芯⽚不友好
- 此⽅法对于ASIC矿机挖矿不友好,但不利于puzzle验证:
- 想要验证该puzzle,也需要存储数组,这对于轻节点来说,并不友好(系统中绝⼤多数节点为轻节点)
- 对于莱特币真正应⽤来说,数组⼤⼩不敢设置太⼤(实际中,莱特币系统设计的数组⼤⼩仅仅为128K)
- 起初莱特币发⾏时,不仅希望能抗ASIC,还希望能抗GPU,但实际中,后来慢慢出现了GPU挖矿,再后来,ASIC芯⽚挖矿也出现了,即莱特币的设计并未起到预期作⽤,也就是说,128k对于ASIC Resistance来说过⼩了
-
ETH的挖矿算法:
- 以太坊的理念与莱特币相同,都是Memory Hard Mining Puzzle,但具体设计上与莱特币不同
- 以太坊设计了两个数据集,⼀⼤⼀⼩:
- ⼩的为16MB的cache,⼤的为1G的dataset(DAG)
- 1G的数据集由16MB数据集⽣成
- 轻节点保存16MB的cache进⾏验证即可,⽽矿⼯为了挖矿更快(减少重复计算)则需要存储1GB的⼤数据集
- 16MB的cache数据⽣成⽅式与莱特币中⽣成⽅式较为类似:即通过Seed进⾏⼀些运算获得第⼀个数,之后每个数字都由前⼀个位置的值取哈希获得
- ETH与LiteCoin的不同:
- 莱特币:直接从数组中按照伪随机顺序读取⼀些数据进⾏运算
- 以太坊:先⽣成⼀个更⼤的数组
- 以太坊中这两个数组⼤⼩并不固定,因为考虑到计算机内存不断增⼤,因此该两个数组需要定期增⼤
- DAG⽣成⽅式:
- ⼤的数组中每个元素都由从⼩数组中按照伪随机顺序读取⼀些元素获得,⽅法同莱特币
- 如第⼀次读取A位置数据,对当前哈希值更新迭代算出下⼀次读取位置B,再进⾏哈希值更新迭代计算出C位置元素
- 如此来回迭代读取256次,最终算出⼀个数作为DAG中第⼀个元素
- DAG中每个元素⽣成⽅式都以此类推
- 轻节点只保存⼩的cache,验证时进⾏计算即可,但对于挖矿来说,如果这样则⼤部分算⼒都花费在了通过cache计算DAG上⾯,因此其必须保存⼤的数组DAG以更快挖矿
- ETH挖矿过程:
- 根据区块block header和其中的Nonce值计算得到⼀个哈希,将其映射到某个初始位置A
- 读取A位置的数及其相邻的后⼀个位置A’上的数,根据这两个数计算得到下⼀个位置B
- 读取B和B’位置上的数,以此类推,迭代读取64次,共读取128个数
- 最后计算出⼀个哈希值与挖矿难度⽬标阈值target⽐较,若不符合就重新换nonce,重复以上操作直到最终计算哈希值符合难度要求或当前区块已经被挖出
# ⽣成16MB⼤⼩的Cache def mkcache(cache_size, seed): o = [hash(seed)] for i in range(i, cache_size): o.append(hash(o[-1])) return o # 略去了源代码中对cache元素进⼀步的处理,只展示原理,即cache中元素按序⽣成,每个元素的⽣成与前⼀ 个元素相关 # 每隔30000个块会重新⽣成seed(对原来的seed求哈希值) # cache初始⼤⼩为16M,每隔30000个块重新⽣成时增⼤初始⼤⼩的1/128 (128K) # 通过cache⽣成DAG中第i个元素 def calc_dataset_item(cache, i): cache_size = cache.size mix = hash(cache[i % cache_size] ^ i) for j in range(256): cache_index = get_int_from_item(mix) mix = make_item(mix, cache[cache_index % cache_size]) return hash(mix) # DAG初始⼤⼩为1G,每隔30000个块重新⽣成,并增⼤初始⼤⼩的1/128 (8M) # ⽣成DAG中的每个元素 def calc_dataset(full_size, cache): return [calc_dataset_item(cache, i) for i in range(full_size)] # 矿⼯挖矿函数与轻节点验证函数 # (全节点)矿⼯ def hashimoto_full(header, nonce, full_size, dataset): mix = hash(header, nonce) for i in range(64): dataset_index = get_int_from_item(mix) % full_size mix = make_item(mix, dataset[dataset_index]) mix = make_item(mix, dataset[dataset_index + 1]) return hash(mix) # 轻节点 def hashimoto_light(header, nonce, full_size, cache): mix = hash(header, nonce) for i in range(64): dataset_index = get_int_from_item(mix) % full_size mix = make_item(mix, calc_dataset_item(cache, dataset_index)) mix = make_item(mix, calc_dataset_item(cache, dataset_index + 1)) return hash(mix) # 轻节点临时计算出⽤到的dataset元素,矿⼯是直接访存 # 矿⼯挖矿的主循环体 def mine(full_size, dataset, header, target): nonce = random.randint(0, 2**64) # 本质上为⼀个不断尝试nonce的过程 while hashimoto_full(header, nonce, full_size, dataset) > target: nonce = (nonce + 1) % 2**64 return nonce- 为何验证只需保存cache,⽽矿⼯需要保存⼤数组DAG?
- 矿⼯需要验证⾮常多的nonce,如果每次都从cache中⽣成dataset的话,挖矿效率过低,因为存在⼤量的重复计算:随机选取的dataset的元素中有很多是重复的,可能之前尝试别的nonce时⽤过
- 矿⼯采取以空间换时间的策略,把整个dataset保存下来
- 轻节点由于只验证⼀个nonce,验证的时候就直接⽣成要⽤到的dataset中的元素即可
- ⽬前以太坊挖矿以GPU为主,可⻅其设计较为成功,这与以太坊设计的挖矿算法(
ethash)所需要的⼤内存具有很⼤关系 - 以太坊能够实现ASIC Resistance,除了挖矿算法设计之外,还存在另外⼀个原因,即其预期从⼯作量证明(
POW)转向权益证明(POS)
-
预挖矿(
Pre-Mining)- 以太坊中采⽤预挖矿的机制,“预挖矿”并不挖矿,⽽是在开发以太坊时,给开发者预留了⼀部分货币
- ⽐特币并未采⽤这⼀模式,所有⽐特币都是通过挖矿产⽣的
- 和Pre-Mining对应,还有Pre-Sale
- Pre-Sale指的是将预留的货币出售掉⽤于后续开发,类似于拉⻛投或众筹
- ⽬前各类加密货币很多,存在⼀部分货币就在采⽤Pre-Sale来获取资⾦
- 如果此时买⼊,后续该货币取得成功,同样可以获得很⼤收益,但真正成功的货币只占少数,这就是其⻛险性
-
权益证明(POS)
- 权益证明(POS,
Proof of Stake):按照所占权益投票进⾏共识达成,类似于股份制有限共识按照股份多少投票,权益证明不需要挖矿 - 这对于ASIC矿机⼚商来说⾮常不利,ASIC芯⽚研发周期很⻓,成本很⾼,如果以太坊转⼊权益证明,这些投⼊的研发费⽤将全部⽩费(ASIC矿机只能⽤于挖特定的加密货币)
- 在设计之初,以太坊开发者就设想要从POW转向POS,并为了防⽌有矿⼯不愿意转埋下了⼀颗“难度炸弹”,但截⾄⽬前以太坊仍然基于POW共识机制
- 权益证明(POS,