> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
> Use this file to discover all available pages before exploring further.

# 트랜잭션 유형 및 인코딩

## 목적 및 범위

이 문서는 StableNet에서 사용되는 트랜잭션의 **데이터 구조**, **타입 계층**, **인코딩 방식**을 설명합니다.\
지원되는 6가지 트랜잭션 타입과 각 타입의 역할, 인코딩 형식(RLP, 바이너리, JSON), 서명 및 해시 계산 방식을 다룹니다.

관련 문서:

* 트랜잭션 라이프사이클: [트랜잭션 처리](/ko/transaction-processing/index)
* 상태 전이 실행: [상태 전이](/ko/transaction-processing/6.2-state-transitions)
* API를 통한 트랜잭션 제출: [트랜잭션 제출 및 서명](/ko/transaction-processing/6.4-transaction-submission-and-signing)

## 트랜잭션 타입 계층 구조

StableNet은 다형성 기반 타입 계층 구조를 통해 6가지 트랜잭션 타입을 지원합니다.\
모든 트랜잭션 타입은 `TxData` 인터페이스를 구현하며, 상위 `Transaction` 구조체로 래핑됩니다.

### 타입 목록

| 타입            | 상수                            | 값         | 설명                    |
| ------------- | ----------------------------- | --------- | --------------------- |
| Legacy        | `LegacyTxType`                | 0x00      | EIP-2718 이전 형식        |
| Access List   | `AccessListTxType`            | 0x01      | EIP-2930 접근 목록 트랜잭션   |
| Dynamic Fee   | `DynamicFeeTxType`            | 0x02      | EIP-1559 동적 수수료       |
| Blob          | `BlobTxType`                  | 0x03      | EIP-4844 데이터 가용성 트랜잭션 |
| Set Code      | `SetCodeTxType`               | 0x04      | EIP-7702 코드 위임        |
| Fee Delegated | `FeeDelegateDynamicFeeTxType` | 0x16 (22) | StableNet 수수료 위임 트랜잭션 |

### TxData 인터페이스

모든 트랜잭션 타입이 구현하는 `TxData` 인터페이스(`core/types/transaction.go`)는 다음 책임을 가집니다.

* **타입 식별**: `txType() byte`
* **필드 접근자**: `chainID()`, `nonce()`, `gas()`, `gasPrice()`, `gasTipCap()`, `gasFeeCap()`, `value()`, `to()`, `data()`, `accessList()`
* **서명 처리**: `rawSignatureValues()`, `setSignatureValues()`
* **수수료 위임 확장**: `feePayer()`, `rawFeePayerSignatureValues()`
* **가스 계산**: `effectiveGasPrice(baseFee, gasTip)`
* **인코딩/디코딩**: `encode(*bytes.Buffer)`, `decode([]byte)`

### Transaction 래퍼

`Transaction` 구조체는 모든 트랜잭션 타입을 감싸는 공통 래퍼로 다음 역할을 수행합니다.

* **타입 무관 인터페이스 제공**: 내부에 `TxData` 구현 보유
* **최초 관측 시점 기록**: 로컬 노드에서 처음 인지한 시각 저장
* **계산 결과 캐시**: 해시, 크기, 발신자/수수료 지불자 주소를 `atomic.Value`로 캐시
* **불변성 보장**: 생성 이후 수정 불가, 변경 시 새 트랜잭션 인스턴스 필요

## 개별 트랜잭션 타입

### 레거시 트랜잭션 (타입 0x00)

EIP-2718 이전의 기본 트랜잭션 형식으로, 가장 단순한 구조를 가집니다.

| 필드            | 타입                | 설명                    |
| ------------- | ----------------- | --------------------- |
| `Nonce`       | `uint64`          | 계정 nonce              |
| `GasPrice`    | `*big.Int`        | Wei 단위 가스 가격          |
| `Gas`         | `uint64`          | 가스 한도                 |
| `To`          | `*common.Address` | 수신 주소 (nil이면 컨트랙트 생성) |
| `Value`       | `*big.Int`        | 전송 값                  |
| `Data`        | `[]byte`          | 호출 데이터                |
| `V`, `R`, `S` | `*big.Int`        | ECDSA 서명 값            |

### 액세스 리스트 트랜잭션 (타입 0x01)

EIP-2930으로 도입되었으며, 트랜잭션 실행 시 접근할 주소와 저장소 키를 사전 선언합니다.

추가 특징:

* **`ChainID` 포함**: 리플레이 공격 방지
* **`AccessList` 포함**: 주소 및 슬롯 목록
* **서명 포맷 단순화**: `yParity`(0 또는 1) 사용

### 동적 수수료 트랜잭션 (타입 0x02)

EIP-1559 기반 트랜잭션으로, 기본 수수료와 우선순위 수수료를 분리합니다.

