스크립토 6기 하진원입니다.
스크립토 방학 스터디로 마스터링 이더리움 공부하고 있습니다.
단순성은 버그와 의도치 못한 결과와 반비례한다. 따라서 버그를 줄이기 위해 최대한 코드의 줄 수를 줄이는 노력을 해야 한다.
만들어져있는 라이브러리와 스마트 컨트랙트를 재사용하는 것이 좋다. 많이 사용되고 검증된 코드는 새로 작성한 코드보다 안전하기 때문에 새로 작성할 필요가 없다.
스마트 컨트랙트에서 버그는 금전적 손실을 발생시키기 때문에 실수에 대한 비용이 크게 발생된다. 따라서 코드가 배포되기 전에 문제가 없다는 것을 확실시 해야 한다.
코드는 가독성이 뛰어나야 한다. 가독성이 뛰어나다면 다른 사람이 검증해주기도 쉬우며 감사받기도 편하고 협업을 하는데도 좋다.
할 수 있는 모든 경우를 테스트하여 버그를 방지하는 것이 필요하다.
예를 들면 함수에서 입력 인수에 대한 테스트
컨트랙트는 외부 코드를 호출하여 활용하거나 외부 사용자 주소로 이더를 전송하는 경우가 잦다. 이런 작업들을 위해 컨트랙트는 외부 호출을 요청하는데 공격자가 이를 콜백함수를 사용해 악용한 것이 재진입성 공격이다. 재진입이라는 용어는 외부의 해커가 호출하여 해킹이 발생되는 것이 아닌
컨트랙트가 알 수 없는 주소로 이더를 전송하는 경우 공격자는 폴백함수에 악성코드를 가지고 있는 컨트랙트를 외부 주소에 만들어 해 주소에 이더가 보내지면 악의적인 코드가 호출되게 할 수 있다.
이더를 외부의 컨트랙트에 보낼 때 transfer 함수 사용하기.
transfer 함수는 외부 호출에 가스를 2300으로 제한하여 목적지 주소/컨트랙트가 다른 컨트랙트를 호출하는 것을 막는다.
이더를 전송하기 전에 상태 변수를 변경하는 로직이 발생하게 하는 것. 즉, 외부 호출을 수행하는 코드를 가장 마지막에 두는것
뮤텍스(mutex) 도입하기. 코드 실행 중에 컨트랙트를 잠그는 상태 변수를 추가하여 재진입을 방지하는 것. 뮤텍스 변수가 잠겨있으면 컨트랙트가 실행되지 않게 하는 방법이다.
데이터 타입을 벗어나는 숫자를 고정 크기 변수에 저장해야 하는 연산이 수행되면 발생한다.
이더가 컨트랙트에 전달될 때는 폴백 함수나 컨트랙트에 정의된 함수를 실행해야 한다.
이에 대한 예외는 어떤코드를 샐행하지 않고 컨트랙트 내에 이더가 존재할 수 있는 경우이다.
일반적으로 payable을 통해서만 이더 교환이 가능하다고 생각을 한다. 하지만 payable 함수와 컨트랙트에서 코드를 실행하지 않고 컨트랙트에 이더를 보내는 방법이 두가지 있고 그것이 자기파괴(selfdestruct)와 미리 보내진 이더(pre-sent ether)이다.
this.balance에 근거하지 않은, 별도의 상태 변수를 만들어 정확한 입금 이더를 추적해야 한다.
CALL과 DELEGATECALL은 개발자가 코드를 모듈화하는데 유용하다.
컨트랙트에 대한 외부 메시지 호출은 CALL에 의해 처리되고 코드가 외부 컨트랙트/함수의 컨텍스트에서 실행된다.
DELEGATECALL은 CALL과 유사하고 코드가 호출한 컨트랙트에서 실행된다.
또, msg.sender와 msg.value는 변하지 않고 이를 통해 라이브러리를 구현할 수 있다.
다만, DELEGATECALL은 예기치 않은 코드를 실행할 위험이 있다.
DELEGATECALL는 컨텍스트를 보존하기 때문에 안전한 사용자 지정 라이브러리를 구축하는 것은 쉽지 않다.
라이브러리에 문제가 없더라도 특정한 컨텍스트에서 취약점이 발생할 수 있다.
솔리디티는 가시성 지정자가 있는데 이는 함수의 호출 방법을 지정할 수 있다.
가시성은 사용자가 함수를 외부에서 호출할 수 있는지 여부와 다른 컨트랙트가 함수를 내부에서, 외부에서 호출할 수 있는지 여부를 결정한다.
기본 가시성은 public으로 사용자가 외부에서 호출할 수 잇다.
기본 가시성이 public인데 개발자가 private으로 함수의 가시성을 지정하지 않아 생기는 문제이다.
가시성을 의도적으로 항상 지정하는 것이 좋다.
이더리움 블록체인의 트랜잭션은 결정론적인 연산이기 때문에 엔트로피, 즉 무작위성이 없다.
이더리움 블록체인 플랫폼을 기반으로 만든 컨트랙트 중 일부분은 도박을 구현하려 하였다.
여기서 일반적으로 무작위 값을 구현하기 위해 값이 알려지지 않은 트랜잭션에 관련된 변수를 사용하는 방법을 사용하였다. 그렇지만 이는 채굴자가 통제가능하기 때문에 무작위한 방법이 아니다.
엔트로피의 원천은 블록체인 외부에 있어야 한다.
이더리움은 코드를 재사용하고 네트워크에 배포된 컨트랙트를 참고할 수 있는 장점이 있어 외부 메시지 호출을 통해 참고한다.
참고(캐스팅) 할 때 주소의 코드의 진위 여부에 상관없이 가져오기 때문에 악의적 공격자가 주소에 악의적인 코드를 삽입한다면 문제가 생긴다.
권한 있는 사용자가 컨트랙트 라이브러리를 변경할 수 있으면 다른 사용자가 모르는 사이 임의의 코드를 실행할 수 있다, 즉 악의적 의도를 가진 코드를 실행할 수 있다.