마스터링 이더리움(Mastering Ethereum) 5장 - 지갑

JinJinJJara·2021년 1월 9일
2

Mastering_Ethereum

목록 보기
1/11

스크립토 6기 하진원입니다.
스크립토 방학 스터디로 마스터링 이더리움 공부하고 있습니다.

지갑의 의미

  • 넓게 보면 지갑은 이더리움에서 주요 UI로 작용하는 소프트웨어 앱이다. 지갑은 사용자의 자산을 관리하고 키와 주소 관리, 자산 추적, transaction 서명등을 한다.

  • 좁게 보면(개발자의 관점에서 보면) 사용자의 키를 보관하기 위한 시스템이다. 모든 지갑은 키를 관리하는 기능은 있고 다른 기능들은 브라우저, 즉 DApps의 인터페이스로 사용된다. 뚜렷한 지갑의 정의는 아직도 이루어지지 않았다.

지갑의 고려할 점

주요 고려해야 할 점은 편리성보안의 균형이다. 하나의 키와 주소를 매번 사용하면 편하지만 보안이 취약할 것이고 매 거래마다 키와 주소를 새로 사용하면 안전하지만 거래가 매우 힘들다.

보통 이더리움 지갑 안에 ether가 들어있다고 하지만 이는 틀린말이다. 지갑은 오직 키를 가지고 있고 ether나 token은 체인위에 기록된다. 사용자는 키를 이용해 체인 위의 ether나 token을 관리한다.

또, 유의할 점은 탈중앙화 시스템은 중앙화 시스템과 다르다는 것이다. 기존의 중앙화 시스템에서는 은행같이 계좌의 소유주만 관리하고 은행을 통해 거래가 이루어지지만 탈중앙화 방식에서는 모두가 계좌를 볼 수 있고 잔고를 볼 수 있으며(소유주가 누구인지는 알지 못하지만) 거래를 위해서는 모두가 검증해야 한다. 이는 계정의 잔고는 지갑을 통하지 않아도 확인할 수 있고 지갑 변경이 가능하다는 것을 말한다.

지갑의 종류

지갑 내의 키가 서로 연관되어 있는지에 따라 나뉜다.

  1. 비결정적 지갑

  2. 결정적 지갑

비결정적 지갑

비결정적 지갑은 키들이 서로 다른 무작위 수로부터 생성되는 것으로 JBOK 지갑이라고도 한다. 초창기 이더리움 지갑들은 랜덤하게 생성된 하나의 개인키가 각각 저장된 비결정적 지갑이었다.

단점

많은 자금을 다루게 되면 키가 늘어나고 주기적으로 백업을 해주어야 하는데 데이터 백업이 일어나기 전에 손실된다면 자금과 스마트 컨트랙트를 잃는다.
키가 서로 연관되지 않기 때문에 매 새로운 주소마다 새로운 지갑 파일을 생성해야 한다.

결정적 지갑

결정적 지갑은 seed로부터 생성된 개인키들을 보관하는 지갑이다. Seed는 랜덤하게 생성된 숫자이고 개인키를 생성하기 위해 인덱스 번호 혹은 체인 코드와 같은 데이터와 연결되어 있다. Seed를 통해 그에서 생산된 키들을 회수할 수 있기 때문에 생성될 때 백업을 한번만 진행하면 충분하다. 따라서 지갑을 옮길 때도 용이하다. 이 방법은 seed를 통해 해당 지갑을 접근할 수 있기 때문에 seed 보안의 중요성이 매우 크다.

계층 결정적 지갑(HD)

HD 지갑은 가장 진화된 지갑 형태로 키가 트리구조로 생성되어 자식 키들도 또 자식 키를 생성할 수 있는 구조이다.

장점

HD는 단순한 결정적 지갑에 비해 장점을 가지는데
1. 추가적인 조직적 의미를 나타낼 수 있다. 즉, 트리에 생기는 여러 브랜치들을 각기 다른 경우에 사용할 수 있다.
예를 들면 특정 브랜치는 돈을 수신받을 때, 특정 페이지는 잔돈을 받을 때 사용하는 등 사용 용도에 따라 다른 브랜치를 사용할 수 있다.
2. HD 지갑은 사용자가 개인키에 접속하지 않고도 연속된 공용키를 생성할 수 있다.

이중 HD 지갑의 큰 장점은 개인키 없이 자식 개인키를 만들 수 있는 것이다. 이를 확장된다(extend)라고 표현한다. HD 지갑에서 확장된 키는 키와 더불어 체인코드를 포함한다. 체인코드는 256bit 문자열로 자식 키를 만들어내기 위한 각각의 키가 섞여 있다.

Hardened derivation(강화된 유도)

확장된 키의 단점은 확장된 키는 체인코드를 가지고 있기 때문에 자식 개인키가 유출된다면 다른 자식 개인키도 알 수 있다는 것이다.

이를 보완하기 위해 Hardened derivation(강화된 유도)를 사용한다. 이 방법은 부모 공개키와 자식 체인코드를 끊어내고 대신 부모 비밀키를 통해 자식 체인코드를 구한다.

하나의 부모키로부터 여러 개의 자식키를 만들고 구분하기 위해 인덱스를 부여한다. 일반 유도 방식과 강화된 유도 방식을 구분하기 위해 인덱스 번호를 0~231-1(일반 유도 방식), 231~232-1(강화된 유도 방식)으로 구분한다.

HD의 복잡성 관리

