# Geth 源码解析
v1.8
- accounts 自己钱包账户相关的应用
- hd abi
- build
- cmd 启动geth 命令行体系
- common 公共的一些内库
- consensus *important 共识 交易怎么确认 挖矿奖励机制 等
- console 控制台用js做交互的内容
- container/docker
- contracts 合约
- core *important 基本的数据结构 区块账户状态等
- crypto 加密算法 hash 椭圆曲线
- dashboard 仪表盘 环境监控和测试
- eth 协议层 实现以太坊协议 怎么信息调用 通信
- ethclient 客户端的实现
- ethdb 以太坊底层数据库的包
- ethstats 收集统计信息
- event 事件
- internal 内部做的一些测试
- les
- light
- log 日志
- metrics
- miner 挖矿相关的
- mobile
- node 节点相关
- p2p 网络组件
- params 初始的配置和参数
- rlp rlp编码方式
- rpc rpc 协议调用方式 的实现
- signer
- swarm * 以太坊分布式存储的方式 底层 服务
- tests
- trie 实现MPT
- vendor
- whisper * 消息机制的服务
- .dockerignore
- .gitattributes
- .gitignore
- .gitmodules
- .mailmap
- .travis.yml
// /go-ethereum/blob/master/trie/node.go
type (
fullNode struct {
Children [17]node
flags nodeFlag
}
// 扩展节点和叶子节点
shortNode struct {
Key []byte // incepath
Val node // hashNode valueNode
flags nodeFlag
}
hashNode []byte
valueNode []byte
)
...
func (n *fullNode) EncodeRLP(w io.Writer) error {
var nodes [17]node
for i, child := range &n.Children {
if child != nil {
nodes[i] = child
} else {
nodes[i] = nilValueNode
}
return rlp.Encode(w, nodes)
}
}
...
type nodeFlag struct {
hash hashNode
gen uint16
dirty bool
}
// /go-ethereum/blob/master/trie/encoding.go
// 压缩打包 两个16进制字符和在一起变为一个字符
func hexToCompact(hex []byte) []byte {
terminator := byte(0) // byte(0) 初值为0
if hasTerm(hex) { //
terminator = 1
hex = hex[:len(hex)-1]
}
buf := make([]byte, len(hex)/2+1)
buf[0] = terminator << 5
if len(hex)&1 == 1 {
buf[0] |= 1 << 4
buf[0] |= hex[0]
hex = hex[1:] //
}
decodeNibbles(hex, buf[1:])
return buf
}
func compactToHex(compact []byte) []byte {
base := keybytesToHex(compact)
if base[0]<2 {
base = base[:len(base) -1]
}
chop := 2-base[0]&1
return base[chop:]
}
...
func decodeNibbles(nibbles []byte,bytes []byte) {
for bi, ni :=0, 0; ni<len(nibbles); bi,ni=bi+1,ni+2 {
bytes[bi] = nibbles[ni] << 4 | nibbles[ni+1]
}
}
func hasTerm(s []byte) bool {
return len(s)>0 && s[len(s)-1] = 16
}
// /go-ethereum/blob/master/trie/trie.go
type Trie struct {
db *Database
root node
cachegen, cachelimit uint16
}
func New(root common.Hash, db *Database)(*Trie, error){
if db==nil {
panic("trie.New called without a database")
}
trie := &Trie{
db: db,
}
if root != (common.Hash{}) && root != emptyRoot {
rootnode, err := trie.resolveHash(root[:], nil)
if err!=nil {
return nil, err
}
trie.root = rootnode
}
return trie, nil
}