Obtuve el siguiente código de este tutorial:
pragma solidity ^0.4.11;
contract Casino {
uint minimumBet;
uint totalBet;
uint numberOfBets;
uint maximumAmountsOfBets = 100;
address[] players;
struct Player {
uint amountBet;
uint numberSelected;
}
mapping(address => Player) playerInfo;
address owner; // Long string from metamask
function Casino(uint _minimumBet) public{ // Constructor : has the same name as the contract , used to set up
//contract owner
owner = msg.sender;
if(_minimumBet !=0) minimumBet = _minimumBet;
}
//To be for a number btw 1 & 10 both inclusive
function bet(uint number) payable public {
require(checkPlayerExists(msg.sender) );
require(number >= 1 && number <= 10);
require(msg.value >= minimumBet);
playerInfo[msg.sender].amountBet = msg.value;
playerInfo[msg.sender].numberSelected = number;
numberOfBets += 1;
players.push(msg.sender);
totalBet += msg.value;
if(numberOfBets >= maximumAmountsOfBets) generateNumberWinner();
}
function checkPlayerExists(address player) public view returns(bool) {
for( uint i = 0 ; i < players.length; i++){
if(players[i] == player) return true;
}
return false;
}
/*
Generate Winner : Generates a number between 1 & 10
*/
function generateNumberWinner() public{
uint numberGenerated = block.number % 10 + 1; // This isnt secure
distributePrizes(numberGenerated);
}
/*
Distribute Prizes : Sends the correspondng ether to each winner
depending on the total bets
*/
function distributePrizes(uint numberWinner) public {
address[100] memory winners ; // We have to create a temporary in memory array with fixed size
uint count = 0; // This is the count for the array of winners
for(uint i = 0; i < players.length ; i++) {
address playerAddress = players[i];
if(playerInfo[playerAddress].numberSelected == numberWinner){
winners[count] = playerAddress;
count ++;
}
delete playerInfo[playerAddress]; // Delete all the players array
}
players.length = 0; //Delete all the players array
uint winnerEtherAmount = totalBet / winners.length; // How much each player gets
for(uint j = 0; j < count; j++) {
if(winners[j] !=address(0)) // Check the address in the fixed array is not empty
winners[j].transfer(winnerEtherAmount);
}
}
/*
Annonymous Fallback function: In case someone sends ether to the
contract so it doesnt get lost
*/
function() payable private{}
/*
Kill function: Used to destroy contract whenever we want. Only owner
has the ability to kill the contract
*/
function kill() private{
if(msg.sender == owner)
selfdestruct(owner);
}
}
Compila bien, pero cuando bet
lo intento, REMIX arroja el siguiente error:
transacción a Casino.bet con error: El gas requerido excedió los límites: 3000000. Una estimación de gas importante también puede ser un signo de un problema en el código del contrato. Verifique los bucles y asegúrese de no enviar valor a una función no pagadera (esa también es una razón para una estimación de gas fuerte).
Agradecería que alguien pudiera indicarme la dirección correcta.
Creo que esta línea:
require(checkPlayerExists(msg.sender));
en realidad debería decir lo contrario:
require(!checkPlayerExists(msg.sender));
Es posible que el jugador no exista la primera vez que llama bet
, por lo que require
está abortando la transacción.
Asumiendo que estás siguiendo https://medium.com/@merunasgrincalaitis/the-ultimate-end-to-end-tutorial-to-create-and-deploy-a-fully-descentralized-dapp-in-ethereum-18f0cf6d7e0e , tenga en cuenta que tienen esta línea, que es más o menos equivalente a lo que sugerí. (Pero creo que require
es más apropiado aquí que assert
.)
assert(checkPlayerExists(msg.sender) == false);
require(checkPlayerExists(msg.sender) == false);
miniumbet
) porque no cuestan nada. Sin embargo, cuando se implementa el contrato, las constantes no se muestran en el panel de la derecha (es decir, se tratan como una función privada)
usuario19510