-
Transaction Data 살펴보기 (feat. ABI)BlockChain Tech 2019. 4. 10. 12:13
Transaction을 구성하는 여러가지 요소들이 있다.
대부분 쉽게 이해할 수 있는 반면, Data라는 친구는 명확하게 어떤 것을 해주는 항목인지 알기 힘들다.
오늘은 Transaction의 Data가 어떤 역할을 하는지 알아보도록 하자.
Transaction의 구성요소
- nonce: 해당 계좌에서 발생된 Transaction의 수
- from: receive address
- to: sender address
- value: 수신자에게 보내는 Ether 수량
- gas limit: 가스의 최대 사용량
- gas price: 가스 가격
- data: 가변길이의 바이너리 데이터
- v, r, s: ECDSA 서명 구성 요소
Transfer Transaction
var transaction = { nonce: web3.toHex(nonce), gasPrice: eb3.toHex(web3.toWei(1, 'Gwei').toNumber()), gasLimit: web3.toHex(100000), to: '0xe456064545F872B311aE7432689a0fECE90C9a29', value: web3.toHex(web3.toWei(0.1, 'ether').toNumber()), data: '0x0' };
일반적인 송금에서는 data에 아무런 값을 넣어주지 않아도 된다. (않아 보다는 할 필요가 전혀 없다.)
Contract Execution Transaction
var transaction = { nonce: web3.toHex(nonce), gasPrice: eb3.toHex(web3.toWei(1, 'Gwei').toNumber()), gasLimit: web3.toHex(5000000), to: contractAddress, value: '0x0', data: '0x18b0c3fd' };
Contract Execution Transaction의 경우 receive address가 일반 EA(External Account )가 아닌 CA(Contract Account)인 점
그리고, data에 어떠한 값이 들어간 점이 달라졌다.
Transaction을 '어떠한 명령'을 수행하라는 주문서라고 생각해보자.
Transfer
(1)From이 (2)To에게 (3)Value 만큼을 (4)GasLimit * GasPrice 만큼의 수수료를 내고 수행해달라!
굉장히 단순하고 쉽게 실행이 되지만, Contract Method를 호출하게될 때는 어떤 형대로 진행이 될까?
Contract Execution
(1)From이 (2)Contract에게 (3)Value 만큼을 (4)GasLimit * GasPrice 만큼의 수수료를 내고 (5)Data에 16진수를 수행해달라!
Data에 16진수
16진수라는 데이터를 가지고, 어떤 함수에 어떤 인자값을 넣었는지 어떻게 알 수 있을까?
Solidity docs에서 그 해답을 찾을 수 있다. (링크)
> Contract를 호출 할 때에는 ABI Spec에 맞추어 data를 변환 해야하고, 그 data를 Transaction에 추가한다.
pragma solidity >=0.4.16 <0.7.0; contract Foo { function bar(bytes3[2] memory) public pure {} function baz(uint32 x, bool y) public pure returns (bool r) { r = x > 32 || y; } function sam(bytes memory, bool, uint[] memory) public pure {} }
(1) CA(Contract Account)의 Contract Address를 통하여 'Foo' Contract의 접근
(2) 호출하고 싶은 Method ID 입력
> Method ID는 각 function마다 다른 값을 갖을 수 있다.
> the first 4 bytes of the Keccak hash of the ASCII form of the signature
> ASCII 서명 방식의 Keccak해시 값의 처음 4 bytes
> bytes4(keccak256('transferFrom(address,address,uint256)')) 를 통해 얻을 수 있다.
> 정말 말 그대로 해당 함수의 interface를 해시화 하고, 앞의 4 bytes를 가지고 오면 Method ID가 된다.
> Solidity에서는 'selector'라는 Method를 통해 Method ID를 추출할 수 있다. (ex. this.bar.selector)
bytes4(keccak256('function bar(bytes3[2])'))
=> 0xfce353f6
(3) 인자값이 들어가야할 경우 32bytes 형식으로 변환하여 Method ID 뒤에 연결한다.
> ["abc", "def"] 라는 인자를 function bar와 함께 호출하고 싶다면
> abc = 0x6162630000000000000000000000000000000000000000000000000000000000
> def = 0x6465660000000000000000000000000000000000000000000000000000000000
> 이대로 Method ID와 합성을 해주면 된다.
Transaction에 포함시킬 Data
"0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000"
Argument가 왜 저런 모습의 16진수가 되는건가요?
- 사전에 EVM에서 약속된 ABI Spec에 따라 변환되어야 하기 때문에 그렇다.
> Encoding 규칙에 대해서 나열할 순 없으니 (링크) 를 참조하자!
Etheruem ABI Encoding / Decoding은 다양한 사이트에서 실험해볼 수 있다.
https://adibas03.github.io/online-ethereum-abi-encoder-decoder/#/decode
[추가] Ethereum Contract ABI Converter
'BlockChain Tech' 카테고리의 다른 글
Klaytn SmartContract로 `내기 | 복권` 만들어보기 리뷰 (1) 2020.06.03 [Klaytn] Contract Execution (feat. Fee Delegated) (2) 2019.04.06 [Klaytn] 대(신)납(부) 기능 (feat. Fee Delegated) (2) 2019.04.06