简单的写写我对以太坊区块链的理解,不过因为我还没读完以太坊的源码,所以一些地方可能还不到位,有不同意见的,欢迎邮件交流
区块链,通过名字理解,就是区块连成的链条,区块,按我的理解,可以认为是一个结构体,以太坊的区块链就是一个单链表
1 2 3 # 以太坊当前最大的区块,或者可以称为区块链的长度 > eth.blockNumber 5973242
第一个区块的id自然是为0,被称为创世区块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 > eth.getBlock(0) { difficulty: 17179869184, extraData: "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", gasLimit: 5000, gasUsed: 0, hash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x0000000000000000000000000000000000000000", mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", nonce: "0x0000000000000042", number: 0, parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 540, stateRoot: "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544", timestamp: 0, totalDifficulty: 17179869184, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
第二个以太坊区块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 > eth.getBlock(1) { difficulty: 17171480576, extraData: "0x476574682f76312e302e302f6c696e75782f676f312e342e32", gasLimit: 5000, gasUsed: 0, hash: "0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x05a56e2d52c817161883f50c441c3228cfe54d9f", mixHash: "0x969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f59", nonce: "0x539bd4979fef1ec4", number: 1, parentHash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 537, stateRoot: "0xd67e4d450343046425ae4271474353857ab860dbc0a1dde64b41b5cd3a532bf3", timestamp: 1438269988, totalDifficulty: 34351349760, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
其中,parentHash
是一个指向上一个区块hash
地址的指针,指向上一个区块,也就是创世区块的hash
字段,而创世区块因为是第一个区块,所以parentHash
字段的值为0x0000000000000000000000000000000000000000000000000000000000000000
,这样就形成了一个单链表
区块是怎么生成的呢?打CTF的人应该都知道PoW
,proof of work
,在CTF中相当于验证码,防止有人爆破题目,比如CTF中的一个简单PoW
:
1 2 3 4 5 6 7 8 9 10 11 12 13 def pow(): print "Proof of Work" with open("/dev/urandom") as f: prefix = f.read(5) print "Prefix: %s" %prefix.encode('base64') try: suffix = raw_input() s = suffix.decode('base64') except: m_exit(-1) r = sha512(prefix + s).hexdigest() if "fffffff" not in r: m_exit(-1)
在CTF中只有通过PoW以后才能访问题目,在区块链中,同样也有一个PoW
机制,但是算法却是更加复杂,而PoW
的过程就被称为挖矿,只有通过PoW
算法的账号才有打包交易的权利
区块的形成过程大概如下:
矿工挖矿(PoW) -> 打包当前所有处于pending状态的交易 -> 形成一个区块,加入区块链当中 ,打包的交易则表示交易成功
了解到这个地方,解答了一些我之前的疑问,也产生了一些新的疑问/学习方向:
PoW的共识算法是怎样的,可不可以通过Block中的字段,复现出来?
为什么区块链的交易那么慢?
因为提交了一个交易之后,这个交易是放在pendingTransactions
中,当有矿工挖矿成功时,你的交易才能被打包到区块链中去,交易才成功,所以交易的速度取决于矿工挖矿的速度,时间不一定,挖矿的速度还跟difficulty
困难度有关,具体关联还未知
以太币怎么得到的?
以太币可以认为是打包交易的酬劳,所以每次挖矿成功能获取一定量的以太币,Block中的miner字段就是打包交易,把该区块加入区块链的用户的地址
Block中有extraData
字段,说明可以往区块中存数据,这是怎么办到的?
交易 以太坊的第一个交易被打包在第46147
个区块中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 > eth.getBlock(46147) { difficulty: 1458282699709, extraData: "0x657468706f6f6c2e6f7267", gasLimit: 21003, gasUsed: 21000, hash: "0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0xe6a7a1d47ff21b6321162aea7c6cb457d5476bca", mixHash: "0xb48c515a9dde8d346c3337ea520aa995a4738bb595495506125449c1149d6cf4", nonce: "0xba4f8ecd18aab215", number: 46147, parentHash: "0x5a41d0e66b4120775176c09fcf39e7c0520517a13d2b57b18d33d342df038bfc", receiptsRoot: "0xfe2bf2a941abf41d72637e5b91750332a30283efd40c424dc522b77e6f0ed8c4", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 634, stateRoot: "0x0e0df2706b0a4fb8bd08c9246d472abbe850af446405d9eba1db41db18b4a169", timestamp: 1438918233, totalDifficulty: 42684150077831833, transactions: ["0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"], transactionsRoot: "0x4513310fcb9f6f616972a3b948dc5d547f280849a87ebb5af0191f98b87be598", uncles: [] }
位于transactions
字段中,所以第一个交易的地址是: 0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060
查看该交易的信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 > eth.getTransaction("0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060") { blockHash: "0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd", blockNumber: 46147, from: "0xa1e4380a3b1f749673e270229993ee55f35663b4", gas: 21000, gasPrice: 50000000000000, hash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", input: "0x", nonce: 0, r: "0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", s: "0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", to: "0x5df9b87991262f6ba471f09758cde1c0fc1de734", transactionIndex: 0, v: "0x1c", value: 31337 } > eth.getTransactionReceipt("0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060") { blockHash: "0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd", blockNumber: 46147, contractAddress: null, cumulativeGasUsed: 21000, from: "0xa1e4380a3b1f749673e270229993ee55f35663b4", gasUsed: 21000, logs: [], logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", root: "0x96a8e009d2b88b1483e6941e6812e32263b05683fac202abc622a3e31aed1957", to: "0x5df9b87991262f6ba471f09758cde1c0fc1de734", transactionHash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", transactionIndex: 0 }
从from: "0xa1e4380a3b1f749673e270229993ee55f35663b4"
账号给to: "0x5df9b87991262f6ba471f09758cde1c0fc1de734"
账号,转账value: 31337
31337
的单位是Wei,和以太币的换算如下:
1 2 > web3.toWei(1) "1000000000000000000"
这块又涉及到一个可以研究的知识点: 4. 用户是怎么对交易进行签名的
另外个人账户和智能合约账户的区别之前的文章也提过了,这里就不再提了
另外还有地址内存数据映射的问题,比如:
智能合约的storage映射是怎么实现的?
区块链是一个单链表结构,geth是怎么通过区块id快速获取区块信息的?
geth是怎么通过交易id快速过去交易信息的
总结 抛开区块链复杂算法不谈,区块链的机制是挺容易理解的。
矿工挖矿成功时,打包上一个区块到现在这段时间内的所有交易,然后添加进区块链中,该矿工获取相应的以太币奖励
比特币的交易只有一种行为,就是用户到用户的交易转账
但是以太坊却存在3中行为: 用户/合约到用户/合约的交易转账行为,创建智能合约,调用智能合约