mLstudent33
mLstudent33

Reputation: 1175

Python TypeError: Unicode-objects must be encoded before hashing

I have looked at the other 4 questions on here but still cannot figure out where to put the .encode() or .encode('utf-8'). I have commented it out to show the various places I have tried.

import hashlib as hasher

    class Block:
        def __init__(self, index, timestamp, data, previous_hash):
            self.index = index
            self.timestamp = timestamp
            self.data = data 
            self.previous_hash = previous_hash #these four items used to calculate crypHash of each block
            self.hash = self.hash_block() #helps ensure integrity throughout blockchain

        def hash_block(self):
            sha = hasher.sha256() #.encode('utf-8')
            sha.update(str(self.index)+
                str(self.timestamp)+
                str(self.data)+
                str(self.previous_hash)) #.encode() inside brackets
            return sha.hexdigest()

Here is the Traceback (reading bottom up):

Traceback (most recent call last):
  File "blockchain.py", line 7, in <module>
    blockchain = [create_genesis_block()]
  File "/media/nobu/win10Files/Blockchain/SnakeCoin/genesis.py", line 8, in create_genesis_block
    return Block(0, date.datetime.now(), "Genesis Block", "0")
  File "/media/nobu/win10Files/Blockchain/SnakeCoin/block.py", line 9, in __init__
    self.hash = self.hash_block() #helps ensure integrity throughout blockchain
  File "/media/nobu/win10Files/Blockchain/SnakeCoin/block.py", line 16, in hash_block
    str(self.previous_hash))
TypeError: Unicode-objects must be encoded before hashing

which seems to indicate that the line str(self.previous_hash)) #.encode() inside brackets should be str(self.previous_hash).encode()) but that gives me this other error:

Traceback (most recent call last):
  File "blockchain.py", line 7, in <module>
    blockchain = [create_genesis_block()]
  File "/media/nobu/win10Files/Blockchain/SnakeCoin/genesis.py", line 8, in create_genesis_block
    return Block(0, date.datetime.now(), "Genesis Block", "0")
  File "/media/nobu/win10Files/Blockchain/SnakeCoin/block.py", line 9, in __init__
    self.hash = self.hash_block() #helps ensure integrity throughout blockchain
  File "/media/nobu/win10Files/Blockchain/SnakeCoin/block.py", line 16, in hash_block
    str(self.previous_hash).encode())
TypeError: must be str, not bytes

So I tried encode() and decode() in various combinations with brackets but that only gets me alternating between errors.
Thus, I am quite lost and would appreciate some guidance. Btw this code is from a Medium article here: Medium Snake Coin

Upvotes: 0

Views: 1083

Answers (1)

Mark Tolonen
Mark Tolonen

Reputation: 178030

Only bytes strings can be hashed. str is a Unicode string. Encode to bytes, decode to Unicode.

In your .update(), all four items are being converted to str. So once you concatenate them together, .encode() the whole thing to bytes:

import hashlib as hasher

class Block:
    def __init__(self, index, timestamp, data, previous_hash):
        self.index = index
        self.timestamp = timestamp
        self.data = data 
        self.previous_hash = previous_hash #these four items used to calculate crypHash of each block
        self.hash = self.hash_block() #helps ensure integrity throughout blockchain

    def hash_block(self):
        sha = hasher.sha256()
        to_hash = str(self.index) + str(self.timestamp) + str(self.data) + str(self.previous_hash)
        sha.update(to_hash.encode())
        return sha.hexdigest()

Upvotes: 1

Related Questions