이더리움 토큰 컨트랙트 이벤트 로그 추적하기

 

 

Contract & Event

 

 

본 포스팅은 이더리움(ethereum) 블록체인의 컨트랙트(contract)에서 발생하는 이벤트(event)를 보고, 해당 컨트랙트를 통해 발생된 이벤트 로그들을 보고 특정 행동을 했는지를 확인해보려고 합니다. 

 

참고로, 컨트랙트(contract)란, 개발자들이 블록체인에 계약서의 내용을 프로그래밍으로 작성해서 올려둔 것을 말합니다. 이 프로그래밍된 계약서의 함수가 실행되면 반드시 지켜지게 됩니다. 함수(function or method)란, 컨트랙트에서 호출되는 함수를 말합니다. 컨트랙트마다 함수는 다를 수 있습니다. 토큰 컨트랙트라면 transfer나 lock 같은 토큰을 전송하거나 잠그는 함수들이 있을 것이고, 게임 컨트랙트라면 attack이나 defence 등의 캐릭터를 제어하는 함수들이 있을 것입니다. 물론, 함수 이름은 개발자 마음이기 때문에 이름도 제각각 일 것입니다. 이벤트(event)란, 개발자들이 컨트랙트를 개발할 때 함수들이 호출될 때 블록에 해당 기록을 남김으로써, 나중에 보기 편하게 기록을 찾아볼 수 있도록 삽입하는 것을 말합니다. 

 

 

목적

이더리움 블록체인 플랫폼에 이미 배포(deploy)된 APIS 토큰 컨트랙트를 통해 이미 처리된 행동(=함수)들 중에서 지갑(wallet)을 잠그는 행위를 했을 때 발생되는 특정 이벤트(=여기서는 "Locked"라는 이름을 가진 이벤트)의 기록을 살펴볼 것입니다. 그리고 이 기록에 어떤 내용들이 기록되어 있는지 확인해보겠습니다.

 

APIS 토큰 컨트랙트의 내용을 살펴본 결과, 지갑을 잠그는 함수인 walletLock이 호출될 때, 정상적으로 처리되는 경우 Locked라는 이벤트가 발생되도록 프로그래밍되어 있었습니다. 따라서, Locked라는 이벤트 기록을 보면 잠겨진 지갑이나 잠긴 기간 등의 몇가지 정보를 볼 수 있겠죠.

 

 

추적 대상

이더리움 (아피스) APIS 토큰 컨트랙트

 

 

추적 하기

컨트랙트에서 발생된 내용을 추적하는 방법을 단계별로 나누었습니다. [Step1] 가장 먼저 추적할 컨트랙트 주소를 가지고 있어야 합니다. 자신이 살펴볼 컨트랙트 주소를 가지고 있다면, [Step2] 해당 컨트랙트가 어떤 내용으로 이루어졌는지 내용을 확인할 필요가 있습니다. 참고로, 이때 컨트랙트 내용이 solidity라는 프로그래밍 언어로 작성되어 있기 때문에 개발자가 아닌 일반 사용자는 보기 불편할 수도 있습니다. 이땐 컴퓨터 전공자에게 도움을 요청하면 어느정도 해석이 가능할 것이라고 생각됩니다. [Step3] 컨트랙트의 행동을 볼 때는, 추적하고 싶은 이벤트에 대한 주소가 필요합니다. 이 주소를 검색하면 해당 이벤트가 발생됬던 모든 기록(history)를 볼 수 있기 때문이죠. 마지막으로, [Step4] 검색된 이벤트 기록들 중에 원하는 이벤트를 찾아서 해당 기록을 살펴보면 됩니다.

 

  1. [Step1] 토큰 컨트랙트 주소 획득
  2. [Step2] 토큰 컨트랙트 내용 확인
  3. [Step3] 토큰 컨트랙트 내의 이벤트 주소 획득
  4. [Step4] 토큰 컨트랙트 내의 이벤트 정보 확인

 

 

Step1. APIS 컨트랙트 주소 획득

0x4C0fBE1BB46612915E7967d2C3213cd4d87257AD

 

