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

I am trying to get my smart contract to transfer all its balance to another address. The transfer line doesn’t throw any errors but the balance of contract does not change afterwards.

I am using web3js with ganache to test this function:

My contract:

// 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);
    }
}

My test case:

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
    })
})

Edit: It is confirmed that the smart contract can run enterLottery and random() as intended

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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

On this line, you’re invoking a read-only call that doesn’t update the contract state. You need to send a transaction using the .send() function – just like on the previous line.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x