마스터링 이더리움 5, 6장

쌍제이(JJVoiture)·2022년 8월 1일
0

5장 - 지갑

지갑은 개인키를 보관하고 키를 관리하는 keychain.
-> 이더 또는 토큰을 보유하는 게 아니다.

비결정적(nondeterministic) 지갑
: 각각의 키를 무작위적으로 추출

결정적(deterministic) 지갑
: seed라고 하는 단일 마스터 키로부터 파생.

HD 지갑 (hierachical deterministic)
: BIP(Bitcoin Improvement Proposal)-32를 따르는 지갑.

mnemonic code
: 데이터 분실 등의 사고에 대비하여 시드를 단어 목록으로 인코딩.

FCCF1AB3329FD5DA3DA9577511F8F137

wolf juice proud gown wool unfair
wall cliff insect more detail hub

니모닉 코드 생성

  1. 암호학적으로 랜덤한 128~256 bits의 시퀀스 S를 만든다.
  2. S의 SHA-256 해시값 중에서 앞(왼쪽)에서 S의 길이 / 32비트만큼을 체크섬으로 만든다.
  3. 2번에서 만든 체크섬을 S의 끝에 추가한다.
  4. 3번에서 만든 시퀀스와 체크섬의 연결을 11 bits 단위로 자른다.
  5. 각 각의 11비트를 2048(2^11)개의 미리 정의된 단어로 치환한다.
  6. 단어 시퀀스로부터 순서를 유지하면서 니모닉 코드를 생성한다.

시드 생성

  1. PBKDF2 키 스트레칭 함수의 첫 번째 파라미터는 6번 단계에서 만든 니모닉이다.
  2. 두 번째 파라미터는 솔트이다. 솔트는 상수 문자열 "mnemonic"에 사용자가 지정한 암호문을 붙인 것이다.
  3. PBKDF2는 니모닉과 솔트를 HMAC-SHA512로 2048번의 해싱해서 512 bits 값을 만들어 내는데, 이 값이 시드이다.

key 스트레칭 함수?

HD 지갑

BIP(Bitcoin Improvement Proposal)-32를 따르는 deterministic 지갑.

HD Wallets

확장 키

키는 확장 가능하다.

  • 트리 계층 구조에서, 어느 키든 부모 키가 되어 자식 키를 파생시킬 수 있다.

  • 키 확장은 키에 특수 체인 코드를 추가하는 것을 말한다.
    - 체인 코드란 자식 키를 생성하기 위해 공개키/개인키와 혼합된 256비트 이진 문자열이다.
    - 개인키라면, 접두어 xprv로 구분되는 확장된 개인키가 된다.
    - 공개키라면, 접두어 xpub으로 구분되는 확장된 공개키가 된다.

  • 개인키가 없는 공개키에서도 자식 공개키를 파생할 수 있다.
    - 자식 공개키는 자식 개인키에서 직접 파생하거나 부모 공개키에서 파생할 수 있다.
    - 따라서 확장된 공개키는 자기 브런치에서 모든 공개키를 파생시키는데 사용 가능하다.
    - 공개키만을 파생시킬 수도 있다.

이걸 이용해서 공개키 전용 배포를 만들 수 있다. 웹서버에서 입금받을 일이 있을때마다 공개키를 확장시켜 새로운 주소를 만드는 것이다. 괜히 개인키까지 같이 만들어서 도난 걱정을 할 필요도 없어서 좋다.

강화 파생

이처럼 확장된 공개키에서 공개키를 파생하는 것은 유용하지만, 잠재적 위험이 있다.

  • 확장 공개키와 자식 개인키를 알면 다른 자식 개인키 전부를 얻을 수 있다.
    - 이는 xpub에 체인 코드가 포함되어있기 때문이다.
  • 부모 체인코드와 자식 개인키가 알려지면 부모 개인키를 추론 가능하다.

이런 위험성 때문에, 강화 파생(hardend derivation)이라고 하는 대체 가능 파생 함수가 사용된다.

  • 부모 공개키와 자식 체인 코드간 관계를 끊는다.
  • 부모 공개키를 사용하지 않고 부모 개인키를 사용해서 자식 체인코드를 만든다.
  • 보안상 마스터키의 1세대 자식들은 항상 단절 유도법을 통해 생성된다.

0 ~ 2^31 - 1사이의 인덱스 번호
: 일반 파생 함수를 통해 파생된 키

  • 0x0 ~ 0x7FFFFFFF

2^31 ~ 2^32 - 1 사이의 인덱스 번호
: 강화 파생 함수를 통해 파생된 키

  • 0x80000000 ~ 0xFFFFFFFF

강화된 자식의 인덱스 번호가 읽기 어려우므로 0x80000000을 0'으로 표기.
-> 2^31 + i == i'

HD 지갑 트리 구조 탐색

m / purpose' / coin_type' / account' / change / address_index

purpose': 항상 44'
coin_type': 암호화폐 유형 ex) 이더리움은 60', 비트코인은 0'
account’: 지갑을 여러 목적에 따라 하위 계좌로 분리 가능
change: 강화 파생 x, 입금 주소 작성용 / 잔액 주소 작성용 --> BIP-44가 비트코인을 위해 작성된 것이어서 이더리움에서는 사용하지 않는다.
address_index’: 사용 가능 주소가 파생되는 레벨

