반응형
Contract Application Binary Interface (ABI)란
Solidity 환경에서의 ABI는 블록체인 외부 환경과 Smart Contract 또는 Smart Contract 간에 상호 작용하는 표준 방법을 의미 합니다.
이러한 상호 작용을 위해서는 ABI 포맷으로 Encoding 하거나, Encoding된 ABI를 Decoding 할 수 있어야 합니다. 실제 Encoding된 ABI Data를 통하여 이러한 방식을 알아보도록 하겠습니다.
※ 이번 포스팅에서는 비표준 방식의 ABI Encoding은 다루지 않을 계획입니다!
ABI Encode
- ABI Encoding된 데이터는 아래와 같은 포맷을 가지게 됨
- 정적 타입 - 일반 타입, <type>[M]와 같이 배열 크기가 고정된 경우
- 4Byte : Method에 대한 Signature
- 32Byte : 첫 번째 인자의 값
- 동적 타입 - bytes, string, <type>[]와 같이 배열 크기가 선언되지 않은 경우
- 4Byte : Method에 대한 Signature
- 32Byte : 첫 번째 인자에 대한 Offset (해당 Block 기준)
- 32Byte : 첫 번째 인자의 배열 크기 X
- 32Byte ~ : 첫 번째 인자에 대한 배열 요소 (X번 반복)
- 정적 타입 - 일반 타입, <type>[M]와 같이 배열 크기가 고정된 경우
※ Contract Creation Code 안에 있는 Constructor Arguments는 Method Type에 해당하는 4Byte 값이 포함되어 있지 않음
샘플 코드
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.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 {}
}
- Foo 샘플 코드에서 baz(69,true) 호출 시 ABI Encoding 과정
- 0xcdcd77c00000000000000000000000000000000000000000000000000000000000000045000000000000000
0000000000000000000000000000000000000000000000001 (68Byte)- 0xcdcd77c0 (4Byte)
- baz(uint32,bool) Method에 대한 Signature 값
- 0x0000000000000000000000000000000000000000000000000000000000000045 (32Byte)
- 첫 번째 인자 값 : 0x45 (69)
- 0x0000000000000000000000000000000000000000000000000000000000000001 (32Byte)
- 두 번째 인자 값 : 0x1 (true)
- 0xcdcd77c0 (4Byte)
- 이에 대한 Return Type은 false로 output은 아래와 같이 구성됨
- 0x0000000000000000000000000000000000000000000000000000000000000000 (32Byte)
- Return : 0x0 (false)
- 0x0000000000000000000000000000000000000000000000000000000000000000 (32Byte)
- 0xcdcd77c00000000000000000000000000000000000000000000000000000000000000045000000000000000
- Foo 샘플 코드에서 bar(["abc","def") 호출 시 ABI Encoding 과정
- 0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000
000000000000000000000000000000000000000000000000 (68Byte)- 0xfce353f6 (4Byte)
- bar(bytes3[2]) Method에 대한 Signature 값
- 0x6162630000000000000000000000000000000000000000000000000000000000 (32Byte)
- 첫 번째 인자 값 : 0x616263 (abc)
- 0x6465660000000000000000000000000000000000000000000000000000000000 (32Byte)
- 두 번째 인자 값 : 0x646566 (def)
- 0xfce353f6 (4Byte)
- 0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000
- Foo 샘플 코드에서 sam("dave",true,[1,2,3]) 호출 시 ABI Encoding 과정
- 0xa5643bf200000000000000000000000000000000000000000000000000000000000000600000000000000000
00000000000000000000000000000000000000000000000100000000000000000000000000000000000000000
000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464
61766500000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000030000000000000000000000000000000000000000000000000000
00000000000100000000000000000000000000000000000000000000000000000000000000020000000000000
000000000000000000000000000000000000000000000000003 (292Byte)- 0xa5643bf2 (4Byte)
- sam(bytes,bool,uint256[]) Method에 대한 Signature 값
- uint 형식의 경우 표준 형식인 uint256으로 변경됨
- 0x0000000000000000000000000000000000000000000000000000000000000060 (32Byte)
- 동적 타입의 첫 번째 인자 Offset을 나타내며, Magic Signature 이후 Block 위치를 기준으로 Byte 단위로 측정됨
- 이 경우에는 0x60으로 측정
- 0x0000000000000000000000000000000000000000000000000000000000000001 (32Byte)
- 두 번째 인자 값 : 0x1 (true)
- 0x00000000000000000000000000000000000000000000000000000000000000a0 (32Byte)
- 동적 타입의 세 번째 인자 Offset을 나타내며, 이 경우 0xa0으로 측정
- 0x0000000000000000000000000000000000000000000000000000000000000004 (32Byte)
- 첫 번째 인자 데이터의 배열 길이를 나타내며, 이경우 0x4로 측정
- 0x6461766500000000000000000000000000000000000000000000000000000000 (32Byte)
- 첫 번째 인자 값 : 0x64617665 (dave)
- 0x0000000000000000000000000000000000000000000000000000000000000003 (32Byte)
- 세 번째 인자 데이터의 배열 길이를 나타내며, 이 경우 0x3으로 측정
- 0x0000000000000000000000000000000000000000000000000000000000000001 (32Byte)
- 세 번째 인자 첫 번재 요소 값 : 0x1
- 0x0000000000000000000000000000000000000000000000000000000000000002 (32Byte)
- 세 번째 인자 두 번재 요소 값 : 0x2
- 0x0000000000000000000000000000000000000000000000000000000000000003 (32Byte)
- 세 번째 인자 세 번재 요소 값 : 0x3
- 0xa5643bf2 (4Byte)
- 0xa5643bf200000000000000000000000000000000000000000000000000000000000000600000000000000000
Reference
'Hack > Cryptocurrency' 카테고리의 다른 글
Solidity Visibility, 그리고 View와 Pure 속성 (0) | 2023.07.08 |
---|---|
Rollup (Optimistic Rollups, ZK Rollups) (0) | 2023.07.01 |
브릿지와 크로스 체인, 멀티 체인, 옴니 체인을 알아보자 (0) | 2023.06.24 |
ERC-165 (Ethereum Request for Comments 165) (0) | 2023.06.21 |
Flash Loan Attack in Crypto Currency (0) | 2023.05.20 |
댓글