1

我试图以两种不同的方式读取几个以太坊测试账户的余额并得到两个不同的答案,但不是针对所有账户。更具体地说,我正在使用 Ganache 建立一个测试以太坊网络,并使用连接到测试网络的 Remix 部署以下智能合约。默认情况下,第一个帐户用于部署事务。

pragma solidity ^0.6.0;

contract Test {
    
    function balanceOf(address addr) external view returns (uint) {
        return addr.balance;
    }
    
}

balanceOf在 Ganache 提供的帐户上调用 Remix 中的函数就像一个魅力。然后我使用最新的 Web3.py 库运行以下 Python 代码来调用balanceOf所有帐户的函数。

from web3 import Web3
import json

web3 = Web3(Web3.HTTPProvider('http://127.0.0.1:7545'))   # connecting to the Ganache Ethereum network

def toEther(balance):
    return web3.fromWei(balance, 'ether')

# connecting to the 'Test' contract
abi = json.loads('[ { "inputs": [ { "internalType": "address", "name": "addr", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" } ]')
contract_address = '0x3038871e10654B87858Be4952B26bd7607Cb0c8b'   # this will be different for you
contract = web3.eth.contract(abi=abi, address=contract_address)

# printing balances
for account in web3.eth.accounts: 
    print(f'balance of {account}:  {toEther(contract.functions.balanceOf(account).call())}  versus {toEther(web3.eth.getBalance(account))}')

如您所见,余额是通过两种方式计算的:

  1. 通过调用balanceOf产生第一个数字的合约函数,
  2. 通过调用web3.eth.getBalanceWeb3 的方法产生第二个数字。结果是这样的
balance of 0x76290BDDea6C156A7F364aBB952aE29D49C593bE:  180143885.09682616  versus 99.99799366
balance of 0x3BFCAC461d922e3b4504BB5fc59dA5546a767617:  100  versus 100
balance of 0xD2AA30E855eb3F9B64A14Bb1a4EE4C4Ad645dA58:  100  versus 100
...

如您所见,balanceOf合约的功能对第一个地址产生了错误的结果。该web3.eth.getBalance方法显示了正确的结果(100 - 用于部署的气体)。我在没有重新启动 Ganache 网络的情况下再次部署合约并得到以下结果(仍然调用第一次部署,但没关系):

balance of 0x76290BDDea6C156A7F364aBB952aE29D49C593bE:  180143885.0988325  versus 99.99598732
balance of 0x3BFCAC461d922e3b4504BB5fc59dA5546a767617:  100  versus 100
balance of 0xD2AA30E855eb3F9B64A14Bb1a4EE4C4Ad645dA58:  100  versus 100
...

如您所见,由于第二次部署交易,第一个值出人意料地上升了 gas 费(约 0.002),而第二个值下降了相同的数量,正如预期的那样。最后,我使用第二个帐户而不是第一个帐户再次部署了合同。同样,两个余额计算都给出了正确的结果,除了第一个帐户:

balance of 0x76290BDDea6C156A7F364aBB952aE29D49C593bE:  180143885.0988325  versus 99.99598732
balance of 0x3BFCAC461d922e3b4504BB5fc59dA5546a767617:  99.99799366  versus 99.99799366
balance of 0xD2AA30E855eb3F9B64A14Bb1a4EE4C4Ad645dA58:  100  versus 100

我是区块链技术的新手,我想知道是否有人可以向我解释balanceOf使用 Web3 的第一个帐户(仅!!!)的功能的奇怪行为。正如我所说,在 Remix 中调用函数总是给出正确的结果。

PS:这不是 Python 问题。我使用 Web3.js 库做了同样的观察。

4

0 回答 0