5.2 以太坊原始碼詳解2
接下來我們看一下RLP,RLP是一種編碼規則,以太坊中的資料都會經過它編碼之後才會儲存到資料庫中,
上面是RLP的編碼原理,接下來我們看一下以太坊中的RLP
從圖上我們可以看到,在以太坊原始碼中,RLP包裡面有用的檔案其實只有三個,接下來我們詳細看看
typecache.go:
1. 核心資料結構
核心資料結構
var (
typeCacheMutex sync.RWMutex
typeCache=make(map[typekey]*typeinfo)
)
type typeinfo struct {
decoder
writer
}
type typekey struct {
reflect.Type
// the key must include the struct tags because they
// might generate a different decoder.
tags
}
- 核心函式
// map的查詢 func cachedTypeInfo(typ reflect.Type, tags tags) (*typeinfo, error) { // 加鎖 typeCacheMutex.RLock() info := typeCache[typekey{typ, tags}] // 查詢型別 typeCacheMutex.RUnlock() // 解鎖 if info != nil { // 如果不為空,直接返回 return info, nil } // not in the cache, need to generate info for this type. typeCacheMutex.Lock() defer typeCacheMutex.Unlock() return cachedTypeInfo1(typ, tags) } func cachedTypeInfo1(typ reflect.Type, tags tags) (*typeinfo, error) { key := typekey{typ, tags} info := typeCache[key] if info != nil { // 不為空,有可能是別的goroutine已經建立成功了,直接獲取資訊,返回 // another goroutine got the write lock first return info, nil } // put a dummmy value into the cache before generating. // if the generator tries to lookup itself, it will get // the dummy value and won't call itself recursively. // 建立了一個值來填充這個型別的位置,避免遇到一些遞迴定義是產生死迴圈 typeCache[key] = new(typeinfo) info, err := genTypeInfo(typ, tags) if err != nil { // remove the dummy value if the generator fails delete(typeCache, key) return nil, err } *typeCache[key] = *info //儲存到快取中 return typeCache[key], err }
-
// 生成對應型別的編、解碼器函式 func genTypeInfo(typ reflect.Type, tags tags) (info *typeinfo, err error) { info = new(typeinfo) // 建立解碼器 if info.decoder, err = makeDecoder(typ, tags); err != nil { return nil, err } // 建立編碼器 if info.writer, err = makeWriter(typ); err != nil { return nil, err } return info, nil }
上面是typecache.go中的主要邏輯
encode.go
編碼器
1 .核心資料結構
var (
// Common encoded values.
// These are useful when implementing EncodeRLP.
EmptyString = []byte{0x80}
EmptyList = []byte{0xC0}
)
// Encoder is implemented by types that require custom
// encoding rules or want to encode private fields.
type Encoder interface {
// EncodeRLP should write the RLP encoding of its receiver to w.
// If the implementation is a pointer method, it may also be
// called for nil pointers.
//
// Implementations should generate valid RLP. The data written is
// not verified at the moment, but a future version might. It is
// recommended to write only a single value but writing multiple
ӣ̵ᖫᎱ encode.go
// values or no value at all is also permitted.
EncodeRLP(io.Writer) error // 介面型別
}
2 .編碼
func Encode(w io.Writer, val interface{}) error {
if outer, ok := w.(*encbuf); ok {
// Encode was called by some type's EncodeRLP.
// Avoid copying by writing to the outer encbuf directly.
return outer.encode(val)
}
eb := encbufPool.Get().(*encbuf)
defer encbufPool.Put(eb)
eb.reset()
if err := eb.encode(val); err != nil {
return err
}
return eb.toWriter(w)
}
func (w *encbuf) encode(val interface{}) error {
rval := reflect.ValueOf(val)
ti, err := cachedTypeInfo(rval.Type(), tags{})
if err != nil {
return err
}
return ti.writer(rval, w)
}
// 此處充當buffer
type encbuf struct {
str []byte //string data, contains everything except list headers
lheads []*listhead // all list headers
lhsize int // sum of sizes of all encoded list headers
sizebuf []byte // 9-byte auxiliary buffer for uint encoding
}
type listhead struct{
offset int // index of this header in string data
size int // total size of encoded data (including list headers)
}
上面是編碼器的核心函式,解碼的邏輯大致一樣,我們不再多說
-
學院Go語言視訊主頁
https://edu.csdn.net/lecturer/1928 -
掃碼獲取海量視訊及原始碼 QQ群:721929980
相關文章
- 5.1 以太坊原始碼詳解1原始碼
- 5.3 以太坊原始碼詳解3原始碼
- 5.4 以太坊原始碼詳解4原始碼
- 5.5 以太坊原始碼詳解5原始碼
- 5.6 以太坊原始碼詳解6原始碼
- 5.7 以太坊原始碼詳解7原始碼
- 以太坊官方 Token 程式碼詳解
- Geth命令用法-引數詳解 and 以太坊原始碼檔案目錄原始碼
- 以太坊原始碼分析(37)eth以太坊協議分析原始碼協議
- 以太坊原始碼分析(18)以太坊交易執行分析原始碼
- 以太坊原始碼分析(14)P2P分析原始碼
- 以太坊原始碼分析(52)以太坊fast sync演算法原始碼AST演算法
- 以太坊原始碼分析(44)p2p-database.go原始碼分析原始碼DatabaseGo
- 以太坊原始碼分析(45)p2p-dial.go原始碼分析原始碼Go
- 以太坊原始碼分析(46)p2p-peer.go原始碼分析原始碼Go
- 以太坊原始碼分析(48)p2p-server.go原始碼分析原始碼ServerGo
- 以太坊原始碼分析(49)p2p-table.go原始碼分析原始碼Go
- 以太坊原始碼分析(50)p2p-udp.go原始碼分析原始碼UDPGo
- 3.4 以太坊架構詳解架構
- 以太坊交易池原始碼分析原始碼
- 以太坊交易池原始碼解析原始碼
- 以太坊原始碼分析(36)ethdb原始碼分析原始碼
- 以太坊原始碼分析(38)event原始碼分析原始碼
- 以太坊原始碼分析(41)hashimoto原始碼分析原始碼
- 以太坊原始碼分析(43)node原始碼分析原始碼
- 以太坊原始碼分析(51)rpc原始碼分析原始碼RPC
- 以太坊原始碼分析(52)trie原始碼分析原始碼
- 以太坊原始碼分析(54)以太坊隨機數生成方式原始碼隨機
- 以太坊原始碼分析(3)以太坊交易手續費明細原始碼
- 以太坊原始碼解讀 BlockChain的初始化原始碼Blockchain
- 3.3 以太坊核心詞彙詳解
- 以太坊原始碼分析(13)RPC分析原始碼RPC
- 以太坊原始碼分析(2)go ethereum 目錄大概介紹原始碼Go
- 以太坊原始碼分析(15)node包建立多重協議以太坊節點原始碼協議
- 以太坊原始碼分析(35)eth-fetcher原始碼分析原始碼
- 以太坊原始碼分析(20)core-bloombits原始碼分析原始碼OOM
- 以太坊原始碼分析(24)core-state原始碼分析原始碼
- 以太坊原始碼分析(29)core-vm原始碼分析原始碼