pragma solidity ^0.4.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund {
/// Mapping of ether shares of the contract.
mapping(address => uint) shares;
/// Withdraw your share.
function withdraw() public {
if (msg.sender.call.value(shares[msg.sender])())
shares[msg.sender] = 0;
}
}
6번 라인의 msg.sender.call.value(x)()는 x만큼 msg.sender에게 이더를 보내고 남은 가스를 넘겨줍니다. 만약 msg.sender가 악의적으로 작성된 스마트 컨트랙트일 경우 withdraw()를 다시 호출하는 re-entracy 공격을 할 수 있는데, 이 경우 코드에 따르면 msg.sender에게 계속 이더를 보내게 되고, 가스가 부족해지거나 Fund에 잔고가 다 떨어졌다고 판단되면 더 이상 withdraw()를 호출하지 않고 정상 종료하여 트랜잭션을 성공시킬 수 있습니다. 360만 이더가 탈취된 DAO 해킹이 이 취약점이 공격된 사례입니다.
pragma solidity ^0.4.16;
contract Ballot {
struct Proposal {
bytes32 name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
}
// A dynamically-sized array of `Proposal` structs.
Proposal[] public proposals;
/// Create a new ballot to choose one of `proposalNames`.
function Ballot(bytes32[] proposalNames) public {
for (uint i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
function winningProposal() public view
returns (uint winningProposal)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal = p;
}
}
}
}
두 번째는 Solidity 공식 문서의 Ballot 예제를 일부 따왔습니다. 코드 전체를 이해할 필요는 없고, 동적 길이의 배열과 그 배열 크기만큼 반복하는 for문에 대한 얘기입니다. winningProposal()이 view function 이여서 적합한 예제는 아니지만, 어느 정도 상상력을 가지고 보시면 되겠습니다. 누군가 ProposalNames를 길게 하여 여러번 Ballot을 호출했다고 가정해봅시다. 그 다음 winningProposal()을 호출하면 상당히 긴 for문을 돌아야 할 지도 모릅니다. 이 때 문제는 proposals의 길이를 줄일 수 있는 코드가 없고, 이미 길어진 proposals를 처리하는데 들어가는 가스가 블록 가스 제한을 넘어버리면, winningProposal()은 더 이상 호출할 수 없는 코드가 되어버립니다. DoS 공격이 가능해지는 것이지요.
'스마트 컨트랙트 개념 소개' 카테고리의 다른 글
Truffle로 구성하는 빠른 Solidity 개발 시작 가이드 (1) | 2018.04.15 |
---|---|
이더리움에서의 랜덤 구현 (0) | 2018.01.30 |
Solidity 프로그래밍 (3) - 이더리움 토큰의 구현 (1) | 2017.12.27 |
Solidity 프로그래밍 (2) - 이벤트와 블룸 필터 (0) | 2017.12.14 |
Solidity 프로그래밍 (1) - 스마트 컨트랙트 생성 및 함수 호출 (0) | 2017.12.10 |
스마트 컨트랙트 프로그래밍 소개 - 프롤로그 (0) | 2017.11.30 |