Web3.py: return of bytes32 and Web3.toHex changes Hash-Value

Created on 7 Feb 2018  ·  5Comments  ·  Source: ethereum/web3.py

  • Version: 0.4.18
  • Python: 3.5
  • OS: linux

What was wrong?

When calling a function which returns a bytes32-Value and use the "Web3.toHex"-Function, Web3.py will return a different Hex-Value than Web3.js.

Python

def deployed_contract(contract_interface, _contract_address):
    deployed_Contract = web3.eth.contract(contract_interface['abi'], _contract_address)

    #Set a Hash as bytes32
    test_Hex = '0xc642c686e44a00a6edf28a978930a2707cd01272349225c31476e8f836a8bdac'
    test_bytes = Web3.toBytes(hexstr=test_Hex)#Web3.toBytes(text="testhash") funktion
    print ("Input:", Web3.toHex(test_bytes))
    deployed_Contract.transact({'from': web3.eth.coinbase}).setHash(test_bytes)
    #Get the bytes32 and use "toHex"-Function
    returned_bytes = deployed_Contract.call().getHash()
    print ('Bytes:', returned_bytes)
    print ('Hex: ', Web3.toHex(returned_bytes))

Solidity

pragma solidity 0.4.18;


contract StoreHash {

    bytes32 public _myHash;

    function setHash(bytes32 _hash) public {
        _myHash = _hash;
    }

    function getHash() public view returns (bytes32) {
        return _myHash;
    }

}

Output
Input: 0xc642c686e44a00a6edf28a978930a2707cd01272349225c31476e8f836a8bdac
Bytes: ÆBƆäJ¦íòЉ0¢p|Ðr4’%Ãvèø6¨½¬
Hex: 0xc38642c386c286c3a44a00c2a6c3adc3b2c28ac297c28930c2a2707cc390127234c29225c3831476c3a8c3b836c2a8c2bdc2ac

  • What type of node you were connecting to.
    Local Testnet

Most helpful comment

I see, it is that latin-1 encoding issue.

>>> x = contracts.StoreHash.call().getHash().encode('UTF-8')
>>> contracts.w3.toHex(x)
'0xc38642c386c286c3a44a00c2a6c3adc3b2c28ac297c28930c2a2707cc390127234c29225c3831476c3a8c3b836c2a8c2bdc2ac'
>>> x = contracts.StoreHash.call().getHash().encode('latin-1')
>>> contracts.w3.toHex(x)
'0xc642c686e44a00a6edf28a978930a2707cd01272349225c31476e8f836a8bdac'
>>> 

All 5 comments

It looks like the call to getHash() is returning a different output than was put in.

The "Bytes:" and "Hex:" output correlate:

>>> Web3.toHex("ÆBÆ�äJ¦íò��0¢p|Ð�r4�%Ã�vèø6¨½¬")
'0xc38642c386efbfbdc3a44ac2a6c3adc3b2efbfbdefbfbd30c2a2707cc390efbfbd7234efbfbd25c383efbfbd76c3a8c3b836c2a8c2bdc2ac'

Maybe the transaction is not complete when you make the call to getHash. Try waiting for the transaction receipt with web3.eth.getTransactionReceipt. It will return None while the transaction is pending.

The "setHash"-function just stores the Hash. No altering involved.
So the Output should be '0xc642c686e44a...' as it is, when I'm calling it with web3.js (on the exact same contract, with the same "getHash"-function).

Also: If I copy the Bytes alias the Unicode-String (ÆBÆ�äJ¦íò��0¢p|Ð�r4�%Ã�vèø6¨½¬) and convert it with the JavaScript implementation of Web3... I also get the correct string.

@Lebski Can you try it in v4 (installed with pip install -U --pre web3)?

I see, it is that latin-1 encoding issue.

>>> x = contracts.StoreHash.call().getHash().encode('UTF-8')
>>> contracts.w3.toHex(x)
'0xc38642c386c286c3a44a00c2a6c3adc3b2c28ac297c28930c2a2707cc390127234c29225c3831476c3a8c3b836c2a8c2bdc2ac'
>>> x = contracts.StoreHash.call().getHash().encode('latin-1')
>>> contracts.w3.toHex(x)
'0xc642c686e44a00a6edf28a978930a2707cd01272349225c31476e8f836a8bdac'
>>> 

Great, thanks for confirming.

Was this page helpful?
0 / 5 - 0 ratings