Klaytn Consensus Validation

Hi Team,

I wanted to check on

  1. How can I verify if the block added to the Klaytn Blockchain was actually validated by 2/3 of the committee members? If somebody could suggest on what APIs I could potentially use that would be of great help.
  2. How can i re-calculate a block hash and what are the fields involved?
  3. I am aware that a random committee is chosen by VRF for consensus, but how are those members chosen, is it an entirely random process or depends on the staked KLAYs ? What increases the chances of a member to be selected in a committee ?

Thanks in advance.

Hello, thanks for asking.

First, you can find our consensus mechanism in Klaytn Docs

  1. There are 2/3 or more signatures from the committee members in the block header. You can find the source code related to this here. We don’t have such an API that shows the addresses and signature validation results for the committee members. Sorry for that.

  2. You can find the source code related to calculate the block hash here. In short, all the fields in the header are involved. You can find the header fields here.

  3. The chances to be selected as a proposer are related to the number of KLAY staked. But, the chances to be selected as a committee member is just random based on the previous block hash.

Hope this helps. If you have more questions, please let us know.

Hi Colin,
Thanks for your response. It helps.

  1. Can I check if there is an existing tool or client that can be used to decode this “extradata” field in the block header?

Thanks in advance.

Hi, Garima.

Sorry for that, we don’t have existing tool for that right now.
Could you tell me why you need this? Making the tool is not that difficult using the code references, though.

Hi Colin,
Thank you for the quick response.

We are in process of evaluating the reliability of Klaytn blockchain. We see the protocol requires 2/3 of the committee members to sign/validate before the block can be appended to the ledger. This is an important control to preserve the integrity of the information being recorded in the blockchain. Hence, we would like to validate that the protocol is working as intended and as designed.

Hi, Garima.

We don’t have a tool for that currently. To validate all the blocks with the committee information, it is somewhat complicated. Basically we should validate two things:

  1. Find the committee members of every block.
  2. Validate 2/3 members are signed to the block.

Each block contains 2/3 or more signatures in the committed seal in the extra field of the block header, but the whole committee members are not recorded in the block. You can find committee members by executing the same algorithm coded in Klaytn.

Hope this helps.

Hi Colin,

Thank you for the information. It was quite helpful.

I’m following the link shared above for the block hash calculation, and because I’m not well versed in the GO language, I have trouble debugging it.
Is there any other way to re-calculate the hash to validate it with the actual block hash? Are there any caver.js functions that could be of help?

Also, I learned that one of the major differences between ethhash and IBFT hash is that we replace the committed seal information with an empty array of bytes in the extradata field. Does Klaytn have any existing functions/ API to do this? Please help me with the links if so.

Thank you very much.

Is there any other way to re-calculate the hash to validate it with the actual block hash? Are there any caver.js functions that could be of help?

Sorry for that. caver-js does not have such a function. It is not a common usage of caver-js.
To make sure, is this what you want?

Calculate the block hash based on the given fields of a block.

Does Klaytn have any existing functions/ API to do this?

We have the function in Klaytn, but it is not exposed as an API, which is not a common usage. I can give you a command so that you can execute above two functions If needed. Before that, please give the exact input/output for the function you want.

Hi Colin,

Thank you for your response :slight_smile:

Yes, your understanding is correct and that is the sole purpose of my test. I am trying to re-calculate the block hash based on the fields of the block and validate it against the actual block hash recorded on Klaytn Blockchain (the “hash” field)

This will help a lot, Please find the input/output below :

  1. For Block Hash calculation :
    Input : Fields in the block (response of klay.getBlock() function) [attached screenshot]

    Output : Re-calculated Block Hash based on the input

  2. For Istanbul Extra :
    Input : The “extradata” field extracted from the response of klay.getBlock() [attached above with 1]
    Output : Decoded IstanbulExtra struct

Thanks for the support, really appreciate it :pray:

Hi Team,

I am trying to re-calculate the Block Hash from the Header fields as follows:

I am utilizing the existing implementation of the Klaytn GO code. My inputs are in the format of GetBlock response as follows:

I am trying to convert the data fields from GetBlock into the Header struct data types for all the required fields and running into errors when extracting Istanbul extradata.

These are the type conversions i am doing to map these to actual Header struct fields :

Can someone please help me to validate the data type conversion, and please help to guide me as I am new to GO language.

Thanks in advance

Hello, Garima.

