초능력을 사용하여 10번 연속으로 정답을 맞춰라
pragma solidity ^0.8.0;
contract CoinFlip {
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor() {
consecutiveWins = 0;
}
function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number - 1));
if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;
if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}
Attack이라는 이름의 컨트랙트의 attack 함수를 호출하면 코인 뒤집기 결과를 계산하여 함수 내부에서 CoinFlip 컨트랙트의 flip 함수를 호출한다고 가정하자

이렇게 호출된 함수는 하나의 Transaction에 담기게 되고

이 Transaction은 하나의 Block에 담기게 된다

하나의 블록 안에있는 트랜잭션에서 함수 호출이 처리되었다는 것은 곧 attack 함수에서 불러온 block.number와 flip 함수에서 불러온 block.number의 값이 동일하다는 것을 의미한다.

즉, 이를 이용하면 CoinFlip의 block.number와 같은 block.number를 추출하고 이를 활용할 수 있게된다.