标签搜索

Go-ethereum 源码解析之重要的数据结构和算法

heyuan
2023-03-03 / 0 评论 / 18 阅读 / 正在检测是否收录...

Go-ethereum 源码解析之重要的数据结构和算法

1. 数据结构

(1) 哈希

32 个字节,256 位。由算法 Keccak-256 计算。

文件:go-ethereum/common/types.go

const (
    HashLength = 32
)

type Hash [HashLength]byte

(2) 地址

20 个字节,160 位。由算法 RIPEMD-160 计算。

文件:go-ethereum/common/types.go

const (
    AddressLength = 20
)

type Address [AddressLength]byte

(3) 区块头

文件: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) 交易回执

文件: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) 日志项

文件: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) 区块

文件: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

计算 Ethereum-SHA-3(Keccak-256)散列值。也被用来计算 Solidity 中的函数签名(仅使用散列值的前 4 个字节,8 个十六进制数)。

(2) sha3

keccak256 的别名。

(3) sha256

计算 SHA-256 散列值。

(4) ripemd160

计算 RIPEMD-160 散列值。这是非对称加密?公钥和私钥?

(5) secp256k1

签名算法,生成 65 个字节的签名信息,或者 R, S, V?

  • 签名方法:secp256k1.Sign()
  • 恢复签名方法:secp256k1.RecoverPubkey()

【备注】

在比特币中,采用非对称加密算法 secp256k1 根据给定的密码求出公钥和私钥,然后对公钥采用 SHA3 家族的散列算法 ripemd160 对公钥进行二次散列,散列为 20 字节,并将散列值作为账户地址。
而在以太坊中,采用非对称加密算法 secp256k1 根据给定的密码求出公钥和私钥,然后对公钥采用 SHA3 家族的散列算法 keccak256 对公钥进行二次散列,散列为 32 字节,将将散列值的前 20 个字节作为账户地址。

3. 重要的概念

(1) 区块头哈希

区块头哈希是指采用散列算法 keccak256 对区块头中所有数据计算出的散列值。

(2) 区块头签名哈希

区块头签名哈希是指采用散列算法 keccak256 对区块头中除了额外数据中的最后 65 个字节之外所有数据计算出的散列值。

(3) 区块哈希

区块哈希,即区块头哈希。

(4) 区块签名哈希

区块签名哈希即区块头签名哈希。

(5) 账户地址 & 以太坊账户地址 & 以太坊账户

以太坊账户地址即 common.Address,包含 20 个字节。

(6) 智能合约地址 & 以太坊智能合约地址

以太坊智能合约地址即 common.Address,包含 20 个字节。

在以太坊中账户地址和智能合约地址基本相同,但也有一些显著的差别:

  • 账户地址由人操控,或者说由以太坊的外部操控。
  • 智能合约地址由账户地址操控。

(7) 签名者

签名者即以太坊账户地址。

(8) 签名区块 & 待确定区块

签名区块是本地节点最新挖出来的区块,存入本地节点的待确定区块列表,需要等待网络中其它节点的验证。

签名区块中,区块头、交易列表、交易回执列表都已经组装完成,并且区块头中也已经包含了签名。

Reference

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

Contributor

  1. Windstamp, https://github.com/windstamp
0

评论

博主关闭了所有页面的评论