Please check below code. I got the same block hash 0x5c0ba5050c597bbe3edfa4434b1bd59ef2c7e3d695bd023469e649dbea6aa02d1 with this code.

	header := &Header{
		ParentHash:  common.HexToHash("0x17ef3bfcd861e9f42f06616262196e3af53bbb03ef8ce1958434b22f2287aa52"),
		Rewardbase:  common.HexToAddress("0x179679457f93094a4e7186abcb2089661e92fc22"),
		Root:        common.HexToHash("0xf7cabcd8242901bc774ca7af1d9858e7f2adfa1c8d3a44402e270ca88ba6b07f"),
		TxHash:      common.HexToHash("0xfb13666763ea4562bdb3f6b288d32c963a0b05edbab59f93677aa04306784070"),
		ReceiptHash: common.HexToHash("0x01125072b53afaed30d7c90b2e28b77abb2eb2af2516a2feb00fce865dff8f92"),
		Bloom:       BytesToBloom(common.Hex2Bytes("00000000000000000000000000000000000000100000000000000000400000000004000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000040000000000000000000000000000000000010000000000000000008400000000000000080000000000000000000000000000000000000000000020008000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000008000000")),
		BlockScore:  big.NewInt(1),
		Number:      big.NewInt(49921251),
		GasUsed:     uint64(974936),
		Time:        big.NewInt(1611578519),
		TimeFoS:     26,
		Extra:       common.Hex2Bytes("d883010503846b6c617988676f312e31342e36856c696e757800000000000000f90604f901ce94bca8ffa45cc8e30bbc0522cdf1a1e0ebf540dfe29452d41ca72af615a1ac3301b0a93efa222ecc7541941782834bf8847e235f21f2c1f13fca4d5dff66219436ff2aa21d5c6828ee12cd2bc3de0e987bc0d4e7949419fa2e3b9eb1158de31be66c586a52f49c5de794e3d92072d8b9a59a0427485a1b5f459271df457c94b9456fd65a6810b19df24832c50b2e61a41867f8948a88a093c05376886754a9b70b0d0a826a5e64be9456e8c1463c341abf8b168c3079ea41ce8a387e18946873352021fe9226884616dc6f189f289aeb0cc5940b59cae1f03534209fdb9ddf5ea65b310cd7060c9453970bc504cbc41c2a0e6460aef7d866551862849416c192585a0ab24b552783b4bf7d8dc9f6855c3594e783fc94fddaeebef7293d6c5864cff280f121e194a2ba8f7798649a778a1fd66d3035904949fec555947b065fbb3a9b6e97f2ba788d63700bd4b8b408bc945e59db28cef098d5a2e877f84127aed10d7378f294ed6ee8a1877f9582858dbe2509abb0ac33e5f24e9456e3a565e31f8fb0ba0b12c03355518c6437212094386ca3cb8bb13f48d1a6adc1fb8df09e7bb7f9c8949f10d38e650184142c1c791e1b8d03e5f14ae47f94f8c9c61c5e7f2b6219d1c28b94e5cb3cdc802594b841f1cbe853c3df5fd75d25d7343e80455e103477f8b381aa0cbac56245da14b9093bcd2134bc12a7b99c02386a2a40bfd016d207c75fd0d2e34b476885448cdcd400f903edb8419e719dd155e9cc7a23f5c4e4a4ac43e4ab38758f5aa9d864267306bb0afafa8c3eaab8933cd4f0e585da5281fb4acfdd5e8ab5901ffa00dfc8bcc1146490455101b84105df89ca0f0ecebfee0358c68c9b14b9cf29af27fb70f7fefcd1d10e11c1503732280fbffec53c559bff1366cfc6e11153fab9e45d0b4230b4f418dbc7fe8d4301b841464414eadf064c3354e05b17188b8a12bb6831a7957e1e43c9f6417189863ed43b1efdd86e932fca444c80b43760adf2fa403d0938a403d7a880e9a25861caab00b841d92d24405ef652f939c91b0f12153de3d0f79f20ccff9d19b5b1907eaa37b4cb54b370cb097b8a3b3eedd484b5e59dcdbb739635a756ebd16ff67079f279292100b8410019ea8f699c67554fed7769438562bb9afcacce87d4b68aa73d79765adf60a554da08109bcae270f472e893154b2b1f5d6db11273a0fd3e386ab8a9044fb0d601b841730b78e6506ad3d2e6aa96e398a50f16350d52e67f8de48a0f1e6eb0543125515707371c9ae1896ac1ad234c6a8b69d4626e37ddfeab77b1d908762ba24bbe2300b841bc1049d862282e4a28b383c71ce08e036e486d633908dc3c4c982d3ef6209168750ffb00886e704d527cc4cb30a0f598d4888e6b645085614920192e781da89001b841949ea5ec5d8e8e3da20a54be04452a239f77e3d540a0bb1dbdcecdc7b952616d08959b9fbfa6529a968e0c9ec7b023b5271aa546799f944210ec8ed786a8efa101b84184407503c7b15a33d115721ea924e3eff4e131b4272d4c6eaab33e88390d9fbf3572f45c8ab5e7d894c4f99df6b7b52da32c0e8a4fb8903c9e81f40732503db900b841f372fb55ac864896d7d78219fc1aacd77641b4e78762e979325fff2b23b194d855939e37bc7eaaad6084dfc4cecf04806c38419ef505fd4114ee9da864bc5e2900b8417806616afaa7d21e49be276a086722cc81d8a3812c19dc80c5e32fa7dd46b3b37a387c6cf83873e2c0b114e1b833d49db2934666e2860d9b57a72fd6093118b900b841662361882fddbc22cd58eb794f06fcfeca39ccdffd642f7450037bab61920d5c06e4d65fa0397dc88875605d2821668a0ebcb94e43d72f5e27eee45860ba95b200b841cc9ba8706b8711e1a9cce58077688273709b0fdfb820a4649f624dd3eff6d6006ce999397e514553348334649b2baed97d7e0e1705459cc22c12ac3842a6e42a00b8415d7cd03c4948afd6dd29662145c661cb2a28a5da75771eddf3436db1e095237c26223e1034b4856f077f5d09a0c62442c5e8d7147caef5ab0f5af41a2edcdbe800b841762ebace1d091ec9eb161d5bfb32bdd232ecf638b4e567333cb8f38783c8973d79a7784cab13a6ceecd077b60be847113b2f8b52be2bbb16a6a496dd166d697e00"),
		Governance:  nil,
		Vote:        nil,

	b := &Block{
		header: header,


Hi Ethan,

Thank you for your support.

This really helped with data conversion.

1 Like