본문으로 바로가기

remix에서 solidity 디버깅하기

category 이더리움/DApp 프로그래밍 2018. 5. 22. 22:38

DApp 작성을 위해 많이 사용하는 Remix IDE에서 디버깅 하는 방법에 대해서 간단히 알아보겠습니다.

디버깅을 하기전에 먼저 EVM(Ethereum Virtual Machine)의 실행구조에 대해서 알아보겠습니다.




Program Counter

   - 프로그램 카운터는 다음 차례에 실행할 EVM 명령어의 위치를 가리킵니다.


Program

   - 프로그램 영역에는 EVM이 실행할 스마트 컨트랙트의 EVM 명령어 목록을 보관합니다.


Stack

   - 연산에 필요한 데이타를 저장하는 공간으로 32바이트 크기의 값들이 저장되며, 최대 2014개가 저장될수 있습니다.  


Storage

   - 블록체인에 영구적으로 기록하기 위한 저장공간으로 스토리지의 구조는 키/값을 매핑하기위한 구조이며, 키/값은 모두 256비트 크기를 사용합니다. 이더리움의 모든 어카운트는 별도의 스토리지를 가지고 있으며, 다른 어카운트의 스토리지에 있는 데이타를 읽어오거다 값을 쓸수 없습니다.


Memory

   - 함수를 호출하거나 메모리 연산을 수행할때 임시로 사용되는 공간입니다. 데이타를 읽을때는 256비트 단위로 읽도록 제한되어 있지만, 쓸때는 8비트단위나 256비트 단위로도 가능합니다.


Log

   - 스마트 컨트랙트가 실행될때 부가적인 정보를 저장하기 위한 공간입니다. 


Call Data

   - 이더리움에 트랜잭션을 요청했을때 전송되는 데이타들이 저장되는 공간입니다.


remix ide에서 solidity을 하기위해서는 Environment는 "JavaScript VM"을 사용해야 합니다. 


다음의 코드를 remix ide에 입력하고 컴파일을 합니다.


pragma solidity ^0.4.0;
contract Debugging {
uint[] private vars;
function assignment() {
uint myVal1 = 1;
uint myVal2 = 2;
uint sum = myVal1 + myVal2;
assert(myVal1 == myVal2);
}
function memoryAlloc() {
string memory myString = "test";
assert(bytes(myString).length == 10);
}
function storageAlloc() {
vars.push(2);
vars.push(3);
assert(vars.length == 4);
}
}


Deploy를 실행하면 컨트랙트의 함수 3개를 확인할수 있습니다.

하기에서 Environment를 JavaScript VM으로 설정했는지를 확인합니다.



먼저 assignment를 선택하면 코드상에서 assert를 발생하도록 되어있기 때문에 에러가 발생되며, 로그에서 Debug를 선택하면 로칼변수와 스택을 확인할수 있습니다.

디버깅 아이콘을 사용하여 Step into, Step over 등으로 단계별 디버깅을 할수 있고, breakpoint를 설정하고, breakpoint 단위로 이동을 할수도 있습니다.

Instruction 에서는 현재 Program counter에서 실행되는 OPCODE를 확인할수 있습니다.



다음으로 memoryAlloc 함수를 선택한후 Debug를 선택하면 메모리 영역을 확인할수 있습니다. 

위에 EVM의 실행구조에서 설명한것처럼 메모리는 하기에 256비트 단위로 사용이 되고 있으며, 실행시에 스트링등의 local 변수가 메모리에서 정상적으로 사용되고 있는지 확인할수 있습니다.



마지막으로 storageAlloc함수를 선택한후 Debug를 선택하면 Storage 영역에 대한 정보를 확인할수 있습니다.

vars 변수는 상태변수(State variable)로 Storage 영역에 저장이 되며, 이는 블록에 영구적으로 저장이 됨을 의미합니다.

위의 EVM의 실행구조에서 설명한것처럼 Storage영역은 key/value 의 형태로 256비트 단위로 값을 저장하도록 되으며, 하기의 디버깅 정보로 확인할수 있습니다.



이더리움 스마트컨트랙트는 한번 배포가 되면 블록에 저장되어 변경이 불가능하기 때문에 버그가 발견되어도 수정할수가 없습니다.

따라서 스마트 컨트랙트를 구현하여 실제 배포를 하기전에 충분한 디버깅 과정을 거쳐서 문제가 없음을 검증한후에 배포가 되어야합니다.