Peppermint is modified Tendermint. It is changed to use to make it compatible with Ethereum addresses and verifiable on Ethereum chain.


  1. Changes to signature scheme
  2. Changes to vote to make it verifiable on Ethereum smart contract
  3. Changes to vote encoding scheme

Peppermint uses secp2556k1 signature scheme to verify Tendermint votes on solidity smart contract.

It adds Data field into Vote and Proposal struct to get hash for transactions in the block. On smart contract, it checks if Data matches with checkpoint data hash and majority (⅔+1) of validator signatures. The idea is to verify if majority of the validator set agrees on transaction in the contract.

Peppermint uses RLP to get Vote bytes instead of Amino encoding. Here Data is Txs.Hash() for the block.

// [peppermint] create RLP vote to decode in contract
type CanonicalRLPVote struct {
ChainID string
Type byte
Height uint
Round uint
Data []byte

And using RLP encoding lib to get byte data for signature on Vote.

func (vote *Vote) SignBytes(chainID string) []byte {
// [peppermint] converted from amino to rlp
bz, err := rlp.EncodeToBytes(CanonicalizeVote(chainID, vote))
if err != nil {
return bz