Published 2022. 6. 3. 21:23

CoinFlip

완전한 랜덤을 구하는 법은 없으며 직접 구현하려 하지 말고 널리사용되고 있는 랜덤 생성 방법을 사용할 것.

Telephone

tx.origin은 트랜젝션을 시작한 사람의 주소가 담겨있음.

msg.sender에는 함수를 call 한 주소가 담겨있음.

function transfer(address _to, uint _value) {
  tokens[tx.origin] -= _value;
  tokens[_to] += _value;
}

이런식으로 transfer를 구현하는 경우 피싱 컨트랙트를 만들 수 있음.

function () payable {
  token.transfer(attackerAddress, 10000);
}

이런 형태의 피싱 컨트랙트를 공격자가 만들고 해당 컨트랙트로 입금을 하도록 유도한다면, 피해자가 입금을 수행하기 때문에 피해자의 address가 tx.origin이 되므로 공격자가 transer 를 요청하는 경우 피해자의 주소의 토큰이 공격자에게 전송된다.

만약 msg.sender를 사용했다면 악성 컨트랙트의 주소가 들어가서 피해자의 토큰에 접근할 수 없었을 것이다.

Force

selfdestruct(address)를 통해 address로 강제로 이더를 보낼 수 있다.

해당 방법은 막을 수 없기때문에 address(this).balance == 0 와 같은 로직을 사용해서는 안된다. 

Valut

web3.eth.getStorageAt(address, index)로 컨트랙트의 private variable을 읽을 수 있다. 블록체인 상에선 private로 선언된 값을 읽을 수 없지만 체인밖에서는 읽을 수 있다는 점을 알아두어야한다.

King

transfer 가 실패할 수 있다는 사실을 알아야 한다.

Preservation

delegateCall은 변수의 이름을 알지 못한다. 따라서 storage 인덱스를 보고 변수를 수정한다. delegateCall이 caller의 변수를 수정하는 경우 변수의 선언을 똑같이 해주어야 한다.

Denial

call은 gasLimit을 직접 정해주어야 한다. 그렇지 않으면 사용가능한 가스의 대부분을 사용할 수도 있다.

Shop

view 가 붙은 함수는 state를 변경할 수 없다. const와 혼동하지 말자. 항상 같은 값이 나오는 것이 아니다.

복사했습니다!