Ethernaut 1
level 1 Fallback
fallback 함수는 이름이 없는 함수로, contract에 트랜잭션을 보냈는데 함수 호출을 하지 않았을 때 작동한다. receive함수는 fallback 함수인데 msg.data 값이 비어있는 경우 처리한다. 즉 별다른 요청 없이 이더를 송금했을 때 작동하는 함수이다.
// 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;
}
}
위 컨트랙트는 돈을 보내 [contributions] balance에 값이 owner보다 커지게 되면 owener 자리를 뺏는다. 하지만 한번 보낼 때 마다 0.001 ether 보다 작게 보내야 하기 때문에 정상적인 방법으론 힘들다고 볼 수 있다. 위에서 설명한 receive 함수를 이용해 owner 자리를 뺏어야 한다.
사실 1번 문제는 코드를 읽고 콘솔에서 트랜잭션 좀 보내는 문제이다. 다만 transaction을 보낼 때 생으로 입력하게 되면 귀찮으니(data에 함수 이름 해시 값을 추가 해야 함)
await contract.contribute.sendTransaction 이런 식으로 사용해주면 좋다.
또한 toWei 함수에 값을 적을 때 스트링 형태로 안 넣어주면 에러가 뜬다.
값이 좀 특이하게 들어가는데 이유는 모른다. 하하
추측 상으론 wei 단위로 들어가는데 16진수라던가(계산해보니 아닌듯)
여튼 이제 돈을 보내고
이 컨트랙트는 이제 제껍니다.
p.s 푼돈일지라도 withdraw로 내돈 찾는게 좋을지도
Author And Source
이 문제에 관하여(Ethernaut 1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@k2822795/Ethernaut-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)