Python Flask Blockchain giving "'dict' object not callable"

huangapple go评论77阅读模式
英文:

Python Flask Blockchain giving "'dict' object not callable"

问题

我正在使用Flask在Python中创建一个区块链,但是当我尝试进行HTTP请求以进行挖矿时,出现了错误。当前完整的代码位于https://github.com/MGedney1/Python-Blockchain/blob/master/blockchain.py。
我遇到的错误是

TypeError 'dict' object not callable.

相关的代码:

from hashlib import sha256      #导入模块
import json
from time import time
from textwrap import dedent
from uuid import uuid4
from flask import Flask, jsonify, request

class Blockchain(object):

    def __init__(self):     #初始化区块链
        self.chain = []     
        self.transactions_list = []      

        self.add_block(proof=100,previous_hash=1)       #创世区块

    def add_block(self, proof, previous_hash=None):
        """
        创建一个新的区块并将其添加到链中
        参数:
            proof (int): 工作证明算法给出的证明
            previous_hash (str): 上一个区块的哈希值
        返回:
            block (dict): 新的区块
        """
        
        block = {       #创建区块
            'index': len(self.chain) + 1,
            'timestamp':time(),
            'transactions':self.transactions_list,
            'proof': proof,
            'previous_hash':previous_hash or self.hash(self.chain[-1])      #找到上一个区块的哈希值
        }


        self.chain.append(block)        #将区块添加到链中
        self.transactions_list = []     #重置交易列表

        return block


    @staticmethod
    def hash(block):
        """
        返回给定区块的SHA-256哈希值
        参数:
            block (dict): 要查找哈希值的区块
        返回:
            hash (str): 区块的哈希值
        """
        block_string = json.dumps(block,sort_keys=True).encode()        #将区块排序为字符串
        hash = sha256(block_string).hexdigest()        #找到哈希值

        return hash

    @property
    def end_block(self):
        """
        返回链中的最后一个区块
        返回:
            last_block (dict): 链中的最后一个区块
        """
        last_block = self.chain[-1]     #找到链中的最后一个区块

        return last_block



app = Flask(__name__)       #初始化Flask应用程序

node_id = str(uuid4()).replace('-','')      #设置节点ID

blockchain = Blockchain()

@app.route('/mine', methods=['GET'])
def mine():
    last_block = blockchain.end_block()      #获取最后一个区块的证明
    last_hash = blockchain.hash(last_block)
    proof = blockchain.proof_of_work(last_hash)

    reward = 1      #奖励的价值
    blockchain.new_transaction(        #奖励矿工
        sender = '0',
        recipient = node_id,
        amount = reward,
    )

    block = blockchain.add_block(proof,last_hash)       #铸造区块

    response = ({       #创建响应
        'message': "New Block Forged",
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash'],
    })

    return jsonify(response), 200

完整的错误报告是:


[2020-01-06 18:36:06,213] ERROR in app: Exception on /mine [GET]
Traceback (most recent call last):
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return this.view_functions[rule.endpoint](**req.view_args)
File "c:/Users/mauri/OneDrive/Documents/GitHub/Python-Blockchain/blockchain.py", line 251, in mine
last_block = blockchain.end_block()      #获取最后一个区块的证明
TypeError: 'dict' object is not callable
127.0.0.1 - - [06/Jan/2020 18:36:06] "GET /mine HTTP/1.1" 500 -
英文:

I'm creating a blockchain in Python using Flask but now get an error when I try to make the HTTP requests to mine. Current full code is at https://github.com/MGedney1/Python-Blockchain/blob/master/blockchain.py.
The error I am getting is

> TypeError 'dict' object not callable.

Relevant code:

from hashlib import sha256      #Imports
import json
from time import time
from textwrap import dedent
from uuid import uuid4
from flask import Flask, jsonify, request

class Blockchain(object):

    def __init__(self):     #Initialising the blockchain
        self.chain = []     
        self.transactions_list = []      

        self.add_block(proof=100,previous_hash=1)       #Genesis block

    def add_block(self, proof, previous_hash=None):
        """
        Creates a new block and adds it to the chain
        Parameters:
            proof (int): The proof given by the Proof of Work algorithm
            previous_hash (str): The hash of the previous block
        Returns:
            block (dict): The new block
        """
        
        block = {       #Creating the block
            'index': len(self.chain) + 1,
            'timestamp':time(),
            'transactions':self.transactions_list,
            'proof': proof,
            'previous_hash':previous_hash or self.hash(self.chain[-1])      #Finding the previous blocks hash
        }


        self.chain.append(block)        #Appending to the chain
        self.transactions_list = []     #Resetting the list of transactions

        return block


    @staticmethod
    def hash(block):
        """
        Returns a SHA-256 hash of the given block
        Parameters:
            block (dict): The block to find the hash of
        Returns:
            hash (str): The hash of the given block
        """
        block_string = json.dumps(block,sort_keys=True).encode()        #Ordering the block into a string
        hash = sha256(block_string).hexdigest()        #Finding the hash

        return hash

    @property
    def end_block(self):
        """
        Returns the last block in the chain
        Returns:
            last_block (dict): The last block in the chain
        """
        last_block = self.chain[-1]     #Finding the last block in the chain

        return last_block



app = Flask(__name__)       #Initialising flask app

node_id = str(uuid4()).replace('-','')      #Setting a node id

blockchain = Blockchain()

@app.route('/mine', methods=['GET'])
def mine():
    last_block = blockchain.end_block()      #Getting the proof for the block
    last_hash = blockchain.hash(last_block)
    proof = blockchain.proof_of_work(last_hash)

    reward = 1      #Value for the reward
    blockchain.new_transaction(        #Rewarding the miner
        sender = '0',
        recipient = node_id,
        amount = reward,
    )

    block = blockchain.add_block(proof,last_hash)       #Forging the block

    response = ({       #Creating a response 
        'message': "New Block Forged",
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash'],
    })

    return jsonify(response), 200

Full error report is:


[2020-01-06 18:36:06,213] ERROR in app: Exception on /mine [GET]
Traceback (most recent call last):
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\mauri\Anaconda3\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "c:/Users/mauri/OneDrive/Documents/GitHub/Python-Blockchain/blockchain.py", line 251, in mine
last_block = blockchain.end_block()      #Getting the proof for the block
TypeError: 'dict' object is not callable
127.0.0.1 - - [06/Jan/2020 18:36:06] "GET /mine HTTP/1.1" 500 -

答案1

得分: 0

你的 end_block 方法被装饰为一个 property。这意味着在访问它时应省略括号,例如:

last_block = blockchain.end_block  # 省略括号

如果包括括号,你实际上在尝试将 end_block 返回的东西(last_block)作为函数调用,就像你做了 last_block() 一样。

或者,从 end_block 中移除 @property 装饰器。

英文:

Your end_block method is decorated as a property. That means you should omit the parentheses when accessing it, e.g.

last_block = blockchain.end_block  # Parentheses omitted

By including the parentheses you are taking the thing end_block returns (last_block) and trying to call it as a function, just like if you did last_block().

Alternatively, remove the @property decorator from end_block.

huangapple
  • 本文由 发表于 2020年1月7日 01:28:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/59616440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定