2주차 공부

박세연·2021년 1월 6일
3

Mastering Ethereum

목록 보기
2/10
post-thumbnail

Chapter 5. 지갑

  • 지갑: 사용자의 키를 보관(개인키를 보관)하고 관리하기 위해 사용되는 시스템

일반적인 돈을 직접 보관하는 의미의 지갑이 아니라 이더리움에서는 트랜잭션에 서명하는 개인키와 공개키의 쌍을 지갑에 넣는 것이라고 생각하면된다.

지갑에 있는 키는 트랜잭션을 서명하는데에 사용되며, 블록체인에 기록되고 이더의 소유권을 나타낸다.

  • 기존 은행은 계좌(지갑)을 해당 계좌의 주인만 내역을 볼 수 있고 잔액을 확인하고, 은행을 통해서 자금을 옮길 수 있다.
  • 탈중앙화된 시스템(블록체인 플랫폼)에서는 모든 사람이 계좌(해당 지갑 주소)의 잔액을 볼 수 있다. 하지만 이더의 소유자가 자금을 옮기고 싶다면 자신의 개인키를 이용해서 자신 소유의 이더를 송금하겠다는 것을 모두에게 납득시켜야한다.

비결정적 지갑

무작위 수 ➔ 무작위 키 추출 : 각각의 키들이 서로 관련이 없다.

  • 단점: 이더리움의 프라이버시 극대화를 위해 키 목록을 늘리는 경우, 모든 키를 백업해야하므로 비효율적이고 다루기 어렵다.

결정적(seed) 지갑

seed ➔ 여러개의 키 파생

  • 장점: 시드를 이용해서 모든 파생된 키를 복구할 수 있으므로, 백업이 쉽다.
  • 시드만 있으면 모든 키를 복원할 수 있으므로 시드에 대한 보안이 중요

HD지갑 (BIP-32/BIP-44)

비트코인의 BIP-32표준으로 정의된 HD지갑이 가장 개선된 결정적 지갑이다.

HD지갑은 트리 구조로 부모키로부터 자식키를 파생할 수 있는 구조를 보여준다.

시드와 니모닉 코드(BIP-39)

키의 백업과 검색을 위해서 개인키를 인코딩하는 방법 ➔ 니모닉

  • 니모닉: 올바른 순서로 단어 시퀀스를 입력하여 고유한 개인키를 복원하는 방법
    대부분의 이더리움 지갑은 BIP-39 표준을 이용하여 호환이 가능한 니모닉으로 시드를 가져오고, 내보낼 수 있다.

  • 장점: 16진수로된 개인키를 기록할 경우, 오류가 발생할 확률이 높다. 단순한 숫자는 오류가 발생했을 때, 복원하기 어려움.
    하지만 단어 목록을 사용하면, 'insect'가 'inzect'로 표기되는 오류가 발생하였을 때, 유효하지 않은 단어이므로 'insect'로 수정하는 등 데이터를 정확하게 보관할 수 있다.

  • 니모닉 코드 단어: 결정적 지갑의 시드로 사용되는 난수를 인코딩하는 단어 시퀀스
    단어 시퀀스 ➔ 시드(seed) ➔ 모든 파생 키

  • 지갑 애플리케이션에서 지갑을 생성할 때 단어 시퀀스를 함께 보여준다.
    숫자가 아니라 단어이므로 읽고, 기억하기 쉽고 오류를 줄일 수 있기 때문에 지갑 백업에 유용하다.

니모닉 단어 생성

니모닉 코드와 시드의 생성은 BIP-39로 정의된다. 니모닉 단어는 BIP-39에서 정의한 표준화된 절차에 따라서 지갑에서 자동으로 생성된다.

