英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论