Wrongly decoded? bytes32 in the transaction logs

Hey guys.

So, these are the logs from our smart contract:
https://testnet.aeternal.io/middleware/contracts/calls/address/ct_2M9XPMwz1GggFRPatEd2aAPZbig32ZqRJBnhTT2yRVM4k6CQnb

The problematic value is:
3264135159653872479015431810322683152639176555098724559580386778482198662677

So, this is a bytes32 argument written as the result of Crypto.sha256.

When I decode it - the hex value of that bytes32 is 7376f5e1bcf508a0e9f519f0ccc27250a6f1e1f83841b6b63c9791838274e15

Passing the hex value to a smart contract function that accepts bytes32 results in the following error:

**TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.**

So, either the encoder is wrong (because in fact, 7376f5e1bcf508a0e9f519f0ccc27250a6f1e1f83841b6b63c9791838274e15` is 63 symbols)

or my conversion of 3264135159653872479015431810322683152639176555098724559580386778482198662677 to 7376f5e1bcf508a0e9f519f0ccc27250a6f1e1f83841b6b63c9791838274e15 is wrong

My guess is that there is missing leading zero?

Looking forward for your response.

So, as I thought, the bytes32 argument that I’m trying to decode is

Result: "#07376f5e1bcf508a0e9f519f0ccc27250a6f1e1f83841b6b63c9791838274e15"

So to reproduce, you can run

contract CryptoHamster =
  entrypoint generate_id(sender : address, receiver : address,
   input_amount : int, hash_lock : bytes(32), expiration : int) : bytes(32) =
    let packed_string : string = String.concat(String.concat(String.concat(Address.to_str(sender),
      Address.to_str(receiver)), String.concat(Int.to_str(input_amount),
       Bytes.to_str(hash_lock))), Int.to_str(expiration))
 
    Crypto.sha256(packed_string)

with the following inputs:

ak_2ifr2XxhrMskWdnXZqJE2mVhhwhXYvQD6nRGYLMR5mTSHW4RZz, ak_2oJ2LR2N5jy5hZsxYnu9fynhUztbbuFyFp16ENPrkRidSVHCcL, 100000000000000000000, 44dbccb0a184c9cfae984bb12fc9306b2698ef2e9e64294e5ef5a2bd91ba08b5, 1576091048128

The TEMPORARY fix is to use hash.padStart(64, '0') (that’s for JS/TS)

I suppose this should be handled appropriately by the SDK because i’m sure it will cause lot’s of issues and headaches.

From then Node’s perspective:

The description of Events explains this I think. It says: “The topics are (currently, this might change in the future) presented as 256-bit unsigned integers”

And indeed, if you interpret your 256-bit integer as a bytes(32) (i.e. using 32 bytes or 64 half-bytes) you get the expected answer:

22> io:format("0x~64.16.0B\n", [3264135159653872479015431810322683152639176555098724559580386778482198662677]).
0x07376F5E1BCF508A0E9F519F0CCC27250A6F1E1F83841B6B63C9791838274E15

The node endpoint don’t know what type the Topic “really” is and can only present something generic. At the moment that something is 256-bit unsigned (little-endian) integers. The SDK may do whatever it likes with this information, if it does know the correct type it should be able to do the right thing.

2 Likes