Go-ethereum 源碼解析之重要的數(shù)據(jù)結(jié)構(gòu)和算法
1. 數(shù)據(jù)結(jié)構(gòu)
(1) 哈希
32 個(gè)字節(jié)沫换,256 位鳞仙。由算法 Keccak-256 計(jì)算娩贷。
文件:go-ethereum/common/types.go
const (
HashLength = 32
)
type Hash [HashLength]byte
(2) 地址
20 個(gè)字節(jié)喉磁,160 位。由算法 RIPEMD-160 計(jì)算涕癣。
文件:go-ethereum/common/types.go
const (
AddressLength = 20
)
type Address [AddressLength]byte
(3) 區(qū)塊頭
文件:go-ethereum/core/types/block.go
type Header struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Number *big.Int `json:"number" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Time *big.Int `json:"timestamp" gencodec:"required"`
Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
Nonce BlockNonce `json:"nonce" gencodec:"required"`
}
(4) 交易
文件:go-ethereum/core/types/transaction.go
type Transaction struct {
data txdata
// caches
hash atomic.Value
size atomic.Value
from atomic.Value
}
type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"`
GasLimit uint64 `json:"gas" gencodec:"required"`
Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation
Amount *big.Int `json:"value" gencodec:"required"`
Payload []byte `json:"input" gencodec:"required"`
// Signature values
V *big.Int `json:"v" gencodec:"required"`
R *big.Int `json:"r" gencodec:"required"`
S *big.Int `json:"s" gencodec:"required"`
// This is only used when marshaling to JSON.
Hash *common.Hash `json:"hash" rlp:"-"`
}
(5) 交易回執(zhí)
文件:go-ethereum/core/types/receipt.go
type Receipt struct {
// Consensus fields
PostState []byte `json:"root"`
Status uint64 `json:"status"`
CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"`
// Implementation fields (don't reorder!)
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress common.Address `json:"contractAddress"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
}
(6) 日志項(xiàng)
文件:go-ethereum/core/types/log.go
type Log struct {
// Consensus fields:
// address of the contract that generated the event
Address common.Address `json:"address" gencodec:"required"`
// list of topics provided by the contract.
Topics []common.Hash `json:"topics" gencodec:"required"`
// supplied by the contract, usually ABI-encoded
Data []byte `json:"data" gencodec:"required"`
// Derived fields. These fields are filled in by the node
// but not secured by consensus.
// block in which the transaction was included
BlockNumber uint64 `json:"blockNumber"`
// hash of the transaction
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
// index of the transaction in the block
TxIndex uint `json:"transactionIndex" gencodec:"required"`
// hash of the block in which the transaction was included
BlockHash common.Hash `json:"blockHash"`
// index of the log in the receipt
Index uint `json:"logIndex" gencodec:"required"`
// The Removed field is true if this log was reverted due to a chain reorganisation.
// You must pay attention to this field if you receive logs through a filter query.
Removed bool `json:"removed"`
}
(7) 區(qū)塊
文件:go-ethereum/core/types/block.go
type Block struct {
header *Header
uncles []*Header
transactions Transactions
// caches
hash atomic.Value
size atomic.Value
// Td is used by package core to store the total difficulty
// of the chain up to and including the block.
td *big.Int
// These fields are used by package eth to track
// inter-peer block relay.
ReceivedAt time.Time
ReceivedFrom interface{}
}
2. 算法
(1) keccak256
計(jì)算 Ethereum-SHA-3(Keccak-256)散列值哗蜈。也被用來計(jì)算 Solidity 中的函數(shù)簽名(僅使用散列值的前 4 個(gè)字節(jié),8 個(gè)十六進(jìn)制數(shù))。
(2) sha3
keccak256 的別名恬叹。
(3) sha256
計(jì)算 SHA-256 散列值候生。
(4) ripemd160
計(jì)算 RIPEMD-160 散列值。這是非對稱加密绽昼?公鑰和私鑰唯鸭?
(5) secp256k1
簽名算法,生成 65 個(gè)字節(jié)的簽名信息硅确,或者 R, S, V目溉?
- 簽名方法:secp256k1.Sign()
- 恢復(fù)簽名方法:secp256k1.RecoverPubkey()
【備注】
在比特幣中,采用非對稱加密算法 secp256k1 根據(jù)給定的密碼求出公鑰和私鑰菱农,然后對公鑰采用 SHA3 家族的散列算法 ripemd160 對公鑰進(jìn)行二次散列缭付,散列為 20 字節(jié),并將散列值作為賬戶地址循未。
而在以太坊中陷猫,采用非對稱加密算法 secp256k1 根據(jù)給定的密碼求出公鑰和私鑰,然后對公鑰采用 SHA3 家族的散列算法 keccak256 對公鑰進(jìn)行二次散列的妖,散列為 32 字節(jié)绣檬,將將散列值的前 20 個(gè)字節(jié)作為賬戶地址。
3. 重要的概念
(1) 區(qū)塊頭哈希
區(qū)塊頭哈希是指采用散列算法 keccak256 對區(qū)塊頭中所有數(shù)據(jù)計(jì)算出的散列值嫂粟。
(2) 區(qū)塊頭簽名哈希
區(qū)塊頭簽名哈希是指采用散列算法 keccak256 對區(qū)塊頭中除了額外數(shù)據(jù)中的最后 65 個(gè)字節(jié)之外所有數(shù)據(jù)計(jì)算出的散列值娇未。
(3) 區(qū)塊哈希
區(qū)塊哈希,即區(qū)塊頭哈希星虹。
(4) 區(qū)塊簽名哈希
區(qū)塊簽名哈希即區(qū)塊頭簽名哈希零抬。
(5) 賬戶地址 & 以太坊賬戶地址 & 以太坊賬戶
以太坊賬戶地址即 common.Address,包含 20 個(gè)字節(jié)宽涌。
(6) 智能合約地址 & 以太坊智能合約地址
以太坊智能合約地址即 common.Address平夜,包含 20 個(gè)字節(jié)。
在以太坊中賬戶地址和智能合約地址基本相同卸亮,但也有一些顯著的差別:
- 賬戶地址由人操控褥芒,或者說由以太坊的外部操控。
- 智能合約地址由賬戶地址操控嫡良。
(7) 簽名者
簽名者即以太坊賬戶地址。
(8) 簽名區(qū)塊 & 待確定區(qū)塊
簽名區(qū)塊是本地節(jié)點(diǎn)最新挖出來的區(qū)塊献酗,存入本地節(jié)點(diǎn)的待確定區(qū)塊列表寝受,需要等待網(wǎng)絡(luò)中其它節(jié)點(diǎn)的驗(yàn)證。
簽名區(qū)塊中罕偎,區(qū)塊頭很澄、交易列表、交易回執(zhí)列表都已經(jīng)組裝完成,并且區(qū)塊頭中也已經(jīng)包含了簽名甩苛。
Reference
Contributor
- Windstamp, https://github.com/windstamp