以太坊(Ethereum)是一个建立在区块链技术之上,去中心化应用平台。它允许任何人在平台中建立和使用通过区块链技术运行的去中心化应用。
区块链是一个去中心化的分布式账本。去中心化就表示区块链网络中的每个节点是分散和独立的,同时又要保证整体的一致性(包括数据和行为),这就是共识,所以共识机制,就是在一个时间段内对事物的前后顺序达成共识的一种算法。
区块链中的情况是非常复杂,节点数量众多,每个节点的网络情况各不相同,其中会掺杂很多恶意的节点企图从中获取私立,如何保证整个区块链网络正常平稳的运行,共识机制是至关重要的一环。
区块链共识机制其中一个经典问题就是拜占庭将军问题,理解这个问题就可以更加理解区块链和比特币挖矿的运行机制。
拜占庭将军问题的描述如下: 拜占庭帝国想要进攻一个强大的敌人,为此派出了10支军队去包围这个敌人。这个敌人虽不比拜占庭帝国,但也足以抵御5支常规拜占庭军队的同时袭击。这10支军队在分开的包围状态下同时攻击。他们任一支军队单独进攻都毫无胜算,除非有至少6支军队(一半以上)同时袭击才能攻下敌国。他们分散在敌国的四周,依靠通信兵骑马相互通信来协商进攻意向及进攻时间。困扰这些将军的问题是,他们不确定他们中是否有叛徒,叛徒可能擅自变更进攻意向或者进攻时间。在这种状态下,拜占庭将军们才能保证有多于6支军队在同一时间一起发起进攻,从而赢取战斗?
具体可以参考http://baijiahao.baidu.com/s?id=1591728006111720793&wfr=spider&for=pc |
对于拜占庭将军问题的解决方案,比特币创造性地引入工作量证明(POW : Proof of Work)。通过工作量证明就增加了发送信息的成本,降低节点发送消息速率,这样就以保证在一个时间只有一个节点(或是很少)在进行广播,同时在广播时会附上自己的签名。
拜占庭将军问题在POW方案中有几个条件:
1.一位将军A在向其他的将军(B、C、D…)发起一个进攻提议一样,将军B、C、D…看到将军A签过名的进攻提议书,如果是诚实的将军就会立刻同意进攻提议,而不会发起自己新的进攻提议。
2. 假设攻下一个城堡需要多次的进攻,每次进攻的提议必须基于之前最多次数的胜利进攻下提出的(只有这样敌方已有损失最大,我方进攻胜利的可能性就更大),这样约定之后,将军A在收到进攻提议时,就会检查一下这个提议是不是基于最多的胜利提出的,如果不是(基于最多的胜利)将军A就不会同意这样的提议,如果是的,将军A就会把这次提议记下来。
工作量证明其实相当于提高了做叛徒(发布虚假区块)的成本,在工作量证明下,只有第一个完成证明的节点才能广播区块,竞争难度非常大,需要很高的算力,如果不成功其算力就白白的耗费了(算力是需要成本的),如果有这样的算力作为诚实的节点,同样也可以获得很大的收益(这就是矿工所作的工作),这也实际就不会有做叛徒的动机,整个系统也因此而更稳定。
很多人批评工作量证明造成巨大的电力浪费,促使人们去探索新共识机制,目前主要的共识机制算法有:
当共识机制是使用POW工作量证明算法,那么区块链网络中的节点就需要提供算力去竞争区块,从而来维持区块链的运行,系统也会给竞争到区块的节点一定的奖励,这个过程被形象地称为挖矿,这些竞争者也就称为旷工。
以太坊的发布分成了四个阶段,即Frontier(前沿)、Homestead(家园)、Metropolis(大都会)和Serenity(宁静),在前三个阶段以太坊共识算法采用工作量证明机制(POW),在第四阶段会切换到权益证明机制(POS)。所以在目前阶段以太坊仍然处于POW的阶段。
熟悉以太坊历史的话,可以知道以太坊是通过比特币进行众筹(也就是ICO)来实现发行的。2014年7月24日起,在为期42天的众筹期间,以太坊众筹地址共收到8,947个交易,来自8,892个不重复的地址(有两个地址是在众筹时间段之外支付的,所以这两个地址不能获得以太币)。通过此次众筹,以太坊项目组筹得31,529.356,395,51BTC,当时价值约1800w美元,0.8945BTC被销毁,1.7898BTC用于支付比特币交易的矿工手续费。同时,以太坊发布后,需要支付给众筹参与者共计60,108,506.26以太币。在众筹成功一年后的2015年7月30日,以太坊正式发布。创世区块中包含了8893个交易。所以太坊中的以太币并不全是矿工挖掘出来的,有大约7200w以太币是在创世时就已经创造出来了。可以在https://etherscan.io/stat/supply查询到以太币的发行情况:
截止2018年5月25日,已经存在99,647,528.78以太币,其中72.3是创世区块中包含的,挖矿产生的以太币仅占到不足四分之一。
以太坊是12秒出一个区块,以太坊的奖励机制采用的是:区块奖励+叔块奖励+叔块引用奖励,详情如下:
普通区块奖励: 固定奖励5ETH,每个普通区块都有 区块内包含的所有程序的Gas花费的总和 如果普通区块包含了叔块,每包含一个叔块可以得到固定奖励5ETH的1/32,也就是0.15625ETH。
叔块奖励: 叔块的奖励计算有些复杂,公式为: 叔块奖励 = ( 叔块高度 + 8 - 包含叔块的区块的高度 ) * 普通区块奖励 / 8 具体参考https://juejin.im/entry/59ad0169f265da2498241fde |
另外和比特币不同,以太币的发行总量是上限。但是以太坊后期也会往POS转换,避免无休止的算力竞争。
GPU(英语:Graphics Processing Unit,图形处理器),又称显示芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上图像运算工作的微处理器。GPU的工作大部分都计算量大,而且要重复很多很多次,是非常适合挖矿的。
目前像比特币和以太坊的POW算法都是重复性高的计算任务,相比于CPU来说GPU更加有算力优势。CPU作为通用性计算单元,里面设计了很多诸如分支预测单元、寄存单元等等模块,这些对于提升算力是根本没有任何帮助的。CPU根本不擅长于进行并行运算,一次最多就执行十几个任务,这个和GPU拥有数以千计的流处理器差太远了,GPU高太多了,因此大家慢慢针对GPU开发出对应的挖矿算法进行挖矿。
我们前面一直提到算力,算力就是代表矿机的计算能力、计算性能的衡量,具体代表的是每秒矿机的整体hash算法运算次数。算力的单位是Hash/s,一般也表示为KHash/s, MHash/s:
1 KHash/s =1000 Hash/s
1 MHash/s = 1000 KHash/s
1 GHash/s = 1000 MHash/s
1 THash/s = 1000 GHash/s
1 PHash/s = 1000 THash/s
挖矿的本质就是解决一个数学计算,谁先算出来谁就获得奖励(币),这个数学计算方式也很简单,就是一直不断的尝试碰撞结果。就类似于你暴力破解一个手机密码(假设尝试多次手机不会被锁),你不断的尝试密码从 111111~ 99999 一个一个的尝试直到你解锁成功,如果你1秒内能尝试一次你的算力就是1次/s 1秒内能尝试两次你的算力就是 2次/s。你1秒内尝试的次数越多你的算力就越大,你解锁的时间也就越短。矿机也是一样,矿机1秒内能计算的hash算法次数越多算力越大,挖的币越多。
不同的币种的挖矿算法是不一样,比特币是sha256算法,莱特币是scrypt算法,以太坊是Ethash算法,所以不用的币种之间的算力是没有任何关系的
随着区块链的流行,像比特币和以太坊全网的算力在不断的呈指数级别上涨,单个设备挖矿(solo挖矿)几乎无法获得收益,对于个人来说只能加入矿池共享收益。
矿池是将分散在全球的矿工及矿场的算力进行联结,一起挖矿。矿池负责信息打包,接入进来的矿场负责竞争记账权。由于集合了很多矿工的算力,所以矿池的算力占比大,挖到区块的概率更高。矿池挖矿所产生的奖励会按照每个矿工贡献算力的占比进行分配。相较solo挖矿,加入矿池可以获得更加稳定的收益。
支持以太坊的矿池有
使用CPU来挖矿以太币,因为效率、效益太低了,在目前的阶段已经很难挖到,所以这里只是作为举例介绍,本文是在Linux环境下进行:
首先使用geth同步以太坊区块链:
$ nohup geth \ --fast --cache=1024 \ --datadir=public_fast \ 1>>eth_public_fast.log 2>>eth_public_fast.log & |
同步进程运行后,可以另开窗口登录控制台:
$ geth attach public_fast/geth.ipc Welcome to the Geth JavaScript console!
instance: Geth/v1.7.2-stable-1db4ecdc/linux-amd64/go1.9.2 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
> |
同步需要花比较长的时间,同步情况可以通过web3.eth.syncing查询,待web3.eth.syncing返回false说明同步完成:
> web3.eth.syncing false > web3.eth.blockNumber 5671651 |
挖矿前需要有账号,如果没有的话可以创建账号,并且设置为挖矿的账号
> web3.personal.newAccount("password") "0xa736b7dc09ab53c07b01c6e23b18d2e92271d4f3"
> web3.eth.coinbase = "0xa736b7dc09ab53c07b01c6e23b18d2e92271d4f3" |
开始挖矿,设置24个线程
> miner.start(24) Null |
挖矿开始后可以查看到日志:
INFO [05-25|09:09:56] Updated mining threads threads=24 INFO [05-25|09:09:58] Commit new mining work number=5671670 txs=59 uncles=0 elapsed=120.660ms |
可以通过命名查询是否在挖矿:
> web3.eth.mining true |
目前来说即使是使用GPU进行solo挖矿也是比较难挖到的,所以推荐加入矿池。本文是使用Linux系统进行挖矿,机器显卡必须是NVIDIA或者AMD,本文是NVIDIA,可以用命令查询:
$ lspci | grep -i vga 04:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1070] (rev a1) 0b:00.0 VGA compatible controller: Matrox Electronics Systems Ltd. G200eR2 42:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1070] (rev a1) |
本文加入鱼池F2POOL,首先下载挖矿软件Bminner
$ wget https://www.bminercontent.com/releases/bminer-v8.0.0-32928c5-amd64.tar.xz $ tar xvf bminer-v8.0.0-32928c5-amd64.tar.xz $ cd bminer-v8.0.0-32928c5 |
然后运行:
$ ./bminer \ -uri ethproxy://0xa736b7dc09ab53c07b01c6e23b18d2e92271d4f3[email protected]:8008 |
具体参考https://www.f2pool.com/help/start-mining/eth-etc/eth-etc
挖矿进程运行后,可以查询NVIDIA GPU的运行状况:
如果运行正常就可以在矿池页上查询到账户信息:
https://www.f2pool.com/eth/0xa736b7dc09ab53c07b01c6e23b18d2e92271d4f3