니모닉 단어 생성 프로세스

  1. 128~256비트의 무작위 암호화 시퀀스 S를 생성한다.
  2. S를 SHA-256으로 해싱한 값을 32비트로 나눈 처음 길이를 체크섬으로 생성한다.
  3. 무작위 시퀀스 S의 끝에 체크섬을 추가한다.
  4. 시퀀스와 체크섬을 연결한 것을 11비트 단위로 나눈다.
  5. 각각의 11비트 값을 사전에 정의된 2,048단어 사전과 매핑한다.
  6. 단어의 시퀀스로부터 순서를 유지하면서 니모닉 코드를 생성한다.
  7. PBKDF2 키 스트레칭 함수의 첫 번째 파라미터는 6단계에서 생성된 니모닉이다.
  8. PBKDF2 키 스트레칭 함수의 두번째 파라미터는 솔트다. 솔트는 문자열 상수 "mnemonic"과 선택적으로 사용자가 지정한 암호문을 연결하여 구성한다.
  9. PBKDF2는 최종 출력으로 512비트 값을 만드는 HMAC-SHA512 알고리즘으로, 2048 해시 라운드를 사용하여 니모닉과 솔트 파라미터를 확장하며, 이 결과로 나온 512비트 값이 시드(seed)다.

BIP-39 선택적 암호문

위의 그림에서 "mnemonic"뒤에 추가되는 암호문에따라 다른 시드를 생성한다. 동일한 니모닉 단어에서 암호문이 다르면 다른 시드가 생성된다.

  • 보안성이 뛰어나지만 손실의 위험도 있다.

시드로 HD(Hierarchical Deterministic) 지갑 생성하기

HD지갑은 128, 256 또는 512비트 임의의 숫자인 단일 루트 시드(root seed)로 부터 생성된다. (니모닉 ➔ 시드생성)

  • HD지갑의 모든 키는 루트 시드에서 결정적으로 파생
    ➔ 하위 계층의 공개키를 만들 때 상위 계층의 공개키를 사용 (상위 계층의 공개키가 하위 계층으로 상속)
    ➔ 하위 계층의 개인키로부터 공개키 생성 (2개는 동일함)
  • 모든 호환 HD지갑에서 그 시드로부터 전체 HD 지갑을 생성할 수 있다.
  • 결정적 키 생성을 위한 BIP-32표준을 따른다.

BIP-32

확장된 공개키와 개인키

HD지갑의 주요한 특징
1. 부모 공개키(상위 계층의 공개키)에서 자식 공개키(하위 계층의 공개키)를 파생할 수 있다.
2. 자식의 개인키(하위 계층의 개인키)에서 자식 공개키 파생
➔ 확장된 공개키는 HD 지갑 구조의 해당 분기(branch)에서 모든 공개키를 파생하는데 사용될 수 있다.

  • 공개키 전용 배포: 서버 또는 애플리케이션의 확장된 공개키 ➔ 무수한 수의 공개키 & 주소 생성 가능 ➔ 해당 주소로 보낸 돈은 쓸 수 없다.(개인키가 없으니까)
  • 보안서버의 확장된 개인키 ➔ 트랜잭션에 서명하고 돈을 사용하기 위해 관련된 모든 개인키를 파생할 수 있다.

강화된 자식 키의 파생

확장된 공개키가 자식 개인키에 대한 접근을 허용하지는 않지만 체인코드를 포함하므로 잠재적인 위험이 있다.

  • 체인코드: 부모 공개키에서 자식 공개키를 파생하는 데 사용

이러한 위험에 대응하기 위해서 HD지갑은 강화 파생(hardened derivation)(단정 유도법)이라고 하는 대체 가능 파생 함수를 사용해 부모 공개키와 자식의 체인코드 사이의 관계를 끊는다.

즉, 체인코드를 파생할 때 공개키 대신에 개인키를 사용함으로써 확장된 공개키를 사용하더라도 개인키의 유출을 막을 수 있다.

일반 및 강화 파생을 위한 인덱스 번호

하나의 부모 키에서는 여러 자식키를 파생할 수 있는데,(트리구조 생각) 이를 관리하기위해 자식의 순서를 나타내기 위한 인덱스 번호가 있다.

  • 인덱스 번호는 32bits 정수
  • 인덱스 번호는 특수한 자식 파생 함수를 사용해 부모 키로부터 자식 키를 얻을 수 있다. (각기 다른 자식 키를 얻을 수 있다.)
  • 일반 파생: (0x0~0x7FFFFFFF) 강화 파생: (0x80000000~0xFFFFFFFF)
    따라서 인덱스 번호의 범위에 따라 자식이 일반자식인지, 강화된 자식인지 알 수 있다.