※ 작성자는 포스팅 설명을 위해 찾아본 토큰 중 하나입니다. 위 주소가 아닌 현재 실습에 사용하고 싶은 다른 컨트랙트 주소를 가지고 있다면 해당 주소를 사용하면 됩니다. 단, 본 포스팅은 APIS 토큰 컨트랙트를 기준으로 작성되었기 때문에, 다른 컨트랙트를 대상으로 할 경우 폰 포스팅에서 설명하는 방법과 조금 다를 수 있습니다. 컨트랙트마다 내용이 모두 다르기 때문이죠. 따라서, 찾아보려는 컨트랙트에서 발생한 특정 이벤트들을 보기 위해, 현재 포스팅처럼 접근하는 방식만 참고하길 바랍니다.

 

 

Step2. APIS 컨트랙트 내용 확인

1. Etherscan 사이트 접속 (=이더리움 블록체인 내의 발생 정보 제공)

https://etherscan.io/

 

2. APIS 컨트랙트 조회

Search : 0x4C0fBE1BB46612915E7967d2C3213cd4d87257AD

 

3. APIS 컨트랙트 내용 확인

[Contract]

  • Contract Source Code : 개발자가 작성한 컨트랙트 코드 내용 (solidity언어로 출력)
  • Contract ABI : 컨트랙트 interface 내용
  • Contract Creation Code : 컨트랙트 코드 내용 (Bytecode로 출력)
  • Contract Creation Code : 컨트랙트 코드 내용 (Opcode로 출력)

 

4. APIS 컨트랙트 내용 중 Locked 이벤트 내용 확인

4-1. “Locked이벤트 확인

Contract Source Code 에서 “event Locked” 검색

/**
* @dev 토큰 지갑의 송금/입금 기능이 제한되었을 때 발생하는 이벤트
* @param target 제한 대상 지갑 주소
* @param timeLockUpEnd 제한이 종료되는 시간(UnixTimestamp)
* @param sendLock 지갑에서의 송금을 제한하는지 여부(true : 제한, false : 해제)
* @param receiveLock 지갑으로의 입금을 제한하는지 여부 (true : 제한, false : 해제)
*/
event Locked (address indexed target, uint timeLockUpEnd, bool sendLock, bool receiveLock);

 

4-2. “Locked이벤트 호출지점 확인

Contract Source Code 에서 “Locked” 검색

/**
* @dev 지갑을 지정된 시간까지 제한시키거나 해제시킨다. 제한 시간이 경과하면 모든 제한이 해제된다.
* @param _targetWallet 제한을 적용할 지갑 주소
* @param _timeLockEnd 제한이 종료되는 시간(UnixTimestamp)
* @param _sendLock (true : 지갑에서 토큰을 출금하는 기능을 제한한다.) (false : 제한을 해제한다)
* @param _receiveLock (true : 지갑으로 토큰을 입금받는 기능을 제한한다.) (false : 제한을 해제한다)
*/
function walletLock(address _targetWallet, uint _timeLockEnd, bool _sendLock, bool _receiveLock) onlyOwner public {
	require(_targetWallet != 0x0);
        
	// If all locks are unlocked, set the _timeLockEnd to zero.
	if(_sendLock == false && _receiveLock == false) {
		_timeLockEnd = 0;
	}
        
	lockedWalletInfo[_targetWallet].timeLockUpEnd = _timeLockEnd;
	lockedWalletInfo[_targetWallet].sendLock = _sendLock;
	lockedWalletInfo[_targetWallet].receiveLock = _receiveLock;
        
	if(_timeLockEnd > 0) {
		Locked(_targetWallet, _timeLockEnd, _sendLock, _receiveLock);
	} else {
		Unlocked(_targetWallet);
	}
}

 

등록된 APIS 컨트랙트에는 한글로 설명이 아주 잘 되있었기 때문에 컨트랙트 내용을 살펴보는데 어렵지 않았던 것 같습니다. 하지만, 컨트랙트마다 작성된 개발자가 다르기 때문에 설명이 불충분할 수도 있습니다. 만약에, APIS 컨트랙트가 아닌 다른 컨트랙트를 대상으로 살펴볼 때, 개발자가 작성해 놓은 설명으로 내용을 파악하기 힘들다면, 직접 코드를 보고 해석할 필요가 있을 수도 있습니다.

 

이제, [4-1]을 통해 APIS 컨트랙트에서 Locked이벤트가 발생할 때 어떤 정보들이 로그에 나오는지 찾았고,  [4-2]를 통해 Locked이벤트가 컨트랙트에서 어떤 처리할 때 발생되는지 찾아냈고 이 정보들을 바탕으로 발생된 이벤트 로그들을 살펴보겠습니다.

 

