Solidity

驗證兩個地址變數之間的相等性

  • February 21, 2020

我正在重新混合中測試我的 Connect4 合約中的 challengeOpponent 函式。該函式創建一個新的 Escrow 合約實例,以便遊戲中的每個玩家都有一個地方存放他們的資金,直到有人獲勝。我只希望 Connect4 合約呼叫它創建的所有 Escrow 合約實例,以便包括玩家在內的任何人都無法直接訪問託管。

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

**我的問題:**在創建的託管的 placeAnte 函式的驗證器中發生還原(require(player == player1 || player == player2, “invalid player address.”);)以下是混音中顯示的確切錯誤:

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.".

我已經嘗試將 challengeOpponent 中的第 2 行和第 3 行更改為

Escrow escrow = new Escrow(address(msg.sender), opponent, address(this), anteAmount);
escrow.placeAnte(address(msg.sender));

但同樣的恢復發生了。我如何要求在託管中“下注”的玩家的地址等於 player1 或 player2?

**相關問題:**當我在 Escrow 合約中的 placeAnte 函式中添加“onlyConnect4()”時,當我測試challengeOpponent 時,出現以下錯誤:

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. 

如何正確驗證兩個地址變數之間的相等性?

也許您在 Escrow 合約的建構子中的狀態和局部變數被彼此遮蔽並導致問題。你能試試下面的程式碼嗎?

contract Escrow {
   address game;
   address player1;
   address player2;

   Escrow addr = Escrow(this);
   address payable escrowWallet = address(uint160(address(addr)));

   constructor(address _player1, address _player2, address _game) public {
       player1 = _player1;
       player2 = _player2;
       game = _game;
   }
}

引用自:https://ethereum.stackexchange.com/questions/79997