1

所以我尝试使用转账功能与 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。有谁知道这里发生了什么?我想知道这个错误背后的原因。

4

1 回答 1

-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)
于 2021-05-16T23:42:21.193 回答