Skip to main content

목적 및 범위

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

트랜잭션 타입 계층 구조

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

타입 목록

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 이전의 기본 트랜잭션 형식으로, 가장 단순한 구조를 가집니다.

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

EIP-2930으로 도입되었으며, 트랜잭션 실행 시 접근할 주소와 저장소 키를 사전 선언합니다. 추가 특징:
  • ChainID 포함: 리플레이 공격 방지
  • AccessList 포함: 주소 및 슬롯 목록
  • 서명 포맷 단순화: yParity(0 또는 1) 사용

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

EIP-1559 기반 트랜잭션으로, 기본 수수료와 우선순위 수수료를 분리합니다. 유효 가스 가격은 다음과 같이 계산됩니다. 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는 네트워크 전송과 저장을 위한 기본 형식입니다. 레거시 트랜잭션:
타입 트랜잭션:
첫 바이트로 레거시/타입 트랜잭션을 구분합니다.

바이너리 인코딩

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

JSON 인코딩

RPC 인터페이스에서 사용되는 사람이 읽기 쉬운 형식입니다.
  • 숫자 값은 모두 16진수 문자열
  • 타입 트랜잭션은 yParity 포함
  • vyParity는 반드시 일치해야 함

트랜잭션 서명

서명자 선택 로직

체인 설정과 블록 상태에 따라 서명자가 선택됩니다.
AnzeonSigner는 Set Code 트랜잭션을 포함한 StableNet 확장을 처리합니다.

서명 및 복구

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

트랜잭션 해싱

해시 계산 규칙

레거시 트랜잭션:
타입 트랜잭션:
해시는 최초 계산 후 캐시됩니다.

Blob 트랜잭션 특이사항

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

상태 전이와의 통합

실행 전 트랜잭션은 TransactionToMessage()를 통해 Message 구조체로 변환됩니다.
  • 발신자 및 수수료 지불자 주소 추출
  • 가스 가격 계산
  • 수수료 위임 정보 반영
  • RPC 호출 시 서명 검증을 건너뛸 수 있는 플래그 포함
이를 통해 트랜잭션은 블록 실행과 RPC 시뮬레이션 양쪽에서 동일한 경로로 처리됩니다.