1

I'm looking through a contract and it casts a blockhash into a uint32, then divides by 42949673 in order to attempt to get a random number between 0 and 100. I assume a blockhash is equivalent to a uint256, but would casting into a uint32 take the most significant 32 bits or the least significant 32 bits? It would make the number smaller either way, but is it chopping off the larger amount or effectively dividing by enough to make it fit into a uint32?

I ask because every block I look at has the least significant bits as zeros, after being converted into binary. I haven't looked at many, but none of the blocks I have looked at have had anything other than a stream of zeros in the least significant bits. On top of this, the contract has generated a low number each time I've rolled, which again isn't a whole lot but the odds that this happens at random is decreasing with each roll. Is this as ineffective at generating a random number as it seems, or am I just beating the odds?

  • Seems unclear; what is meant by "every block I look at has the least significant bits as zeros"? What is "block"? An example could help. – eth Nov 7 '16 at 11:11
  • A block being the things that are chained together in a blockchain. The issue was I was trying to figure it out by first converting the hash into binary then casting, but my binary converter was likely subpar and therefore not giving a decent result. – Beez Nov 7 '16 at 16:41
  • In your second paragraph, replacing block with blockhash makes it clear. block.blockhash(n) already returns binary. Is there a title that can fit your question better? Maybe mention blockhash somewhere... Reading this Q&A it's unclear what the Q was and how the answer applied: the current answer is about casting a blockhash to a uint32. – eth Nov 8 '16 at 10:11
3

I didn't get what do you try to do. the blockhash is a bytes32. However to cast uint256 into uint32 use the following function

function convert (uint256 _a) returns (uint32) 
{
    return uint32(_a);
}

In your case:

function get_hash_block_uint (uint256 _a) public returns (uint32) 
{
    return uint32(block.blockhash(_a));
}

Results:

  • bytes32: 0x97f5d27188791a619a9a12388f67169476222e646acde42ce6f1c5ef57db05bd"

  • uint32 after casting: "0x0000000000000000000000000000000000000000000000000000000057db05bd"

So you could conclude that the conversion preserves the least significant 4 bytes.

Update Solidity ^0.5.0

The blockhash function is no longer part of the block namespace in solidity versions 5 and above:

function get_hash_block_uint (uint256 _a) public returns (uint32) 
{
    return uint32(blockhash(_a));
}
  • Thanks, this is giving me correct values now. The online converter I was using to try to figure out what the code was doing may have simply not been up to par. A blockhash being a bytes32 was exactly what I needed to know. – Beez Nov 7 '16 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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