I'm testing the challengeOpponent function in my Connect4 contract in remix. The function creates a new Escrow contract instance so that each player in the game has a place to hold their funds until someone wins. I only want the Connect4 contract to make calls to all Escrow contract instances it creates so that no one, including the players, has direct access to the escrows.
contract Escrow {
// required ante amount for each player
uint256 public anteAmount;
// connect4
address connect4;
// player 1
address player1;
// player 2
address player2;
// has each player anted
mapping(address => bool) anted;
// winner
address payable winner;
constructor(address player1, address player2, address connect4, uint256 anteAmount) public {
player1 = player1;
player2 = player2;
connect4 = connect4;
anteAmount = anteAmount;
}
modifier onlyConnect4() {
require(address(msg.sender) == connect4, "Forbidden Access.");
_;
}
function () external payable onlyConnect4 {
}
function placeAnte(address player) payable public returns (bool) {
require(anted[player] == false, "player has already placed ante.");
require(player == player1 || player == player2, "invalid player address.");
require(msg.value == anteAmount, "ante unequal to required ante amount.");
address(this).transfer(msg.value);
anted[player] = true;
return true;
}
...
}
contract Connect4 {
event LogConstructorInitiated(string nextStep);
event announceWinner(string winStatement);
uint[] rows;
uint[] columns;
uint[][][] slopes4;
uint[][][] slopes5;
uint[][][] slopes6;
constructor() public {
emit LogConstructorInitiated("Constructor was initiated");
rows = [1,2,3,4,5,6,7];
columns = [1,2,3,4,5,6];
slopes4 = [[[1,3],[2,4],[3,5],[4,6]], [[1,4],[2,3],[3,2],[4,1]], [[4,6],[5,5],[6,4],[7,3]]];
slopes5 = [[[1,2],[2,3],[3,4],[4,5],[5,6]],[[3,1],[4,2],[5,3],[6,4],[7,5]],[[1,5],[2,4],[3,3],[4,2],[5,1]],[[3,6],[4,5],[5,4],[6,3],[7,2]]];
slopes6 = [[[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]],[[2,1],[3,2],[4,3],[5,4],[6,5],[7,6]],[[1,6],[2,5],[3,4],[4,3],[5,2],[6,1]],[[2,6],[3,5],[4,4],[5,3],[6,2],[7,1]]];
numGames = 0;
}
uint256 numGames;
Game[] games;
struct Board {
mapping(string => uint) state;
uint[] rows;
uint[] columns;
uint[][][] slopes4;
uint[][][] slopes5;
uint[][][] slopes6;
}
struct Game {
Escrow escrow;
address winner;
uint playersTurn;
address[2] players;
uint256 challengeDate;
uint256 acceptChallengeMaxTime;
bool challengeAccepted;
uint256 maxStallTime;
uint256 lastMoveTime;
uint256 anteAmount;
Board board;
bool isValid;
mapping(uint => bool) tieGameApproval;
}
function challengeOpponent(address opponent, uint playersTurn, uint256 anteAmount, uint256 acceptChallengeMaxTime, uint256 maxStallTime) public payable returns (bool){
require(msg.value == anteAmount*10**18, "value must be equal to specified ante amount.");
Escrow escrow = new Escrow(msg.sender, opponent, address(this), anteAmount);
escrow.placeAnte(msg.sender);
address[2] memory players = [msg.sender, opponent];
address winner;
Board memory board = Board({rows: rows, columns: columns, slopes4: slopes4, slopes5: slopes5, slopes6: slopes6});
Game memory game = Game({escrow: escrow, winner: winner, playersTurn: playersTurn, players: players,
acceptChallengeMaxTime: acceptChallengeMaxTime, challengeDate: now, lastMoveTime: now,
challengeAccepted: false, maxStallTime: maxStallTime, anteAmount: anteAmount, board: board, isValid: true});
games.push(game);
numGames++;
return true;
}...
My problem: A revert occurs in the created escrow's placeAnte function's validator (require(player == player1 || player == player2, "invalid player address.");) Below is the exact error that showed in remix:
transact to Connect4.challengeOpponent errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Reason provided by the contract: "invalid player address.".
I've already tried changing the 2nd and 3rd lines in challengeOpponent to
Escrow escrow = new Escrow(address(msg.sender), opponent, address(this), anteAmount);
escrow.placeAnte(address(msg.sender));
but the same revert happened. How do I require that the player "placing the ante" in the escrow has an address equal to either player1 or player2?
Related problem: when I add "onlyConnect4()" to the placeAnte function in the Escrow contract, when I test challengeOpponent, I get the following error:
transact to Connect4.challengeOpponent errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Reason provided by the contract: "Forbidden Access.". Debug the transaction to get more information.
How do I correctly validate the equality between two address variables?