[4-1] 에서 알 수 있는 내용 (="Locked" 이벤트에 출력되는 내용)

  • target : 잠근(Locked) 지갑에 대한 주소
  • timeLockUpEnd : 잠금 해제가 종료되는 시간
  • sendLock : 잠글 때, 해당 지갑에서 돈 인출 기능을 제한할지에 대한 설정여부
  • receiveLock : 잠글 때, 해당 지갑에 돈 송금 기능을 제한할지에 대한 설정여부       

[4-2] 에서 알 수 있는 내용 (="Locked" 이벤트가 발생되는 시점)

  • walletLock : 지갑을 잠글 때, 잠금 해제 시간이 유효하다면 Locked 이벤트 호출

 

※ Contract Source Code는 컨트랙트 코드가 출력되는데, 이더리움 블록체인 내의 컨트랙트는 이곳에 작성된 내용대로 동작하게 됩니다. 따라서, 원하는 이벤트를 확인하고 싶다면 이곳에서 발생가능한 이벤트들을 코드에서 찾아야 합니다. Contract Source Code 안에서 찾기 단축키인 “Ctrl+F” 눌러서 “event”를 찾아보면 모두 볼 수 있습니다.

 

참고로, Contract Source Code에 출력되는 코드가 블록체인 내에 그대로 저장되는 것이 아닙니다. 사람(=프로그램 개발자)가 읽기 쉬운 형태(=solidity)가 아닌, 읽기 어려운 형태(=opcode)로 변경되서 저장됩니다. 따라서, Contract Creation Code(Opcode)를 통해 원하는 이벤트를 찾아낼 수 있지만 쉽지 않습니다. 그래서 본 포스팅에서는 이벤트 주소를 이 코드 안에서 찾아내지 않고, 컨트랙트 내에서 포함된 이벤트 주소들까지 알려주는 사이트인 Bloxy를 사용해서 알아낼 것입니다.

 

 

Step3. APIS 컨트랙트 내의 이벤트 주소 획득

1. Bloxy 사이트 접속 (이더리움 블록체인 내의 발생 정보 제공)

https://bloxy.info/

 

2. APIS 컨트랙트 조회

Search : 0x4C0fBE1BB46612915E7967d2C3213cd4d87257AD

 

3. APIS 컨트랙트 이벤트 주소 획득

[Smart Contract Events]

 

※ [Smart Contract Event] 탭에 표시된 이벤트 목록들은 APIS 컨트랙트에서 발생시킨 이벤트 이름과 발생 횟수에 대한 정보입니다. 여기서 원하는 이벤트를 클릭하서 이벤트 주소(=Event Hash)를 가져옵니다. 아래는 Bloxy에서 제공된 APIS 컨트랙트 이벤트들에 대한 주소 정보입니다.

Event name Event Hash
Transfer 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
Locked 0x9a26d7aa8d0b0885c3a5cce1b95072a26bc415306c652f20e7b507c07a3914d5
RejectedPay.. 0x77c483e4ff749a73be4f6404c2ecea502a159772ef1cd46e475516a4cdf0eb0d
Approval 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
Unlock 0x7e6adfec7e3f286831a0200a754127c171a2da564078722cb97704741bbdb0ea
Burn
0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5

 

 

Step4. APIS 컨트랙트 내의 이벤트 로그 확인

1. Etherscan 사이트 접속

https://etherscan.io/

 

2. APIS 컨트랙트 조회

Search : 0x4C0fBE1BB46612915E7967d2C3213cd4d87257AD

 

3. APIS 컨트랙트 이벤트(=토픽) 로그 검색

[Events]

Find : 0x9a26d7aa8d0b0885c3a5cce1b95072a26bc415306c652f20e7b507c07a3914d5

 

이벤트 로그들 중에 확인이 필요한 Locked이벤트(=위 처럼 Locked 이벤트에 해당하는 16진수 주소값)를 검색하면, 해당 이벤트가 발생했을 때의 로그들이 모두 출력됩니다. 출력되는 내용들이 어떤 의미를 가지는지 살펴보겠습니다.

 

Txn Hash Method Event Logs

트랜잭션 해시

트랜잭션이 담긴 블록 번호

함수 주소

함수 이름 (정의된 내용)

이벤트 이름 (정의된 내용)

이벤트 입력값 내용

 

