以太坊学习笔记2 -- 对以太坊机制的理解

简单的写写我对以太坊区块链的理解,不过因为我还没读完以太坊的源码,所以一些地方可能还不到位,有不同意见的,欢迎邮件交流

区块链,通过名字理解,就是区块连成的链条,区块,按我的理解,可以认为是一个结构体,以太坊的区块链就是一个单链表

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的人应该都知道PoWproof 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状态的交易 -> 形成一个区块,加入区块链当中
,打包的交易则表示交易成功

了解到这个地方,解答了一些我之前的疑问,也产生了一些新的疑问/学习方向:

  1. PoW的共识算法是怎样的,可不可以通过Block中的字段,复现出来?

  2. 为什么区块链的交易那么慢?

因为提交了一个交易之后,这个交易是放在pendingTransactions中,当有矿工挖矿成功时,你的交易才能被打包到区块链中去,交易才成功,所以交易的速度取决于矿工挖矿的速度,时间不一定,挖矿的速度还跟difficulty困难度有关,具体关联还未知

  1. 以太币怎么得到的?

以太币可以认为是打包交易的酬劳,所以每次挖矿成功能获取一定量的以太币,Block中的miner字段就是打包交易,把该区块加入区块链的用户的地址

  1. 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. 用户是怎么对交易进行签名的

另外个人账户和智能合约账户的区别之前的文章也提过了,这里就不再提了

另外还有地址内存数据映射的问题,比如:

  1. 智能合约的storage映射是怎么实现的?
  2. 区块链是一个单链表结构,geth是怎么通过区块id快速获取区块信息的?
  3. geth是怎么通过交易id快速过去交易信息的

总结

抛开区块链复杂算法不谈,区块链的机制是挺容易理解的。

矿工挖矿成功时,打包上一个区块到现在这段时间内的所有交易,然后添加进区块链中,该矿工获取相应的以太币奖励

比特币的交易只有一种行为,就是用户到用户的交易转账

但是以太坊却存在3中行为: 用户/合约到用户/合约的交易转账行为,创建智能合约,调用智能合约

文章目录
  1. 1. 交易
  2. 2. 总结