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