해당 컨트랙트를 통해서 어떤 일들이 발생했는지는 위 3가지 정보들을 기반으로 살펴볼 수 있습니다. “Locked이벤트에 대해서 검색했기 때문에, 해당 이벤트에 대한 목록들이 모두 출력되는 것을 볼 수 있습니다. 참고로, Etherscan에서는 일어난 모든 이벤트는 볼 수 없고, 발생했던 이벤트들 중에 최근것들에 대해서만 볼 수 있도록 제공하고 있습니다.

 

4. APIS 컨트랙트 이벤트(=토픽) 로그 분석

아래 사진은 Etherscan에서 Locked이벤트의 로그 중 가장 마지막으로 제공된 내용을 캡쳐한 것입니다. (참고, Etherscan에서 제공된 데이터 중 가장 마지막 로그일 뿐 APIS를 통해 처리된 로그 중 가장 마지막은 아닙니다.)

 

Locked 이벤트 로그 중 하나

 

아래 표는 위 캡쳐된 정보를 살펴보면 알 수 있는 내용들을 정리한 것입니다. 앞에서 언급했던 것처럼 아래 표에서 Event Log 기록을 보면, APIS 컨트랙트의 지갑을 잠글 때 사용되는 “walletLock” 함수가 처리될 때 발생된 Locked이벤트 정보를 통해 어떤 값들이 사용되었는지 볼 수 있습니다.

 

잠겨진 지갑의 주소(=target)0x8c133a2144b66ac06a12fe5c1a88c460f4dce4aa이고, 잠김 해제시간(timeLockUpEnd)1534921200이고, 잠긴 지갑의 돈 인출 제한여부(=sendLock)는 1(=true)이기 때문에 인출 불가능하다는 것이고, 돈을 더 넣을 수 있는지 송금 여부(=receiveLock)는 0(=false)이기 때문에 잠근 지갑에 추가 송금이 가능하다는 것을 알 수 있습니다.

 

구분

설명

Trx Hash

이더리움 블록체인에서 처리된 트랜잭션 정보

 

트랜잭션 해시

: 0x8abde45fabab69d5a2431d58f4c9d8d97befdec61f6e603fd15b023bee99fb16

트랜잭션이 담긴 블록 번호

: 6191216
Method

APIS 컨트랙트에서 처리된 함수(=Event를 발생시킨 함수)

 

함수 주소

: 0x74ccd7cc

함수 정의

: walletLock(address,uint256,bool,bool)

Event

Logs

APIS 컨트랙트에서 처리된 함수에서 발생된 이벤트(=메모 로그)

 

이벤트 정의

: Locked (index_topic_1 address target, uint256 timeLockUpEnd, bool sendLock, bool receiveLock)

입력 값 내용

(address) target : 0x8c133a2144b66ac06a12fe5c1a88c460f4dce4aa

(uint256) timeLockUpEnd : 1534921200

(bool) sendLock : 0000000000000000000000000000000000000000000000…1

(bool) receiveLock : 0000000000000000000000000000000000000000000000…0

 

지갑 잠금 시간인 timeLockUpEnd의 값이 1534921200으로 출력되었지만, 실제로 이 값은 컴퓨터에서 사용되는 UnixTimestamp 포멧의 시간정보입니다. 따라서 사람이 읽을 수 있는 시간 정보로 변환해서 봐야합니다. 변환된 시간값은 “2018822일 수요일 오후 4:00:00”이므로, 이 때까지 해당 지갑은 잠겨있었다는 것을 알 수 있습니다. (시간 변환 사이트는 아래 첨부했습니다.)

 

참고로, 발생된 Locked 이벤트 로그 중에 timeLockUpEnd 시간이 9999999999인 것들이 많이 있는데, 이 시간을 변환하면 “22861121일 일요일 오전 2:46:39”이므로, 영원히 잠궈버리겠다는 의미입니다.

 

APIS라는 처음 들어보는 코인이었는데, 올해(2019) 초에 상장된 코인이었네요. 아마도 이번 포스팅에 설명하는 컨트랙트는 APIS가 상장하기 전에 사용했던 이더리움 블록체인 플랫폼에 올려둔 토큰 컨트랙트인 것 같습니다.

 

 

참고 사이트

Etherscan (이더리움 블록 정보 제공)

https://etherscan.io/

Bloxy (이더리움 블록 정보 제공)

https://bloxy.info/

시간 정보 변환 (UnixTimestamp Converter)

https://www.epochconverter.com/