Go-ethereum 源碼解析之重要的數(shù)據(jù)結(jié)構(gòu)和算法

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

  1. https://github.com/ethereum/go-ethereum/blob/master/miner/worker.go

Contributor

  1. Windstamp, https://github.com/windstamp
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹂楣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子讯蒲,更是在濱河造成了極大的恐慌痊土,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墨林,死亡現(xiàn)場離奇詭異赁酝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)旭等,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門酌呆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搔耕,你說我怎么就攤上這事隙袁。” “怎么了弃榨?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵菩收,是天一觀的道長。 經(jīng)常有香客問我惭墓,道長坛梁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任腊凶,我火速辦了婚禮划咐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钧萍。我一直安慰自己褐缠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布风瘦。 她就那樣靜靜地躺著队魏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪万搔。 梳的紋絲不亂的頭發(fā)上胡桨,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天先朦,我揣著相機(jī)與錄音笆豁,去河邊找鬼苗傅。 笑死部脚,一個(gè)胖子當(dāng)著我的面吹牛嗡害,可吹牛的內(nèi)容都是我干的鹏控。 我是一名探鬼主播庶近,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼富蓄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了尚镰?” 一聲冷哼從身側(cè)響起阀圾,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狗唉,沒想到半個(gè)月后初烘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敞曹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年账月,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澳迫。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡局齿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出橄登,到底是詐尸還是另有隱情抓歼,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布拢锹,位于F島的核電站谣妻,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卒稳。R本人自食惡果不足惜蹋半,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望充坑。 院中可真熱鬧减江,春花似錦、人聲如沸捻爷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽也榄。三九已至巡莹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甜紫,已是汗流浹背降宅。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囚霸,地道東北人钉鸯。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像邮辽,于是被迫代替她去往敵國和親唠雕。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容