5

I'm not sure how to write this block header digest/hash generation in another language then C(++). Is this even possible without a lot of hacking?

If so: Could a language-neutral format for the digest message be documented?

If not: This would be a very undesireable lock-in: EOS blocks will not be able to be validated on other blockchains like ethereum. Perhaps this hash function should be refined in a more language-neutral way.

Edit 1 (May 10) I found this serialiser that was written for steem data types, but obviously there's a lot of interoperability!

2
  • A better question might be: "How can I calculate the block digest?" Commented May 8, 2018 at 23:12
  • ^ Exactly, clear documentation on this would be extremely useful.
    – wanheda
    Commented May 8, 2018 at 23:21

2 Answers 2

7

Here's how the C++ code calculates the block digest:

  • digest_type::hash(*this) serializes the block into a binary form, then runs the binary through sha-256.
  • block.hpp#L125 identifies the order that the fields are serialized in.
  • The types of these fields is at block.hpp#L18
  • Each type has its own serialization procedure. Most of them live in libraries/fc.
  • Here's an example of how it serializes an unsigned_int. This is a 32-bit type which serializes to 1-5 bytes depending on value: raw.hpp#L210

Note: many users of the JSON RPC API have to serialize objects to binary form, so I suspect someone will create documentation of this process.

Note: the block fields may still change. I pointed to the master branch as of 2018-05-08.

3
  • Awesome, could you link to such a type serialisation procedure in libraries/fc?
    – wanheda
    Commented May 8, 2018 at 23:19
  • @toonsevrin added Commented May 8, 2018 at 23:28
  • Take a look at my post edit, quite a nice resource!
    – wanheda
    Commented May 10, 2018 at 14:40
0

No, it is not C++ specific. EOSIO can just be a pain.

So long story short, you have to understand what the block header properties and their respective datatypes.

for example: block_header.timestamp is of 'block_header_timestamp' type

Also, some datatypes are aliases. like all checksum256s are from the fc library (just 32 byte hex).

You must know the order and datatypes and serialize all them into a long hexadecimal. Then after, you have to hash the values using SHA256. That is the block digest.

If you're looking to create the signature digest of the block producer, you have to do this (psudo-code for explanation)

const blockDigest = '32_byte_hash_here';
const blockMerkleRoot = '32_byte_hash_here_from_block_header_state_obj';
const blockDigestMrootHash = sha256(blockDigest + blockMerkleRoot);
const scheduleHash = '32_byte_hash_here_from_block_header_state_obj';
const blockProduerSignatureDigest = sha256(blockDigestMrootHash + scheduleHash);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.