본문 바로가기
블록체인

[이더리움] Signature API 클라이언트

by dbadoy 2023. 5. 16.

이더리움 스마트컨트랙트의 메서드 호출, 이벤트 식별은 Signature를 Keccak256 처리한 값으로 가능하다.

Signature란 'transfer(address,uint256)', 'Transfer(address,uint256)'과 같은 문자열을 의미하고, Keccak256 처리를 한 뒤 메서드의 경우 8글자(4 byte), 이벤트의 경우 64글자(32 byte)를 앞에서 추출한 것을 Selector 또는 ID 라고 부른다.

Keccak256('transfer(address,uint256)')[0:4] -> 0xa9059cbb
Keccak256('Transfer(address,address,uint256)')[0:32] -> 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

주로 트랜잭션을 전송해 스마트컨트랙트의 특정 메서드를 호출할 때, 또는 익스플로러나 지갑과 같이 사용자와 연관된 트랜잭션에 대한 내용을 보여줘야하는 경우 사용된다.

트랜잭션 Data 가장 앞에 "0x" 포함 10글자가 메서드 ID를 의미하고, 위 사진과 같이 'Method' 필드를 보여줄 수 있다. 물론, 0xa9059cbb가 transfer(address,uint256)의 메서드 ID인 것을 알기 위해서는 메서드 ID와 메서드 Signature 정보를 데이터베이스에 저장하고 있어야 한다. 

하지만 이를 위한 데이터베이스와 서버 구축, 데이터 업데이트가 번거롭기도 하고... 서로 다른 서비스라도 동일한 데이터를 저장하고 관리하고 있는 것은 비효율적으로 느껴질 수도 있다.

이를 위한 해결책으로, 외부에서 제공하는 API를 사용하는 방법이 있다. 메서드 ID, 이벤트 ID를 입력했을 때 그에 맞는 Signature를 돌려주는 API 서비스는 꽤 여러 가지가 있다. 해당 글에서는 그 중 두 가지를 소개하려고 한다.

4byte.directory

https://www.4byte.directory/

4byte directory는 이더리움 재단 멤버인 Piper Merriam가 호스팅하고 있는 서비스다. 메서드와 이벤트를 포함하여 총 1,210,119 개의 Signature를 저장하고 있으며, HTTP를 통해 값을 가져올 수 있다. 현재(2023-05-16) 따로 API Key 없이 사용할 수 있다.

API docs
https://www.4byte.directory/docs/

Example
"0x"를 포함하지 않아도 알아서 처리해준다!

메서드
https://www.4byte.directory/api/v1/signatures/?hex_signature=0xa9059cbb
https://www.4byte.directory/api/v1/signatures/?hex_signature=a9059cbb

이벤트
https://www.4byte.directory/api/v1/event-signatures/?hex_signature=0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
https://www.4byte.directory/api/v1/event-signatures/?hex_signature=ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

주의해야 하는 점은 메서드 ID가 4 byte밖에 안되다 보니 충돌이 나는 경우가 존재한다. 이럴 때는 같은 메서드 ID를 갖는 여러 Signature가 넘어오기 때문에 별도의 처리가 필요하다.

openchain.xyz

https://openchain.xyz/

openchian.xyz는 이벤트 Signature 373,542개, 메서드 Sgianture 2,367,700개로 4byte.directory보다 더욱 많은 Signature를 보관하고 있다. 해당 서비스도 API Key가 따로 필요하지 않으며 HTTP를 통해 값을 가져올 수 있다.

API docs
https://docs.openchain.xyz/#/default

하지만 특정 Signature를 검색했을 때, 데이터베이스에 해당 값이 존재하지 않는 경우조차도 실패가 아니라 200에 null값을 돌려주는데 ID에 "0x" 를 안 붙이면 에러를 리턴하는 점이나, 반환값의 포맷이 이상...한 것이 조금 그렇다.

외부 API를 이용해 서비스를 만드는 입장에서, 사용 가능한 엔드포인트는 많을 수록 좋다. 그러한 점에서 제공되는 API가 아니라 GitHub를 통해 가져오는 방법도 소개한다.

GitHub

https://github.com/ethereum-lists/4bytes

위 저장소의 /signatures 에는 915,173개의 메서드 Signature가 저장되어 있다. 이 값을 HTTP 요청으로 가져와 사용할 수 있다.

https://raw.githubusercontent.com/ethereum-lists/4bytes/master/signatures/a9059cbb
--> transfer(address,uint256)

 

해당 방법을 사용하면 메서드 ID 요청만 가능하고, 메서드 ID 충돌이 발생해 여러 Signature가 존재하는 경우는,

getTokenLockersForAccount(address);activateCollection(uint256)

위와 같이 ';'로 구분된 결과가 리턴되기 때문에 따로 처리가 필요하다.

이 방법에는 치명적인 문제가 존재하는데... 결과값으로 methodName((uint256)) 이와 같이 넘어오는 경우가 존재한다. 해당 케이스가 넘어오면 별도의 처리를 해주는 로직이 필요한데, 약 90만개 중 손에 꼽는 케이스를 위해 로직을 추가해야 한다는 점이 마음에 들지는 않는다.

 

위에서 소개한 `4byte.directory`, `openchian.xyz`, `GitHub`로 부터 Signature를 가져오는 클라이언트를 Go로 만들어봤다. 해당 라이브러리를 사용하거나, 코드를 참고해서 클라이언트를 직접 만들어 사용하면 된다.

https://github.com/dbadoy/signature