초보자를 위한 ICON DApp 만들기 4

Sample 코드 분석

harry kim
ICON DAPP ALLIANCE
9 min readJun 29, 2020

--

이 글은 스마트 컨트랙트 샘플 코드 및 현재 서비스 되고 있는 여러 DApp들을 분석해 초보자들도 자신들의 아이디어에 ICON을 쉽게 도입할 수 있도록 돕기 위해 작성되었습니다.

이번 글은 lastVisit 예제를 통해 SCORE 작성 방법에 대해 알아보겠습니다. SCORE 작성에 필요한 문법 및 API는 아래 사이트를 통해 확인 가능합니다.

lastVisit은 일정 시간동안 방문 호출이 없을 경우, 가장 마지막 방문자를 기록하는 SCORE 입니다. 먼저 tbears를 이용하여 프로젝트를 생성합니다.

필요한 변수들을 __init__에 추가합니다. DB에 상태를 저장하기 위해 VarDB, DictDB, ArrayDB 세 가지 wrapping class를 제공합니다. 내부적으로 key-value 데이터베이스인 LevelDB를 사용하며, key를 통해 데이터를 저장하고 조회할 수 있습니다.

방문 duration, 마지막 방문 시간, 어드레스, 방문 가능 여부를 기록할 변수를 DB에 생성합니다. 그리고 초기화가 필요한 변수들은 on_install에서 SCORE 최초 배포되었을 때 초기화 되도록 합니다. 여기서 _duration_time은 5분으로 5분 동안 다른 방문이 없을 경우, 방문 불가능 상태로 바뀌고 이전 방문이 마지막 방문이 됩니다. (변수 초기화가 반드시 on_install에서 이루어 질 필요는 없습니다. 필요에 따라 초기화 메소드를 만들어 외부에서 초기화 하도록 만들수도 있습니다.)

duration을 변경할 수 있도록 set_duration_time 메소드를 추가합니다. DB에 저장된 데이터의 변경, 조회는 set,get 메소드를 통해 가능합니다. 외부에서 호출 가능한 메소드는 반드시 @external로 데코레이팅되어야 합니다. @external로 데코레이팅된 메소드 호출은 db 변경에 따른 트랜잭션 비용이 발생합니다. 이 트랜잭션 비용 지불을 위해 호출 시, 지갑이 요구됩니다. (db 변경없이 조회만 필요한 경우, 반드시 readonly=True 파라미터가 있어야 합니다.) self.owner는 SCORE를 배포한 지갑 주소를 의미하고 self.msg.sender는 트랜잭션 비용을 지불한 지갑의 주소를 의미합니다. set_duration_time은 SCORE를 배포한 소유주만 호출할 수 있도록 설정합니다.

visit 메소드를 통해, 이전 방문자의 방문 시간으로부터 duration을 넘지 않을 경우, 마지막 방문 시간을 갱신합니다. _is_open이 False로 변경되어 더 이상 방문이 불가능한 경우만, 마지막 방문자 확인이 가능합니다. self.now()는 시스템의 시간이 아닌 current block의 timestamp를 반환하여 모든 node에서 동일한 결과를 얻을 수 있습니다.

lastVisit SCORE를 배포할 소유주 지갑을 생성하고 ICX를 충전합니다.

VSCode에서 settings.json에 생성한 SCORE 배포용 지갑을 추가합니다.

ICON Support를 실행하여 SCORE를 배포합니다.

테스트를 위해 유저로 사용할 지갑을 생성하고 keystore_test1에서 100 ICX를 송금합니다. 그리고 ICONex에 생성한 유저 지갑을 추가하고 contract 탭에서 visit 메소드를 호출합니다.

Step 한도를 설정하여 예상을 벗어난 수수료 지불을 방지할 수 있습니다. 아래 visit 메소드를 실행하면 트랜잭션 주소를 반환합니다. MainNet의 경우 tracker를 통해 결과를 조회할 수 있지만 테스트 환경에서는 tbears를 통해 결과를 조회할 수 있습니다. txresult 결과에서 stepPrice * stepUsed로 visit메소드를 실행하는데 지불한 ICON을 확인 할 수 있습니다.

각 주소별 방문 횟수 조회 및 reset 기능을 추가하였습니다. 컨트랙트를 업데이트 할 때, ICON Support에서 update를 체크해야 새로 배포하지 않고 기존 컨트랙트 주소에 업데이트합니다.

--

--