Skip to main content
Source Link

Why is my account balance after executing the contract so different?

I'm writing a test for a Lottery contract:

var Lottery = artifacts.require("./Lottery.sol");

contract('Lottery', function (accounts) {
    var ACC_FABIAN = accounts[0];
    var ACC_RENE = accounts[1];
    var ACC_OTHER = accounts[2];
    var TICKET_PRICE = 1;

    var balance_before = web3.eth.getBalance(ACC_FABIAN).toString(10);

    var lotteryFn = Lottery.deployed();

    it('should buy a ticket for one user', function () {
        var meta;
        return lotteryFn.then(function (instance) {
            meta = instance;
            return instance.buyTicket(200, {from: ACC_FABIAN, value: TICKET_PRICE});
        }).then(function () {
            var buyingTimeFactor;
            meta.calculateBuyingTimeScore.call().then(function (btf) {
                buyingTimeFactor = btf.toNumber();
            });
            // ESTIMATION
            meta.getEstimation.call(ACC_FABIAN).then(function (estimation) {
                assert.equal(estimation.toNumber(), 200, "Estimations are different");
            });
            // BUYING TIME
            meta.getBuyingTime.call(ACC_FABIAN).then(function (buyingTime) {
                assert.equal(buyingTime.toNumber(), buyingTimeFactor, "Buying time not correct");
            });

            // PAYOUT
            meta.payout(200).then(function (response) {
                var balance_now = web3.eth.getBalance(ACC_FABIAN);
                console.log(web3.fromWei(balance_before, 'ether').toString(), web3.fromWei(balance_now, 'ether').toString());
            });
        });
    });
});

As you can see, I'm checking the account balance before and after the contract. The console.log gives me something like this:

97.0711255 97.0326134

This is a difference of 0.0385121 ETH

Where is this coming from?

Even with a TICKET_PRICE of 0 I get this difference. Is the gas so expensive?


The contract:

contract Lottery {

    // CONSTANTS
    int constant LOTTERY_INTERVAL = 1 days;

    uint256 constant private TICKET_PRICE = 1;

    uint constant FEE_FACTOR = 200; // 0.5 %

    // VARIABLES
    uint256 totalBalance = 0;

    uint totalParticipants = 0;

    uint winnerCounter = 0;

    // Structs
    struct TicketHolder {
    address ticketHolder;
    uint estimation;
    uint buyingTimeScore;
    uint timestamp;
    uint score;
    }

    // Mappings
    mapping (address => TicketHolder) ticketHolders;

    mapping (uint => TicketHolder) ticketHoldersIndex;

    // Arrays
    address[] ticketHoldersAddress;

    address [] winners;

    // Constructor
    function Lottery(){

    }

    //Getters setters
    function getBuyingTime(address ticketHolder) /*internal*/ returns (uint){
        return ticketHolders[ticketHolder].buyingTimeScore;
    }


    function getEstimation(address ticketHolder) /*internal*/ returns (uint){
        return ticketHolders[ticketHolder].estimation;
    }

    function getScore(address ticketHolder) /*internal*/ returns (uint){
        return ticketHolders[ticketHolder].score;
    }


    function getMinute(uint timestamp) /*internal*/ constant returns (uint8) {
        return uint8((timestamp / 60) % 60);
    }

    function setScore(address ticketHolder, uint score) /*internal*/{
        ticketHolders[ticketHolder].score = score;
    }

    function calculateBuyingTimeScore() /*internal*/ returns (uint){
        uint timeBeforeNewRound = 60 - getMinute(now);
        return timeBeforeNewRound * 100 * 100 / 60;
    }

    function calculateDeviationScore(uint courseValue, uint estimatedValue) /*internal*/ returns (uint){
        uint difference = 0;
        if (courseValue >= estimatedValue) {
            difference = courseValue - estimatedValue;
        }
        else if (courseValue < estimatedValue) {
            difference = estimatedValue - courseValue;
        }

        // Calculated standard deviation
        uint deviation = (difference * 10000 / courseValue);
        uint score = 10000 - deviation;
        return score;
    }

    //TODO: add more conditions
    function buyTicket(uint estimation) payable {
        if (msg.value < TICKET_PRICE) throw;
        address ticketHolder = msg.sender;
        uint buyingTimeScore = calculateBuyingTimeScore();
        totalBalance += msg.value;
        ticketHolders[ticketHolder] = TicketHolder(msg.sender, estimation, buyingTimeScore, now, 0);
        ticketHoldersIndex[totalParticipants++] = TicketHolder(msg.sender, estimation, buyingTimeScore, now, 0);
        ticketHoldersAddress.push(ticketHolder);
    }

    function calculateScore(uint courseValue) /*internal*/ {
        if (totalParticipants == 0) throw;
        for (uint participant = 0; participant < totalParticipants; participant++) {
            TicketHolder ticketHolder = ticketHoldersIndex[participant];
            uint deviationScore = calculateDeviationScore(courseValue, ticketHolder.estimation) / 2;
            uint buyingTimeScore = ticketHolder.buyingTimeScore / 2;
            uint totalScore = deviationScore + buyingTimeScore;
            setScore(ticketHolder.ticketHolder, totalScore);
        }
    }

    function determineWinners() /*internal*/ returns (uint){
        uint highestScore = 0;
        for (uint participant = 0; participant < totalParticipants; participant++) {
            TicketHolder ticketHolder = ticketHoldersIndex[participant];
            uint score = ticketHolder.score;
            if (score >= highestScore) {
                winners.push(ticketHolder.ticketHolder);
                winnerCounter++;
                highestScore = score;
            }
        }
        return ticketHoldersAddress.length;
    }

    function payout(uint courseValue) /*internal*/ {
        if (totalParticipants == 0) throw;
        calculateScore(courseValue);
        determineWinners();
        uint256 winAmount = totalBalance / winnerCounter;
        for (uint i = 0; i < winnerCounter; i++) {
            address winnerTicket = winners[i];
            winnerTicket.transfer(winAmount);
        }
    }

}