HD 지갑 트리 구조는 대단히 유연함과 동시에 복잡하다. 모든 부모는 40억개의 자식을 가질 수 있다. 따라서 트리는 원하는 만큼 깊어질 수 있다. 그렇기 때문에 BIP-43, BIP-44를 통해 지갑의 표준을 만들어 복잡성을 관리한다.
BIP-43은 첫번째 hardened child index를 트리의 목적을 드러내는 것으로 사용한다. HD 지갑이 m/I’/…이라고 하면 해당 지갑은 i로 지정한 특정 목적에만 사용되는 것이다.
BIP-44는 BIP-43에 용도를 위한 숫자를 추가하여 다양한 암호화폐와 계정에 사용이 가능하게 한다.

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

해당 형식을 따르게 되는데
purpose’는 항상 44’로 설정되어 있다.
coin_type'는 암호화폐의 종류를 지정한다. 예를 들면 이더리움은 60’, 비트코인은 0’ 등이 있다.
Account’는 사용자가 목적에 따라 세분할 수 있게 해준다.
Change'는 비트코인이 수신 주소와 잔돈 주소가 따로 있는 것에서 유래한 것인데 이더리움은 수신 주소만 사용하기 때문에 항상 0이다.
address_index는 그 다음 자식의 인덱스이다.

시드와 니모닉(mnemonic) 코드

니모닉 코드는 개인키를 안전하게 보관하고 찾기 위해 여러 개의 단어로 인코딩하는 방식이다. 예시로는 메타마스크가 있다.

  • 단어들을 맞는 순서로 입력하면 개인키를 다시 찾을 수 있는 방법으로 많은 이더리움 지갑에서 사용되고 있다. 해당 방법이 사용되는 이유는 단순히 무작위의 글자를 조합하는 것보다 사용하는 입장에서 덜 틀리기 때문이다. 즉, 백업이 쉽기 때문이다. E.g) adhdnl보다 insect가 더 쉬움.

니모닉 코드 구성

니모닉 코드 단어는 seed를 인코딩한 단어들의 조합이다. 단어들의 조합을 통해 seed를 구할 수 있고 그로 지갑과 파생된 키를 구할 수 있다. 보통 12~24개 단어의 조합으로 이루어져 있는데 이는 지갑의 백업으로 호환되는 지갑에서 키를 복원할 때 사용할 수 있다.

니모닉 코드 생성

니모닉 코드는 지갑에 의해 자동으로 생성되는데 6가지 단계를 밟는다.

  1. 암호학적으로 랜덤한 128~256 사이의 비트 시퀀스 s 생성
  2. S의 SHA-256 해시값 중에서 S의 길이/32를 S의 checksum으로 만든다.
  3. Checksum을 s 뒤에 잇는다.
  4. S를 11bit단위로 자른다.
  5. 각 11bit를 211개의 미리 정의된 단어로 바꾼다.
  6. 해당 단어 순서를 유지하며 니모닉 코드를 만든다.

P.S. 처음 비트 시퀀스 s는 32의 배수이고 항상 11의 배수로 떨어진다는 것을 알 수 있다.

니모닉 코드에서 시드 구하기

니모닉 코드를 통해 seed를 구하는 것은 3 단계를 밟는다.
각 니모닉 단어들은 128~256사이의 비트를 상정하는데 키 스트레칭 함수 PBKDF2를 통해 512 비트로 늘린다. 키스트레칭 함수는 니모닉과 salt를 입력값으로 받는데 salt는 brute-force 공격이 가능케하는 lookup table을 힘들게 하는 효과가 있다.

  1. 생성된 니모닉을 첫번째 파라미터로 PBKDF2에 집어넣는다.
  2. Salt를 두번째 파라미터로 넣는다. Salt는 mnemonic에 사용자가 지정한 문구를 붙인 것이다.
  3. PBKDF2가 입력받은 니모닉과 salt를 사용하여 HMAC-SHA512로 2048번 해싱하여 512비트 값을 구하고 그가 seed이다.

선택적 암호문

BIP-39는 seed 생성할 때 선택적 암호문을 사용할 수 있다고 정의한다(salt에서 mnemonic뒤에 붙이는 것을 말한다). 선택적 암호문을 사용하면 PBKDF2는 같은 니모닉이라도 다른 seed를 만든다.
선택적 암호문을 사용할 때 장점은 니모닉이 유출되어도 안전하다는 것이다. 단점은 암호문을 아는 사람이 죽거나 잊는다면 자산을 잃고 이를 방지하기 위해 암호문을 기록한다면 그 의미가 퇴색된다.
니모닉코드 생성은 python, javascript 등 다양한 언어에서 library로 구현되어 있고 생성 웹페이지도 있다.

지갑의 좋은 예

암호화폐 지갑은 발전하여 지갑의 사용성, 보안성, 유연성 등은 모두 발전했다. 지갑의 일반적인 표준은

  • 니모닉 코드 단어
  • HD 지갑
  • Multipurpose HD wallet structure
  • Multicurrency and multiaccount wallet
    등이 있다.

이 표준은 다양한 암호화폐 지갑들에 적용되어 서로 연동 가능하게 되어 있다. 예시로 사용자는 한 지갑의 니모닉을 다른 지갑으로 전할 수 있다.
해당 표준을 지키는 지갑들은 Jaxx, MetaMask, Mycrypto 등이 있다.

profile
갈팡질팡 공부하는 중입니다

0개의 댓글