6장 - 트랜잭션

트랜잭션은 상태 변경이나 컨트랙트를 실행할 유일한 방법.

아래 데이터를 포함하는 serialize된 binary message

  • 논스(nonce): 발신 EOA에 의해 발행되어 메세지 재사용을 방지하는 데 사용되는 일련번호
  • 가스 가격(gas price): 발신가자 지급하는 가스의 가격(웨이, wei)
  • 가스 한도(gas limit): 이 트랜잭션을 위해 구입할 가스의 최대량
  • 수신자(recipient): 목적지 이더리움 주소
  • 값(value): 목적지에 보낼 이더의 양
  • 데이터: 가변 길이 바이너리 데이터 페이로드
  • v,r,s: EOA의 ECDSA 디지털 서명의 세 가지 구성요소
  • 발신자에 대한 정보는 v,r,s로부터 알아낼 수 있다.

트랜잭션 논스

  • 모든 트랜잭션은 일회성이고 고유하다.
  • 논스(nonce)는 계정에서 보내는 트랜잭션에 할당 된 번호이다.
  • 거래(transaction)를 전송시 nonce는 1씩 증가한다.
  • 논스는 계정에서 유일하기 때문에 동일한 논스가 존재하지 않는다.

--> 이중 지불 문제 방지

Gas

노드가 작업을 처리함에 있어서 우선 순위를 정할려면 이더리움의 작업을 수치화해야 한다. gas price가 높을 수록 우선 순위가 높게 처리된다.
튜링 완전 계산 모델은 DoS 공격이나 막대한 자원을 소모하는 트랜잭션을 피해야 하는데, 이를 위해 트랜잭션에 gas limit을 지정하는 것.

수신자

20바이트 이더리움 주소(EOA or contract)가 포함되는데 모든 20바이트 값은 유효한 것으로 간주하므로 없는 주소로 보내서 이더가 연소될 수 있다.

Zero Address

새로운 컨트랙트를 만들기 위해 배포하는 트랜잭션이 있는데 이 트랜잭션은 zero address라고 하는 주소로 전송된다. 해당 주소는 0x0를 포함한다.

Digital Signature

이더리움에서는 타원곡선을 사용한 ECDSA가 사용된다. 전자 서명은 이더리움에서 개인키의 소유주, 즉 계정의 소유주가 트랜잭션을 실행했다는 것을 공인하고 트랜잭션이 사인된 후에는 변경되지 않았다는 것을 검증한다.
전자 서명은 개인키를 바탕으로 서명을 만드는 알고리즘과 메시지(트랜잭션)와 공개키 만으로 서명을 검증 가능하게 해주는 알고리즘으로 이루어진다.

Sig=F_sig(F_keccak256(m),k)

K는 서명하는 개인키, m은 RLP로 인코딩된 트랜잭션, Fkeccak256 은 keccak256, Fsig 은 서명 알고리즘, Sig 는 생성된 전자서명이다. 이로 생성된 Sig 는 r, s 두가지 값으로 이루어진다.
서명 검증 알고리즘은 메시지, 서명자의 공개키, 전자서명을 input으로 받고 참 거짓 여부를 반환한다.

이더리움의 트랜잭션 서명 과정

  1. 9개의 값을 받는 트랜잭션 자료 구조 생성
  2. 트랜잭션을 RLP 인코딩
  3. Keccak-256 계산
  4. EOA 개인키로 ECDSA(타원곡선 서명 알고리즘) 서명을 계산한다
  5. 결과값 서명의 v, r, s 값을 트랜잭션에 집어넣는다.

EIP-155 단순 반복 공격 방지

서명하기 전 트랜잭션 데이터에 chain identifier를 포함한다.

네트워크에 따라 ID 부여. 예를 들면 메인넷은 1, Ropsten은 3

이를 통해 한 블록체인 네트워크에서 생성된 트랜잭션을 다른 블록체인 네트워크에 올릴 수 없게 하여 반복 공격을 막는다. Chain identifier와 0, 0 총 3가지 필드를 추가하는데 이들은 인코딩 전에 트랜잭션 데이터에 포함되어 트랜잭션 데이터의 해시값이 변한다.

트랜잭션 전파, 전파 과정

이더리움에서 트랜잭션 전파는 시작 노드에서 다른 노드들로 P2P 방식으로 전파된다.

전파과정은 다음과 같다.

트랜잭션이 생성되면 생성한 노드로부터 직접적으로 연결되어 있는 노드들로 (평균 13개 정도) 전파된다. 해당 노드들이 검증한 후에 복사본을 만들어 저장하고 그들의 이웃으로 전파한다. 그 결과 네트워크 전체로 파도처럼 퍼지게 된다. 수초 만에 전세계의 노드들로 트랜잭션은 퍼지게 되고 공격자는 상당한 양의 노드를 소유하고 있지 않은 이상 트랜잭션의 발원지를 찾을 수 없다.
검증된 트랜잭션은 블록에 담겨 이더리움 블록체인 위에 기록되게 된다.


profile
안녕하세요. 중구난방 개발자 쌍제이입니다.

0개의 댓글