BEP-402: Complete Missing Fields in Block Header to Generate Signature

  BEP: 402
  Title: Complete Missing Fields in Block Header to Generate Signature
  Status: Candidate
  Type: Standards
  Created: 2024-06-28

BEP-402: Complete Missing Fields in Block Header to Generate Signature

1. Summary

Since the London upgrade on the BSC chain, 5 new fields have been added to the block header, but these fields are not used when generating the block signature. As a result, users cannot guarantee that these new fields have not been tampered with after only verifying the signature. This BEP aims to address this issue.

2. Motivation

After a block producer mines a block, they first encode all fields in the block header along with the chainId, then sign it, and place the signature in the block header before broadcasting it. The receiver only needs to extract the signature and verify it to confirm whether the block has been tampered with.

The BSC client, when signing the block header, omitted the 5 new fields. In most scenarios, this does not cause security issues, as the receiver will strictly validate these fields upon receiving the block. However, to adhere to best practices in blockchain and further enhance security, this BEP proposes to include these 5 new fields when generating the signature.

3. Status

This BEP is in progress.

4. Specification

4.1 Define ParentBeaconRoot

The ParentBeaconRoot is unnecessary for BSC and is retained for compatibility with Ethereum APIs. The value of this field will be changed from nil to zero hash, allowing the encoding stage for signing and verification to be based solely on the values of the fields in the header, independent of hard fork timing. Following Geth, the zero hash will be used as a placeholder.

header.ParentBeaconRoot = new(Hash)

4.2 Encode Before Signing

The encoding logic will be determined based on whether header.ParentBeaconRoot is a zero hash.

if header.ParentBeaconRoot != nil && *header.ParentBeaconRoot == Hash{} {
    encoding = rlp([chainId,
        header.ParentHash,
        header.UncleHash,
        header.Coinbase,
        header.Root,
        header.TxHash,
        header.ReceiptHash,
        header.Bloom,
        header.Difficulty,
        header.Number,
        header.GasLimit,
        header.GasUsed,
        header.Time,
        // signature will be put at the end of header.Extra, exclude it 
        header.Extra[:len(header.Extra)-len(signature)],
        header.MixDigest,
        header.Nonce,
        header.BaseFee,
        header.WithdrawalsHash,
        header.BlobGasUsed,
        header.ExcessBlobGas,
        header.ParentBeaconRoot,
    ])
} else {
    encoding = rlp([chainId,
        header.ParentHash,
        header.UncleHash,
        header.Coinbase,
        header.Root,
        header.TxHash,
        header.ReceiptHash,
        header.Bloom,
        header.Difficulty,
        header.Number,
        header.GasLimit,
        header.GasUsed,
        header.Time,
        // signature will be put at the end of header.Extra, exclude it 
        header.Extra[:len(header.Extra)-len(signature)],
        header.MixDigest,
        header.Nonce,
    ])
}

5. Backwards Compatibility

There are no known backward compatibility issues.

6. License

The content is licensed under CC0