Синхронизация с Ganache-Cli в Python
Я хочу протестировать простой Ethereum смарт-контракт Ganache печатает учетные записи в нижнем регистре, и web3 выдает мне ошибку:
web3.exceptions.InvalidAddress: ('Web3.py принимает только адреса контрольной суммы. Программное обеспечение, которое предоставило вам этот адрес без контрольной суммы, следует считать небезопасным, пожалуйста, сообщите об этом как ошибку на их платформе. Попробуйте вместо этого использовать имя ENS. Или если вы должны принять более низкий уровень безопасности, используйте Web3.toChecksumAddress(lower_case_address).', '0xfcad0b19bb29d4674531d6f115237e16afce377c')
Затем я конвертирую адрес в смешанный адрес, используя:
Web3.toChecksumAddress(the_lower_case_ganache_address)
и возникает ошибка:
Файл "/usr/local/lib/python3.7/site-packages/web3/contract.py", строка 1385, в call_contract_function поднимает BadFunctionCallOutput(msg) из e web3.exceptions.BadFunctionCallOutput: не удалось выполнить транзакцию с / call контрактной функцией правильно ли развернут контракт и синхронизирована ли цепочка? 127.0.0.1 - - [25/Jan/2019 21:35:21] "POST /blockchain/user HTTP/1.1" 500 -
это мой код Python:
def check_gender(data):
valid_list = ["male", "female"]
if data not in valid_list:
raise ValidationError(
'Invalid gender. Valid choices are'+ valid_list
)
class UserSchema(Schema):
name = fields.String(required=True)
gender = fields.String(required=True, validate=check_gender)
app = Flask(__name__)
# api to set new user every api call
@app.route("/blockchain/user", methods=['POST'])
def transaction():
w3.eth.defaultAccount = w3.eth.accounts[0]
with open("data.json", 'r') as f:
datastore = json.load(f)
abi = datastore["abi"]
contract_address = datastore["contract_address"]
# Create the contract instance with the newly-deployed address
user = w3.eth.contract(
address=contract_address, abi=abi,
)
body = request.get_json()
result, error = UserSchema().load(body)
if error:
return jsonify(error), 422
tx_hash = user.functions.setUser(
result['name'], result['gender']
)
tx_hash = tx_hash.transact()
# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)
user_data = user.functions.getUser().call()
return jsonify({"data": user_data}), 200
if __name__ == '__main__':
app.run()
`и файл json:
{
"abi": [
{
"constant": false,
"inputs": [
{
"name": "name",
"type": "string"
},
{
"name": "gender",
"type": "string"
}
],
"name": "setUser",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "getUser",
"outputs": [
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"contract_address": "0xFCAd0B19bB29D4674531d6f115237E16AfCE377c"
}
1 ответ
Ошибка утверждает, что Ganache не может найти развернутый контракт для взаимодействия.
Ваш код кажется правильным, но ошибка, вероятно, возникает в этой строке:
tx_hash = user.functions.setUser(
result['name'], result['gender']
)
Код пытается установить пользователя, но не может найти контракт для взаимодействия (даже если ABI и экземпляр контракта действительны).
Если вы используете Ganache, вполне вероятно, что вы повторно развертываете контракт каждый раз, когда запускаете код, поэтому следующая строка, скорее всего, не будет работать, если вы извлекаете данные из статического файла:
contract_address = datastore["contract_address"]
Вам нужно будет динамически получать адрес контракта от Ganache, если вы каждый раз его развертываете.