转账ERC20代币失败:web3.exceptions.ContractLogicError:执行恢复:ERC20:从零地址转账
Posted
技术标签:
【中文标题】转账ERC20代币失败:web3.exceptions.ContractLogicError:执行恢复:ERC20:从零地址转账【英文标题】:Transfer ERC20 Token Failed: web3.exceptions.ContractLogicError: execution reverted: ERC20: transfer from the zero address 【发布时间】:2021-08-06 06:55:18 【问题描述】:所以我尝试使用转账功能与 ERC20 智能合约进行交互,它完美运行下面的示例将扣除第一个账户的 ERC20 代币余额并将其添加到第二个账户的 ERC20 代币余额中。
import json
from web3 import Web3
from web3.middleware import geth_poa_middleware
if __name__ == "__main__":
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545', request_kwargs='timeout': 60))
w3.middleware_onion.inject(geth_poa_middleware, layer=0)
print(w3.clientVersion)
first_account = w3.eth.accounts[0]
fist_account = w3.toChecksumAddress(first_account)
print(first_account)
first_account_ether_balance = w3.eth.get_balance(first_account)
print(f"ether balance for first_account is first_account_ether_balance")
ABI = '["constant":true,"inputs":[],"name":"name","outputs":["name":"","type":"string"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"_upgradedAddress","type":"address"],"name":"deprecate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":false,"inputs":["name":"_spender","type":"address","name":"_value","type":"uint256"],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":[],"name":"deprecated","outputs":["name":"","type":"bool"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"_evilUser","type":"address"],"name":"addBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":[],"name":"totalSupply","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"_from","type":"address","name":"_to","type":"address","name":"_value","type":"uint256"],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":[],"name":"upgradedAddress","outputs":["name":"","type":"address"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":["name":"","type":"address"],"name":"balances","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"decimals","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"maximumFee","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"_totalSupply","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":["name":"_maker","type":"address"],"name":"getBlackListStatus","outputs":["name":"","type":"bool"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":["name":"","type":"address","name":"","type":"address"],"name":"allowed","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"paused","outputs":["name":"","type":"bool"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":["name":"who","type":"address"],"name":"balanceOf","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":[],"name":"getOwner","outputs":["name":"","type":"address"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"owner","outputs":["name":"","type":"address"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"symbol","outputs":["name":"","type":"string"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"_to","type":"address","name":"_value","type":"uint256"],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":false,"inputs":["name":"newBasisPoints","type":"uint256","name":"newMaxFee","type":"uint256"],"name":"setParams","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":false,"inputs":["name":"amount","type":"uint256"],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":false,"inputs":["name":"amount","type":"uint256"],"name":"redeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":["name":"_owner","type":"address","name":"_spender","type":"address"],"name":"allowance","outputs":["name":"remaining","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"basisPointsRate","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":["name":"","type":"address"],"name":"isBlackListed","outputs":["name":"","type":"bool"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"_clearedUser","type":"address"],"name":"removeBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":[],"name":"MAX_UINT","outputs":["name":"","type":"uint256"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"newOwner","type":"address"],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":false,"inputs":["name":"_blackListedUser","type":"address"],"name":"destroyBlackFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","inputs":["name":"_initialSupply","type":"uint256","name":"_name","type":"string","name":"_symbol","type":"string","name":"_decimals","type":"uint256"],"payable":false,"stateMutability":"nonpayable","type":"constructor","anonymous":false,"inputs":["indexed":false,"name":"amount","type":"uint256"],"name":"Issue","type":"event","anonymous":false,"inputs":["indexed":false,"name":"amount","type":"uint256"],"name":"Redeem","type":"event","anonymous":false,"inputs":["indexed":false,"name":"newAddress","type":"address"],"name":"Deprecate","type":"event","anonymous":false,"inputs":["indexed":false,"name":"feeBasisPoints","type":"uint256","indexed":false,"name":"maxFee","type":"uint256"],"name":"Params","type":"event","anonymous":false,"inputs":["indexed":false,"name":"_blackListedUser","type":"address","indexed":false,"name":"_balance","type":"uint256"],"name":"DestroyedBlackFunds","type":"event","anonymous":false,"inputs":["indexed":false,"name":"_user","type":"address"],"name":"AddedBlackList","type":"event","anonymous":false,"inputs":["indexed":false,"name":"_user","type":"address"],"name":"RemovedBlackList","type":"event","anonymous":false,"inputs":["indexed":true,"name":"owner","type":"address","indexed":true,"name":"spender","type":"address","indexed":false,"name":"value","type":"uint256"],"name":"Approval","type":"event","anonymous":false,"inputs":["indexed":true,"name":"from","type":"address","indexed":true,"name":"to","type":"address","indexed":false,"name":"value","type":"uint256"],"name":"Transfer","type":"event","anonymous":false,"inputs":[],"name":"Pause","type":"event","anonymous":false,"inputs":[],"name":"Unpause","type":"event"]'
ABI = json.loads(ABI)
second_account = "0x2ee7304bad7c1aef6292f1e70124e77370007924"
second_account = w3.toChecksumAddress(second_account)
ether_balance_second_account = w3.eth.get_balance(second_account)
print(f"ether balance for second_account is ether_balance_second_account")
gldd_contract_address = "0xe9814432a38b18d0730b9e0e277eab759b6019d7"
contract_address = w3.toChecksumAddress(gldd_contract_address)
gldd_goerli_contract = w3.eth.contract(contract_address, abi=ABI)
contract_name = gldd_goerli_contract.functions.name().call()
print(f"Contract name is contract_name")
contract_symbol = gldd_goerli_contract.functions.symbol().call()
print(f"Contract symbol is contract_symbol")
decimals = gldd_goerli_contract.functions.decimals().call()
DECIMALS = 10 ** decimals
# total_supply = gldd_goerli_contract.functions.totalsupply().call()
# print(f"Total supply total_supply")
first_account_gldd_balance = gldd_goerli_contract.functions.balanceOf(first_account).call()
print(f"First account GLDD balance first_account_gldd_balance")
second_account_gldd_balance = gldd_goerli_contract.functions.balanceOf(second_account).call()
print(f"Second account GLDD balance second_account_gldd_balance")
# print("Trying to send GLDD the first way")
# transaction =
# 'from': first_account,
# 'to': second_account,
# 'nonce': w3.eth.getTransactionCount(Web3.toChecksumAddress(first_account)),
# 'gas': 1000000,
# "gasPrice": w3.eth.gas_price,
# 'data' : gldd_goerli_contract.caller.transfer(Web3.toChecksumAddress(second_account), 100),
#
# tx_hash = w3.eth.send_transaction(transaction)
# tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
# print(tx_receipt)
print("Trying to send GLDD the second way")
tx_hash = gldd_goerli_contract.functions.transfer(second_account, 1000).transact('from': first_account)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(tx_receipt)
first_account_gldd_balance = gldd_goerli_contract.functions.balanceOf(first_account).call()
print(f"First account GLDD balance first_account_gldd_balance")
second_account_gldd_balance = gldd_goerli_contract.functions.balanceOf(second_account).call()
print(f"Second account GLDD balance second_account_gldd_balance")
现在,如果我为第一笔交易发表评论
# print("Trying to send GLDD the first way")
# transaction =
# 'from': first_account,
# 'to': second_account,
# 'nonce': w3.eth.getTransactionCount(Web3.toChecksumAddress(first_account)),
# 'gas': 1000000,
# "gasPrice": w3.eth.gas_price,
# 'data' : gldd_goerli_contract.caller.transfer(Web3.toChecksumAddress(second_account), 100),
#
# tx_hash = w3.eth.send_transaction(transaction)
# tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
# print(tx_receipt)
事务似乎因错误web3.exceptions.ContractLogicError: execution reverted: ERC20: transfer from the zero address
而失败。
有谁知道这里发生了什么?我想知道这个错误背后的原因。
【问题讨论】:
【参考方案1】:我刚刚发现错误,您需要将第一笔交易记录如下
print("Trying to send GLDD the first way")
transaction =
'from': first_account,
'to': second_account,
# 'nonce': w3.eth.getTransactionCount(Web3.toChecksumAddress(first_account)),
'gas': 2000000,
'gasPrice': w3.eth.gas_price,
'value': "0x0",
'data' : gldd_goerli_contract.functions.transfer(second_account, 1000).transact('from': first_account),
tx_hash = w3.eth.send_transaction(transaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(tx_receipt)
【讨论】:
以上是关于转账ERC20代币失败:web3.exceptions.ContractLogicError:执行恢复:ERC20:从零地址转账的主要内容,如果未能解决你的问题,请参考以下文章