Minwook’s portfolio

블록체인 data의 hashing방법 파해치기 본문

Codestates 블록체인 부트캠프 6기

블록체인 data의 hashing방법 파해치기

yiminwook 2023. 1. 5. 16:08

 

우리는 트랜젝션을 실행시킬때 메타마스크에서 데이터를 확인할 수 있고,

실행시킨뒤에는 이더스캔을 통해 트랜젝션의 Data 값을 확인할 수 있다.

CA로 보내는 Data는 SmartContract가 공개되어 있다면 내장 기능을 통해 디코딩을 할 수 있다.


Data 값을 직접 디코딩 하면서 어떠한 원리와 순서로 기존 Data가 인코딩되어 CA계정으로 보내지고,

CA계정에서는 Data를 어떤식으로 읽는지 알아보고자 한다.

 


 

우선 input Data에서 맨 먼저 보이는 정보 MethodID.

MethodID는 SmartContract에서 어떤 함수를 실행시킬건지에 대한 정보이다.

 

MethodID를 인코딩해서 만드는 방법은 간단하다.

1. 함수명과 파라메터를 가져온다.

2. 변수명과 공백을 삭제한다.

3. keccak256으로 hashing 한다.  https://emn178.github.io/online-tools/keccak_256.html < = 인코딩 사이트 

4. 앞에서부터 4바이트(8글자)를 끊는다. 

5. 0x를 붙인다.

 

위 방법으로 ERC20의 safeTransferFrom(address from, address to, uint256 tokenId)의 MethodID를 만들어 보자.

//1. safeTransferFrom(address from, address to, uint256 tokenId)
//2. safeTransferFrom(address,address,uint256) 변수명과 공백을 삭제.
//3. 42842e0eb38857a7775b4e7364b2775df7325074d088e7fb39590cd6281184ed //keccak256 hashing
//4. 42842e0e //4바이트로 끊는다 
//5. 0x42842e0e //0x를 붙인다

 

자주 쓰는 컨트랙트 함수는 MethodID가 같기 때문에 https://www.4byte.directory/에서 확인 해볼 수 있다.

앞 8글자만 때오기 때문에 hashing을 하더라도 중복되는 경우가 있을 수 있지만, 하나의 SmartContract에서 겹치게되는 확률은 아주 작아 크게 문제없다.

 

 

해당 사이트에서 0x42842e0e를 검색해보면 safeTransferFrom함수가 나오는 것을 알 수 있다. 

위를 통해 우리가 ABI파일을 통해 MethodID를 만들고 Data에 담아 컨트랙트에 보내면 MethodID에 해당하는 함수를 실행시킴을 알 수 있다.

 


 

이번에는 ERC721의 Mint()함수의 Data를 분석하여 파라메터의 data가 어떤 식으로 들어가는지 알아보도록 하겠다.

 

0xeacabe140000000000000000000000003ad254289688001fb5a427121aaf0bf77000e6d70000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005b68747470733a2f2f697066732e696f2f697066732f516d574d7235587568413453737135655175577a5a79514a4d7664335a72334469646441577635754e64584c776d3f66696c656e616d653d64756d6d79446174612e6a736f6e0000000000

 

민트후에 이더스캔에서 확인한 Data값은 위와 같다. 

우리는 이미 MethodID에 대해서 알아보았으니 Data의 앞 8글자는 MethodID임을 쉽게 눈치 챌 수 있다.

 

이번에는 MethodID를 제외하고 32바이트(64글자)로 쪼개보도록 하겠다. 

0xeacabe14
[0]: 0000000000000000000000003ad254289688001fb5a427121aaf0bf77000e6d7
[1]: 0000000000000000000000000000000000000000000000000000000000000040
[2]: 000000000000000000000000000000000000000000000000000000000000005b
[3]: 68747470733a2f2f697066732e696f2f697066732f516d574d72355875684134
[4]: 53737135655175577a5a79514a4d7664335a72334469646441577635754e6458
[5]: 4c776d3f66696c656e616d653d64756d6d79446174612e6a736f6e0000000000

 

mintNFT(address recipient, string tokenURI)의 파라메터로는 address(받는사람)와 string(tokenURI)로 이루어져있다.

data도 address와 string 순으로 들어가야 함으로 [0]은 받는 사람의 address 임을 알 수 있다.

[1] ~ [5]는 string에 넣어줄 value(값)를 나타낸다.

 

10진수 변환 사이트 https://www.rapidtables.com/convert/number/hex-to-decimal.html

[1]을 16진수에서 10진수로 바꾸면 64, 해당 값이 string임을 암시한다.

[2]을 16진수에서 10진수로 바꾸면 91로, 이 값은 [3] ~ [5]사이의 182글자가 string의 인코딩 값임을 나타낸다.

data는 32바이트 단위로 입력되기 때문에 91바이트(182글자)를 입력하고 남는 자릿수는 모두 0이 채워진다.

위 data에서는 96바이트중 91바이트를 사용하기 때문에 남는 5바이트(10글자)가 0으로 채워지게 된다.

 

68747470733a2f2f697066732e696f2f697066732f516d574d7235587568413453737135655175577a5a79514a4d7664335a72334469646441577635754e64584c776d3f66696c656e616d653d64756d6d79446174612e6a736f6e

따라서 string value를 구하기 위해서는 위 부분만 가져와서 16진수 => 10진수 => utf-8로 바꿔주면 된다.

 

위 값을 변환사이트 https://onlineutf8tools.com/convert-hexadecimal-to-utf8 에서 디코딩해보면 

https://ipfs.io/ipfs/QmWMr5XuhA4Ssq5eQuWzZyQJMvd3Zr3DiddAWv5uNdXLwm?filename=dummyData.json 

위와 같은 string이다.

 

맨 처음 Data는 MethodID, adress, string 3가지 값이 들어있음을 우리는 알 수 있었다.

 

우리는 지금까지의 과정을 생략하고 web3.contract.methods 내장함수를 통해 data값을 쉽게 만들어서 트랜젝션을 날릴 수 있지만 함수내부에서 어떤 일들이 일어나는지 알아두면 활용하는데 더욱 도움이 될 것 이라고 생각한다.

Comments