HD 지갑 키 식별자(경로)

  • 마스터 개인키에서 파생된 개인키 : m
  • 마스터 공개키에서 파생된 공개키 : M
  • 트리의 각 레벨은 슬래시(/) 문자로 구분한다.
    m / 0 : 마스터 개인키(m)의 첫번쨰 자식 개인키
    m / 0 / 0 : 첫번째 자식(m/0)의 첫번째 자식 개인키
    M / 23 / 17 / 0 / 0 : 24번째 자식(M.23)의 17번째 자식의 첫번째 자식의 첫번째 자식의 공개키

BIP-43/44

HD 지갑 트리 구조 탐색

HD 지갑 트리 구조는 무한한 복잡성을 허용하여 각 부모의 확장키는 약 40억 개의 자식키를 가질 수 있다.
➔ 이렇게 무한하게 자식을 갖게되면 트리의 탐색이 어려울 수 있다.

  • BIP-43 : 강화된 첫번째 자식의 인덱스를 트리 구조의 목적을 나타내는 특수 식별자로 사용하도록 제안
  • BIP-44 : 목적 번호를 44'로 설정하여 복수화폐 복수계정 구조를 제안
    ➔ BIP-44를 따르는 모든 HD 지갑 구조는 단지 하나의 트리 분기(m/44'/* )만을 사용한다는 사실에 의해 식별된다.
    ➔ BIP-44는 미리 정의된 다섯가지 트리 레벨로 구성된 구조를 지정한다.
    ( m / purpose' / coin_type' / account' / change / address_index)
    • purpose' : 항상 44'로 설정

    • coin_type' : 암호화폐 동전의 유형을 지정(60'=이더리움, 61'=이더리움 클래식, 0'=비트코인, 1'=모든화폐의 테스트넷)

    • account' : 지갑을 별도의 논리적 하위 계좌로 세분화한다.

    • change: 원래 비트코인을 위해 제작된 BIP-44이므로 해당 부분은 이더리움과는 관련이 없다.
      2개의 하위트리가 있는데, 하나는 입금 주소, 하나는 잔액 주소를 작성하는데 사용되며, 이더리움에서는 잔액 주소가 필요하지 않으므로 입금 경로만 사용한다.

    • address_index : 인덱스(주소) 번호를 의미한다.




Chapter 6. 트랜잭션

  • 트랜잭션: 외부 소유 계정(EOA)에 의해 서명된 메시지로 이더리움 네트워크에 의해 전송되고 이더리움 블록체인에 기록된다.
    즉, 트랜잭션은 EVM(이더리움 가상 머신)에서 컨트랙트를 실행할 수 있는 유일한 방법

트랜잭션의 구조

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

트랜잭션 논스

  • 논스: 해당 주소에서 보낸 트랜잭션 건수 또는 연결된 코드가 있는 계정의 경우 이 계정에서 만든 컨트랙트 생성 건수와 동일한 스칼라 값 ➔ 계정에서 보내는 트랜잭션에 할당된 번호
    • 해당 주소에서 트랜잭션이 발생하면 동적으로 계산(1씩 증가)
    • 트랜잭션 생성 순서대로 포함
    • 트랜잭션 복제 방지 (지급 금액을 복제하는 행위를 막을 수 있다.)

논스의 간격, 중복 논스 및 확인

이더리움 네트워크는 논스에 따라 트랜잭션을 순차적으로 처리한다.

  • 논스가 0인 트랜잭션 뒤에 논스가 2인 트랜잭션이 전송되면, 누락된 논스가 나타날때까지 멤풀에 저장된다.
  • 논스가 1인 트랜잭션이 전송되면 순서에 맞게 2도 처리된다.

동시 실행, 트랜잭션 생성 및 논스(잘 모르겠당)

  • 동시 실행 문제: 여러 독립 시스템에 의한 동시적인 계산이 있는 경우

동일한 핫 월렛(키가 온라인에 저장된 지갑) 계정에서 여러 컴퓨터가 트랜잭션을 생성, 서명 및 브로드캐스트하는 경우

  1. 단일 컴퓨터를 사용하여 트랜잭션에 서명한는 컴퓨터에 선착순으로 논스 할당
  2. 트랜잭션 생성시 논스를 할당하지 않음. (트랜잭션은 서명되지 않은 상태)
    해당 트랜잭션을 한 노드의 대기열에 올려서 노드가 트랜잭션을 서명하고 논스를 관리할 수 있게 한다.

트랜잭션 가스

  • 가스(gas): 이더리움의 연료. 이더에 대한 자체 환율을 가진 별도의 가상 화폐
    이더리움은 튜링 완전한 모델이기때문에 많은 자원을 소모하는 트랜잭션을 방지하기 위해서 가스를 이용해 사용할 수 있는 자원의 양을 제한한다.
  • 트랜잭션의 gasPrice 필드: 트랜잭션 생성자가 가스와 교환하여 지급할 가격을 설정할 수 있음.
  • gasPrice가 높을 수록 트랜잭션은 더 빨리 컨펌된다.(우선순위 높음)
  • gasPrice의 최솟값은 0으로, 무료 트랜잭션(수수료 0)을 생성할 수 있음을 의미한다.
  • 트랜잭션의 gasLimit 필드: 트랜잭션을 완료하기 위해 트랜잭션을 시도하는 사람이 최대로 구매할 수 있는 가스의 단위 수
  • 트랜잭션을 보내기 전에 지급할 의사가 있는 최대 금액만큼(구매할 수 있는 가스 단위 만큼) 잔액이 있어야한다.

트랜잭션 수신자

트랜잭션 수신자는 20바이트 이더리움 주소로, EOA(외부 소유 계정) 혹은 컨트랙트 주소일 수 있다.

  • 트랜잭션 수신자의 주소 필드는 검증하지 않는다.
  • 모든 20바이트 값은 유효한 것으로 간주
  • 잘못된 주소로 트랜잭션을 보내면, 수신한 주소와 개인키를 알 수 없기 때문에 보내진 이더는 영원히 사용할 수 없는 상태가 된다.(소실)

트랜잭션 값과 데이터

  • 지급(Payment): 값(value)만 있는 트랜잭션
    ➔ 대상 주소가 EOA 주소인 경우: 이더리움은 상태 변경을 기록하고, 주소 잔액에 보낸 값을 추가한다.
    ➔ 대상 주소가 컨트랙트인 경우: EVM이 컨트랙트를 실행하고 트랜잭션의 데이터 페이로드에 지정된 함수를 호출하려고 시도한다.
        트랜잭션에 데이터가 없다면 폴백(fallback)함수를 호출한다.

  • 호출(invocation): 데이터(data)만 있는 트랜잭션
  • 지급과 호출: 값과 데이터를 모두 갖는 트랜잭션
  • 값과 데이터가 모두 없는 트랜잭션 : 단순한 가스 낭비(가능한 트랜잭션)

트랜잭션에 데이터가 포함된다면, 받는 주소는 컨트랙트 주소가 될 가능성이 크다.
이렇게 데이터를 전달하는 것은 컨트랙트 호출로 해석된다.즉, 컨트랙트에 정의된 함수를 호출하고 인코딩된 인수를 함수에 전달한다.

특별 트랜잭션: 컨트랙트 생성

  • 컨트랙트 배포: 새로운 컨트랙트를 배포하는 트랜잭션의 경우, 수신자 주소가 0x0(제로 어드레스)이다.
  • 0x0(제로 어드레스)
    EOA나 컨트랙트 주소가 아니다.
    컨트랙트 배포를 위한 목적지로만 사용된다.
    이더 손실이나 의도적인 이더 연소를 위한 목적지가 되기도 한다.

디지털 서명

디지털 서명의 용도
1. 이더리움 계정과 개인키의 소유자가 이더 지출 혹은 컨트랙트 이행을 승인했음을 증명
2. 부인 방지. 즉 승인한 내용을 부인할 수 없음.
3. 트랜잭션이 서명된 후에는 트랜잭션 데이터는 수정될 수 없음을 증명한다.

profile
안녕하세요

0개의 댓글