| 필드          | 설명          |
| ----------- | ----------- |
| `GasTipCap` | 최대 우선순위 수수료 |
| `GasFeeCap` | 최대 총 가스 비용  |

유효 가스 가격은 다음과 같이 계산됩니다.

`min(GasTipCap + BaseFee, GasFeeCap)`

StableNet에서는 거버넌스 정책에 따라 `GasTipCap`이 블록 헤더 기준 값으로 제한될 수 있습니다.

### Blob 트랜잭션 (타입 0x03)

EIP-4844로 도입된 데이터 가용성 트랜잭션입니다.

추가 필드:

* **`BlobFeeCap`**: blob 가스당 최대 수수료
* **`BlobHashes`**: 버전 포함 blob 커밋 해시
* **`Sidecar`**: 실제 blob 데이터

제약사항:

* 컨트랙트 생성 불가
* 사이드카 데이터는 해시 계산에서 제외됨
* blob 관련 수치는 `uint256.Int` 사용

### Set Code 트랜잭션 (타입 0x04)

EIP-7702 기반 트랜잭션으로, EOA가 실행 코드를 위임할 수 있습니다.

추가 필드:

* **`AuthList`**: 코드 위임 인가 목록

제약사항:

* 컨트랙트 생성 불가
* `AuthList`는 비어 있을 수 없음
* 실행 실패 시에도 이미 처리된 위임은 롤백되지 않음

### 수수료 위임 트랜잭션 (타입 0x16)

StableNet 고유 확장 트랜잭션으로, 제3자가 가스 수수료를 부담합니다.

추가 필드:

* **`FeePayer`**: 수수료 지불자 주소
* **`FV`, `FR`, `FS`**: 수수료 지불자 서명

두 개의 서명이 필요합니다.

1. 발신자 서명: 트랜잭션 내용 승인
2. 수수료 지불자 서명: 가스 비용 지불 승인

상태 전이 시 수수료 지불자의 잔액만 가스 비용에 사용됩니다.

## 인코딩 형식

### RLP 인코딩

RLP는 네트워크 전송과 저장을 위한 기본 형식입니다.

레거시 트랜잭션:

```
RLP([Nonce, GasPrice, Gas, To, Value, Data, V, R, S])
```

타입 트랜잭션:

```
type_byte || RLP([field1, field2, ...])
```

첫 바이트로 레거시/타입 트랜잭션을 구분합니다.

### 바이너리 인코딩

`MarshalBinary()` / `UnmarshalBinary()`는 EIP-2718 정식 바이너리 인코딩을 제공합니다.\
해시 및 서명 계산에 사용됩니다.

### JSON 인코딩

RPC 인터페이스에서 사용되는 사람이 읽기 쉬운 형식입니다.

* 숫자 값은 모두 16진수 문자열
* 타입 트랜잭션은 `yParity` 포함
* `v`와 `yParity`는 반드시 일치해야 함

## 트랜잭션 서명

### 서명자 선택 로직

체인 설정과 블록 상태에 따라 서명자가 선택됩니다.

```
if IsCancun(blockNumber, blockTime):    → CancunSigner
else if AnzeonEnabled():                → AnzeonSigner
else if IsLondon(blockNumber):          → LondonSigner
else if IsBerlin(blockNumber):          → EIP2930Signer
else if IsEIP155(blockNumber):          → EIP155Signer
else if IsHomestead(blockNumber):       → HomesteadSigner
else:                                   → FrontierSigner
```

`AnzeonSigner`는 Set Code 트랜잭션을 포함한 StableNet 확장을 처리합니다.

### 서명 및 복구

* 서명은 서명 필드를 제외한 해시에 대해 수행
* `Sender()`를 통해 발신자 주소를 복구
* 수수료 위임 트랜잭션은 `FeePayer()`로 별도 주소 복구

## 트랜잭션 해싱

### 해시 계산 규칙

레거시 트랜잭션:

```
keccak256(rlp([...]))
```

타입 트랜잭션:

```
keccak256(type_byte || rlp([...]))
```

해시는 최초 계산 후 캐시됩니다.

### Blob 트랜잭션 특이사항

Blob 트랜잭션 해시는 사이드카 데이터를 포함하지 않습니다.\
사이드카 유무와 무관하게 동일한 해시를 유지합니다.

## 상태 전이와의 통합

실행 전 트랜잭션은 `TransactionToMessage()`를 통해 `Message` 구조체로 변환됩니다.

* 발신자 및 수수료 지불자 주소 추출
* 가스 가격 계산
* 수수료 위임 정보 반영
* RPC 호출 시 서명 검증을 건너뛸 수 있는 플래그 포함

이를 통해 트랜잭션은 블록 실행과 RPC 시뮬레이션 양쪽에서 동일한 경로로 처리됩니다.
