智能合约可以将以太币转移到一个地址,但该地址的余额不会更新

Smart Contract could transfer ether to an address, but the balance of that address does not update

我正在尝试让我的智能合约将其所有余额转移到另一个地址。传输线没有抛出任何错误,但之后合约余额没有改变。

我正在使用带有 ganache 的 web3js 来测试这个功能:

我的合同:

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.12;

contract Lottery {
    address payable public manager;
    address payable[] public players;

    constructor() {
        manager = payable(msg.sender);
    }

    function enterLottery() public payable {
        require(msg.value >= .01 ether);
        players.push(payable(msg.sender));
    }

    function getPlayers() public view returns (address payable[] memory) {
        return players;
    }

    function random() public view returns (uint256) {
        return
            uint256(
                keccak256(
                    abi.encodePacked(block.difficulty, block.timestamp, players)
                )
            );
    }

    function pickWinner() public { // this transfer contract balance to the account
        uint256 index = random() % players.length;
        players[index].transfer(address(this).balance);
    }
}

我的测试用例:

beforeEach(async () => {
    accounts = await web3.eth.getAccounts();
    contract = await new web3.eth.Contract(abi)
        .deploy({ data: evm.bytecode.object })
        .send({ from: accounts[0], gas: "1000000" })
})

describe("Lottery", () => {
    it("Contract has an address? ", () => {
        assert.ok(contract.options.address)
    })

    it("Prize pool can receive ether", async () => { 
        await contract.methods.enterLottery().send({ from: accounts[1], gas: "1000000", value: "10000000000000000" });
        const contractBalance = await web3.eth.getBalance(contract.options.address)

        const hasContractReceivedEntry = contractBalance === "10000000000000000";
        assert.equal(hasContractReceivedEntry, true)
    })

    it("Winner can receive the prize pool", async () => {
        await contract.methods.enterLottery().send({ from: accounts[1], gas: "1000000", value: "10000000000000000" });
        await contract.methods.pickWinner().call();

        const contractBalance = await web3.eth.getBalance(contract.options.address)

        console.log(contractBalance) // the contract balance should be 0 after the pickWinner call, but it is still 10000000000000000 wei the enterLottery function gave
    })
})

编辑:确认智能合约可以运行 enterLottery 和 random() 按预期

await contract.methods.pickWinner().call();

在这一行中,您正在调用一个 read-only 调用 ,它不会更新合同状态。您需要使用 .send() 函数 发送交易 - 就像上一行一样。