강의 5 : 스마트 계약을 보호하는 방법 (2 부)

이더 리움 개발 101 : 강의 5 : 산술 오버플로 및 언더 플로에 대한 스마트 계약 보호

선행 조건 : 이 문서는 교육을 위해 고안된 과정 인 Ethereum Development 101 의 일부입니다. 이더 리움 네트워크에서 스마트 계약을 개발, 테스트 및 배포하는 기본 개념

학습 목표 : 이 강의가 끝나면 Solidity 스마트 계약의 산술 오버플로 및 언더 플로 취약성을 이해할 수 있어야합니다. 이를 방지하는 코드를 작성할 수 있어야합니다.

무엇입니까?

산술 오버플로 및 언더 플로를 이해하려면 먼저 표시되는 데이터 유형을 이해해야합니다.

이더 리움 가상 머신 (EVM) 정수는 항상 고정 된 크기입니다. 예를 들어 unit8 은 0과 255 사이의 값만 저장할 수 있습니다. 값 256을 uint8 변수에 저장하려고하면 값이 0이됩니다. 실행 전에 확인하지 않으면 악용 될 수 있습니다.

언더 플로

언더 플로는 정수에서 값을 빼면 해당 정수의 현재 값이 빼는 값보다 작을 때 나타날 수 있습니다. 예 :

여기서 result 변수는 우리가 생각하는대로 -1과 같지 않습니다. result 는 255와 같습니다.

2에서 거꾸로 세면 EVM은 1… 0… 255가됩니다.이를 언더 플로

라고합니다.

오버플로

오버플로는 언더 플로의 반대입니다. 값이 정수 변수에 추가되면 결과가 해당 변수 데이터 유형의 최대 한계보다 큰 경우 나타날 수 있습니다. 예 :

여기서 result 변수는 우리가 생각하는 257과 같지 않습니다. 255가 uint8 의 최대 값이기 때문에 1로 계산됩니다.

254에서 위로 세면 EVM은… 255… 0… 1. 이것은 오버플로

로 알려져 있습니다.

솔리 디티 코드를 고려하여 설명으로 이동하기 전에 문제를 발견 할 수 있습니까?

require 문은 발신자에서 출금 금액을 뺀 잔액이 0보다 크거나 같아야합니다. 이는 누구에게도 더 이상 출금하는 것을 허용하지 않기 때문에 논리적으로 의미가 있습니다. 균형에있는 것보다. 그러나 이것은 언더 플로 악용에 취약합니다.

공격자가 계약에 2 개의 Ether를 저장하고 10 개를 인출하려고 시도한 경우 require 문이이를 허용합니다. 뺄셈으로 인해 balances [msg.sender] — _value 의 결과가 최대 값까지 언더 플로되어 0보다 크거나 같기 때문입니다. 정수가 서명되지 않았기 때문에 msg.sender 에 잔액이있는 한 require 문은 항상 전달됩니다.

이 논리에 따라 언제든지 잔액을 예치 한 누구나 자금 계약을 완전히 헹굴 수 있습니다.

예방 조치

기본 산술을 수행하기 위해 항상 안전한 기능을 제공하는 라이브러리를 사용하십시오. OpenZeppelin의 SafeMath 라이브러리는 Solidity 커뮤니티에서 가장 일반적으로 사용됩니다. 덧셈, 뺄셈, 곱셈, 나눗셈 및 계수를위한 기능을 제공합니다.

라이브러리는 릴리스되기 전에 커뮤니티에서 철저히 조사하므로 산술 논리 버그를 방지 할 수있는 능력에 확신을 가질 수 있습니다. 다음은 스마트 계약에서 마이너스 산술 연산자를 사용하는 대신 SafeMath의 sub () 함수를 사용하는 방법의 예입니다.

이 시나리오에서 잔액보다 많은 금액을 인출하려고하면 require 문이 실패합니다. 이는 sub () 함수에서 잔액이 _value 보다 크거나 같아야하기 때문입니다.

아래 댓글에 질문을 추가해주세요. 이 강의를 마치면 다음 강의로 바로 이동하세요.

또는 Ethereum Development 101 과정 페이지로 돌아가서 다른 강의를 선택하세요.