관리 메뉴

개발이야기

[마스터링 이더리움] Mastering Ethereum - Wallet 본문

블록체인 /마스터링 이더리움

[마스터링 이더리움] Mastering Ethereum - Wallet

안성주지몬 2018. 10. 23. 00:00

지갑


지갑은 이더리움에서 기본 사용자 인터페이스 역할을 하는 응용 프로그램입니다. 지갑은 사용자의 자금 접근 권한, 키와 주소 관리, 잔액 확인과 트랜잭션작성, 그리고 서명을 제어합니다. 또한 일부 이더리움 지갑은 ERC20 토큰같은 계약과 상호작용을 합니다.

개발자 관점에서는 지갑은 사용자의 키를 저장하고 관리하는데 사용되는 시스템으로 모든 지갑에는 이를 관리하는 구성 요소가 있습니다. 일부 지갑은 키 저장 및 관리에 대한 기능만 있고, 어떤 지갑은 이더리움 기반 분산 응용프로그램이나 Dapp에 대한 인터페이스로 활용됩니다.



지갑의 기술

지갑을 만들 때 중요한 사항으로는 편의성과 개인 정보를 보호하는 것 입니다. 가장 편리한 점으로는 이더리움 지갑은 다시 사용가능한 개인키와 주소를 관리하는 것 입니다. 이것은 모든 사람이 트랜잭션을 쉽게 추적하고, 연관시킬 수 있기 때문에 보안면에서는 좋지 않습니다. 트랜잭션 생성시 새로운 키를 사용하는 것이 정보 보호를 하는데 적절하지만, 이렇게하면 키 관리가 매우 어려워집니다.

우리가 잘못알고 있는 것은 이더리움 지갑이 이더나 토큰을 직접 소유하고 있다는 것입니다. 사실 지갑에는 키 값만 소유하고 있습니다. 이더나 토큰에 대한 정보는 이더리움 블록체인에 기록됩니다. 사용자는 지갑에 있는 키를 사용하여 트랜잭션에 서명함으로 토큰을 제어할 수 있습니다. 따라서 이더리움 지갑은 키 체인으로 이해할 수 있습니다. 하지만 지갑의 키가 이더나 토큰을 다른 사람에게 전송할 수 있는 유일한 수단이므로 이것을 구분짓는 것은 무의미합니다. 중요한 차이로는 기존의 은행에서 사용하는 중앙화된 시스템에서 탈중앙화 시스템으로 바꾸는 것입니다. 이것은 계정의 소유자는 알지 못하지만 모든 사람이 계정에 대한 이더 잔액을 확인할 수 있고, 이더 소유자는 트랜잭션을 생성할때 이더의 송금에 대한 컨펌을 해줘야 한다는 것입니다.  그리고 지갑 없이 계정의 잔액을 확인할 수 있는 방법이 있습니다. 그리고 지갑에서 다른 지갑으로 계정을 옮길 수도 있습니다.

지갑은 키의 연관 관계에 따라 구분하여 총 두 가지로 나누어집니다. 첫번째는 비결정적인 지갑입니다. 여기서 각 키는 랜덤하게 생성되며 독립적입니다. 두번째는 모든 키가 시드와 마스터키에서  파생되어 생성되는 결정적 지갑입니다. 모든 키는 서로 연관되며 시드가 있으면 재생성이 가능합니다. 결정론적에는 다양한 키 유도방법이 있는데 가장 일반적인 방법은 트리형 구조를 사용하는 것이며 계층적 결정적인 것과 HD 지갑이 있습니다.

데이터 손실에 대비하여 결정적 지갑을 안전하게 유지하려면 시드를 단어 목록으로 인코딩하여 사용하는 방법이 있습니다. 이를 니모닉 코드라고 합니다. 다른 사람이 니모닉 코드를 보유하면 지갑을 재생성할 수 있으므로 이더와 스마트 컨트랙트에 접근할 수 있습니다.



비결정적 지갑

비결정적 지갑은 무작위로 생성된 개인키가 저장됩니다. 비결정적 지갑은 많은 면에서 안좋은 면이 많아서 결정적 지갑으로 대체되는 추세입니다. 송금받을 때마다 새로운 주소를 사용하는 것은 이더리움 주소를 재사용하는 것보다 토큰을 많이 사용하게 되지만 개인 정보 보호를 수월하게 할 수 있습니다. 이 과정에서는 정기적으로 키 목록을 늘려야하므로 정기적인 백업이 필요합니다. 백업 전에 데이터를 손실하게되면 스마트 컨트랙트에 대한 접근 권한을 잃게됩니다. 비결정적 지갑은 새 주소에 대한 파일을 매번 만들기 때문에 처리에 어려움이 있습니다. 그럼에도 많은 이더리움 클라이언트는 보안 강화를 위해 개인키가 들어있는 암호화된 JSON 인코딩 파일을 사용합니다.


{

   "address": "001d3f1ef827552ae1114027bd3ecf1f086ba0f9",

   "crypto": {

       "cipher": "aes-128-ctr",

       "ciphertext": "233a9f4d236ed0c13394b504b6da5df02587c8bf1ad8946f6f2b58f055507ece",

       "cipherparams": {

           "iv": "d10c6ec5bae81b6cb9144de81037fa15"

       },

       "kdf": "scrypt",

       "kdfparams": {

           "dklen": 32,

           "n": 262144,

           "p": 1,

           "r": 8,

           "salt": "99d37a47c7c9429c66976f643f386a61b78b97f3246adca89abe4245d2788407"

       },

       "mac": "594c8df1c8ee0ded8255a50caf07e8c12061fd859f4b7c76ab704b17c957e842"

   },

   "id": "4fcb2ba4-ccdb-424f-89d5-26cce304bf9c",

   "version": 3

}



키 저장소는 Brute force, Dictionary, Rainbow table 공격으로부터 보호하는 KDF 암호확장 알고리즘을 사용합니다. 암호문은 직접 암호화되지 않고 262,144번 해싱하여 적용합니다.




결정적 지갑

결정적 지갑은 하나의 시드에서 파생된 개인키를 갖는 지갑입니다. 시드는 인덱스 번호나 체인 코드같이 다른 데이터와 결합되어 랜덤하게 생성된 번호입니다. BIP-32를 사용하여 랜덤한 개인키를 생성하게 됩니다. 시드에서 모든 키를 생성하기 때문에 시드만 백업하더라도 자금과 스마트 컨트랙트 접근 권한을 보호하는데 충분합니다. 지갑 내보내기나, 가져오기에도 간단하기 때문에 지갑의 교체가 쉽습니다. 시드만 있으면 지갑을 액세스할 수 있기 때문에 시드를 보호하는데 최선을 다해야 합니다.




HD Wallet(BIP-32 / BIP-44)

결정적 지갑은 하나의 시드에서 많은 키를 생성할 수 있습니다. 현재 가장 진보된 지갑은 비트코인에서 BIP-32에 의해 정의된 HD 지갑입니다. HD 지갑은 트리구조로 되어있으며 상위 키가 하위 키를 생성할 수 있습니다.

HD 지갑은 다른 결정적 지갑에 비해 다음과 같은 장점이 있습니다.

첫째로는 트리구조를 사용하여 특정 분기에서 입금받고, 다른 분기에서 지불의 변경 사항을 수신하는 등의 조직적인 구조를 만들 수 있습니다. 기업을 예로 든다면 부서, 자회사, 회계 등 분기별 다른 역할을 수행할 수 있습니다.

두번째 장점은 사용자가 개인키에 접근하지 않고 공개키를 생성할 수 있습니다. 따라서 HD 지갑은 서버나 수신 전용으로 사용할 수 있습니다. 자금을 사용할 수 있는 개인키가 없기 때문입니다.



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

안전한 백업을 위해 개인키를 인코딩 하는 방법으로 여러가지가 있지만, 선호되는 방법은 니모닉으로 BIP-39를 사용하여 단어 목록을 만드는 것입니다.

니모닉은 다음과 같은 형태입니다.


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



니모닉을 활용하여 16진수 시드를 생성할 수 있고, 시드는 16진수 형태로 FCCF1AB3329FD5DA3DA9577511F8F137와 같이 표현됩니다.



16진수는 오류 발생 확률이 높지 않지만, 니모닉은 사용하기 쉽습니다. 영어 단어이기 때문에 inzect라는 단어가 들어오면 유효하지 않은 단어이므로 insect가 사용되어야 한다고 확인할 수 있습니다. 시드 하나만으로 지갑을 복원할 수 있기 때문에 백업에 신중을 가해야 합니다.

Wallet Best Practices

암호화폐 지갑 기술이 발전됨에 따라 암호화폐 지갑을 광범위하게 상호 운용 가능하고, 사용하기 쉽고, 안전하고, 융통성을 갖도록 만드는 몇 가지 공통된 업계 표준이 등장했습니다.

또한 [ 이러한 표준들은 암호화폐 지갑이 하나의 니모닉으로부터 여러 개의 서로 다른 암호화폐에 대한 키를 만들도록 허용합니다 ] 공통된 업계 표준은 다음과 같습니다.


BIP-39 기반 니모닉 코드 단어


BIP-32 기반의 HD 지갑


BIP-43 기반 다용도 HD 지갑 구조


BIP-44 기반 다중 통화 및 다중 계정 지갑


이러한 표준들은 향후 개발로 인하여 변경 되거나 폐기 될 수 있지만, 현재로서는 대부분의 블록체인 플랫폼과 해당 플랫폼의 암호화폐에 대한 사실상의 암호화폐 표준이 되어가는 일련의 인터로킹(연동)기술을 만들고 있습니다.


이 표준은 대부분의 소프트웨어 및 하드웨어 지갑에서 채택되어 이러한 지갑들이 상호 운용될 수 있도록 만들고 있습니다. 사용자는 이러한 지갑들중 하나에서 생성된 니모닉을 다른 지갑으로 가져와 모든 키와 주소를 복구할 수 있습니다.


이러한 표준을 채택하고 있는 소프트웨어 지갑의 예로 Jaxx, MetaMask, MyCrypto 및 MyEtherWallet (MEW)이 있습니다. 마찬가지로 이러한 표준을 채택하고 있는 하드웨어 지갑의 예로 Keepkey, Ledger, and Trezor가 있습니다.


다음 절에서는 이러한 기술들을 자세히 살펴봅니다.


Tip 이더리움 지갑을 구현하려는 경우,  BIP-32, BIP-39, BIP-43 및 BIP-44 표준에 따라 백업을 위한 니모닉 코드로 인코딩 된 시드를 사용하여 HD 지갑으로 구축해야합니다. 다음 절에서 설명합니다.

Mnemonic Code Words (BIP-39)

Mnemonic code는 결정론적 지갑을 만들기 위해 시드로 사용되는 난수를 인코딩하는 연속적인 단어입니다. 연속적인 단어는 시드를 재생성하기에 충분하며 거기에서 지갑과 모든 파생된 키를 다시 만듭니다. mnemonic 단어가 있는 결정론적 지갑을 구현하는 지갑 응용프로그램은 처음 지갑을 만들 때 사용자에게 12 ~ 24개의 연속적인 단어를 보여줍니다.

연속적인 단어는 지갑의 백업용도이며 동일하거나 호환되는 지갑 응용 프로그램의 모든 키를 복구하고 다시 생성하는데 사용될 수 있습니다. 위에서 설명했듯이 mnemonic 단어 목록은 읽기 쉽고 정확하게 바꿔 쓸 수 있으므로 사용자가 쉽게 지갑을 백업할 수 있습니다.


Tip mnemonic 단어는 종종 brainwallets와 혼동됩니다. 둘은 같지 않습니다. 가장 큰 차이점은 brainwallets이 사용자가 선택한 단어로 구성되는 반면 mnemonic 단어는 지갑에서 임의로 생성되어 사용자에게 제공되어집니다. 이 중요한 차이점은 mnemonic 단어를 훨씬 더 안전하게 만듭니다. 왜냐하면 인간은 무작위성에 취약하기 때문입니다. 아마도 더 중요한 것은  ‘brainwallets’이라는 용어를 사용하는 것은 단어를 외워야한다는 것을 의미하고, 이는 별로 좋지 않은 생각이며 필요할 때 백업을 안하게 될 것입니다.


mnemonic 코드는 BIP-39에 정의되어있습니다. BIP-39는 mnemonic 코드 표준의 하나의 구현입니다. 이더리움, 비트코인 지갑과 이전버전의 BIP-39가 사용하는 일련의 다른 단어집합은 각각 다른 표준을 가지고 있습니다. BIP-39는 Trezor hardware wallet를 사용하는 회사에서 제안했으며 이더리움과 상호호환 되지 않았었습니다. 하지만  BIP-39는 현재 수십개의 상호운용 가능한 구현에 대한 업계의 지지를 받고 있으며 사실상 업계 표준으로 간주되고 있습니다. 또한 BIP-39는 이더리움을 지원하는 다중통화 지갑을 만들수 있도록 사용될 수 있지만 이더리움 seed는 그렇게 하지 못합니다.


BIP-39는 mnemonic 코드와 seed의 생성을 정의합니다. 이를 우리는 9단계에 걸쳐서 설명할 것입니다. 명확하게 프로세스는 두개의 파트로 분리됩니다. 단계 1에서 6단계는 Generating mnemonic words에서 나타나고 단계 7에서 9단계는 From mnemonic to seed에서 나타납니다.


Generating mnemonic words


mnemonic 단어는 BIP-39에 정의 된 표준화 된 프로세스를 사용하는 지갑에서 자동으로 생성됩니다. 지갑은 a source of entropy에서 시작하여 checksum을 추가하고 단어 리스트에 다음 entropy을 맵핑합니다.


1. 128비트에서 256비트의 암호화된 랜덤 sequence S를 만듭니다.


2. Create a checksum of S by taking the first length-of-S ÷ 32 bits of the SHA256 hash of S


3. 랜덤 sequence S의 끝에 checksum을 추가하라.


4. 연속적인 the sequence-and-checksum을 11개의 비트로 나누어라


5. 사전에 정의된 2048 단어의 각각 11비트를 맵핑하라


6. mnemonic 코드는 순서를 유지하면서 연속적인 단어입니다.


entropy를 만들고 mnemonic 단어로 인코딩하는 것은 어떻게 entropy가 mnemonic 단어를 만드는데 사용되는지 보여줄 것이다.


Figure 2. Generating entropy and encoding as mnemonic words


Mnemonic codes : entropy와 단어 길이는 entropy 데이터의 크기와 단어 안에 있는 mnemonic code의 길이 사이의 관계를 보여줍니다.



From mnemonic to seed


mnemonic 코드는 길이가 128 ~ 256 비트인 entropy를 나타냅니다. entropy는 key-stretching 함수인 PBKDF2를 사용하여 더 긴 512비트의 seed를 얻을 수 있습니다. 생성된 seed는 결정론적 지갑을 만들고 그것의 키를 만드는데 사용됩니다.


key-stretching 함수는 두 가지 매개변수(the mnemonic and a salt)를 사용합니다. key-stretching 함수에서 salt의 목적은 무차별 대입 공격을 어렵게 만드는 것입니다. BIP-39 표준에서 salt는 또다른 목적을 가지고 있습니다. BIP-39의 선택적 암호문에서 자세히 설명 하듯이 salt는 seed를 보호하는 추가적인 보안 요소 역할을 하는 암호문을 도입하게 해줍니다.


7 ~ 9단계에서 설명할 프로세스는 Generating mnemonic words에서 설명한 프로세스에 이어집니다.


7. PBKDF2 key-stretching 함수의 첫 번째 인자는 6단계에서 생성 된 mnemonic 입니다.


8. PBKDF2 key-stretching 함수의 두 번째 인자는 salt입니다. salt는 선택적인 사용자 제공 passphrase와 연결된 연속적인 mnemonic 문자열로 구성되어 있습니다.


9. PBKDF2는 HMAC-SHA512 알고리즘으로 2048회 해싱을 함으로써 the mnemonic and salt parameters를 확장시킴으로써 최종 출력 결과물로 512 비트 값을 생성합니다. 이 512 비트 값이 seed입니다.


From mnemonic to seed는 mnemonic를 사용하여 seed를 생성하는 방법을 보여줍니다.


Tip

2048회의 해싱을 사용한 key-stretching 함수는 the mnemonic or the passphrase에 대한 무차별 대입 공격에 대해서 다소 효과적인 보호를 제공합니다. 수천개의 passphrase and mnemonic를 조합하는 것은 비용이 많이 소요될 것입니다. 계산된 seed의 수는 우주의 원자 수보다 훨씬 큰 방대한 수입니다.


표 128-bit entropy mnemonic code, no passphrase, resulting seed, 128-bit entropy mnemonic code, with passphrase, resulting seed, and 256-bit entropy mnemonic code, no passphrase, resulting seed는 mnemonic codes와 mnemonic codes가 만든 seed의 몇 가지 예시를 보여줍니다.





Optional passphrase in BIP-39

BIP-39 표준을 사용하면 seed 파생시 optional passphrase를 사용할 수 있습니다. 만약 passphrase가 사용되지 않는다면, mnemonic은 일련의 연속적인 문자열 "mnemonic"으로 구성된 salt와 함께 확장되어서 주어진 mnemonic에서 특정 512 비트의 seed를 생성할 것입니다. 만약 passphrase가 사용된다면 , the stretching 함수는 같은 mnemonic으로 부터 다른 seed를 생성할 것입니다. 사실 단일 mnemonic이 주어졌을 때 모든 passphrase는 다른 seed로 이르게 됩니다. 본질적으로 잘못된 passphrase는 없습니다. 모든 passphrase는 유효하며 그들은 모두 다른 seed로 이르게 되기 때문에 초기화 되지 않은 광범위한 지갑을 만들게 됩니다. 지갑들은 너무 많기 때문에(2^512) 실질적인 무차별 대입이 없을 뿐더러 passphrase가 충분히 복잡하고 길이가 있는한 실수로 추측할 수 있는 가능성이 없습니다


Tip BIP-39에는 "잘못된" passphrase가 없습니다. 모든 passphrase는 이전에 사용하지 않은 한 비어있는 지갑을 만듭니다.


선택적 passphrase는 두 가지 중요한 기능을 만듭니다.


[mnemonic 백업을 해킹당하지 않도록 보호하기 위해서 mnemonic 자체를 쓸모 없게 만드는 두번째 요소 ] -> ?



그러나 passphrase을 사용하면 손실의 위험이 있을 수 있습니다


만약 지갑 소유자가 무능력하거나 죽었거나 아무도 passphrase을 알지 못한다면, seed는 쓸모 없으며 지갑에 있던 모든 자금은 영영 잃어버리게 될 것입니다.


반대로 소유자가 seed와 같은 위치에 암호를 백업할 경우 두번째 요소를 무시하게 됩니다.


passphrase는 매우 유용하지만 소유주의 생존 가능성과 상속인이 암호 해독성을 복구 할 수있는 가능성을 고려하여 신중하게 계획된 백업 및 복구 프로세스와 함께 사용해야합니다.

  

Working with mnemonic codes

BIP-39는 많은 다른 프로그래밍 언어에서 라이브러리로써 실행된다.

-python-mnemonic

Python으로 BIP-39를 제안한 SatoshiLabs 팀이 표준을 구현함

-Consensys/eth-lightwallet

노드 및 브라우저용 경량 JS Ethereum Wallet (BIP-39 포함)

-npm/bip39

Bitcoin의 JavaScript 구현


                              

 

Creating an HD Wallet from the Seed

HD wallet은 128-,256-,512비트의 랜덤 숫자로 이루어진 단일 root seed로부터 생성된다. 이때 이 시드는 mnemonic으로부터 생성된다.

HD wallet에 있는 모든 키는 이 root seed에서 파생된다.

root seed가 파생된 mnemonic만을 전송하면 수천 또는 수백만 개의 키가 들어있는 HD 지갑을 쉽게 내보내고, 백업하고, 복원하고 가져올 수 있다.

Hierarchical Deterministic Wallets (BIP-32) and paths (BIP-43/44)

대부분의 HD wallet은 BIP-32표준을 따른다.

여기서는  BIP-32가  어떻게 지갑에서 사용되는지 이해하는데 필요한 구성요소에 대해서만 알아볼것이다

중요한 것은 HD wallet에서 볼 수 있듯이 파생된 키가 가지는 트리같은 계층적인 관계를 이해하는것이다


                                      <단일 시드에서 생성된 key tree>


Extended public and private keys
BIP-32에서 키는 ‘확장’되어 ‘자식’을 생성할 수 있다. 이 방법으로 키는 확장키가 된다. 올바른 연산을 사용하면 확장된 ‘부모’키는 ‘자식’키를 파생하는데 사용될 수 있다. 부모키는 트리의 맨 위에 있을 필요는 없다.  키를 확장하는것은 키 자체를 가져와서 특별한 chain code를 추가하는 것이다. chain code는 자식 키를 생성하기 위한 각 키와 혼합된 256비트의 이진 문자열이다.

- 만약 키가 개인키라면, 이것은 접두사 xprw로 구별된 확장 개인키이다.

xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNsmsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73

- 확장 공개키는 접두사 xpub에 의해 구별된다.

xpub661MyMwAqRbcEnKbXcCqD2GT1di5zQxVqoHPAgHNe8dv5JP8gWmDproS6kFHJnLZd23tWevhdn4urGJ6b264DfTGKr8zjmYDjyDTi9U7iyT

 HD wallet의 유용한 특징은 개인키가 없어도 부모의 공개키에서 자식의 공개키를 파생시킬 수 있다는것이다. 이것은 자식 공개키를 파생 시키는 두가지 방법을 제공한다. (자식 개인키로부터 직접 or 부모의 공개키로부터)

 따라서 HD wallet 구조에서 확장된 공개키를 사용하여 모든 공개키를 파생 시킬 수 있다.

이 방법은 매우 안전한 공개키 전용 배포를 하는데에 사용되는데 , 확장 공개키의 복사본이 있지만 개인키는 없는 서버 또는 응용 프로그램에서 사용된다.

더 안전한 서버 일수록  확장된 개인키는 트랜잭션에 서명하고 돈을 지출 하기위해 모든 상응하는 개인키를 파생할 수 있다.

->을이 갑에 의존하지 않기 위함


 웹 서버는 공개 키 파생 함수를 사용하여 모든 트랜잭션을 위한 새로운 Ethereum 주소를 생성할 수 있다. 웹 서버에는 도용에 취약한 개인 키가 없다. HD wallet이 없으면, 별도의 보안 서버에 수천 개의 Ethereum 주소를 생성 한 다음 전자 상거래 서버에 미리 접근하는 것이 유일한 방법이다.

 이러한 접근 방식은 번거롭고 전자 상거래 서버의 키가 부족하지 않도록 지속적인 유지 관리가 필요합니다. 따라서 HD wallet \에서는 확장된 공개키를 사용하는 것이 좋다.

Hardened child key derivation

xpub(확장된 공공 키)로 부터 공공 키들의 가지를 얻는 능력은 매우 유용하지만, 잠재적 위험이 같이 온다. xpub에 접근하는 것은 자식 개인 키들에 대한 접근을 주지 않는다. 그러나,

xpub이 체인 코드(부모 공공 키로부터 자식 공공 키를 얻는데 사용)을 가지고 있기 때문에, 만약 자식 개인 키가 알려지거나 유출된다면, 다른 자식 개인 키를 얻으려고 체인 코드와 함께 사용된다. 부모 체인 코드와 함께 하나의 유출된 자식 개인 키는 모든 자식의 모든 개인 키들을 보여준다. 최악의 경우, 부모 체인 코드와 같이 자식 개인 키는 부모 개인 키를 추론하는 데 사용된다.


이러한 위험을 상대하려면, HD 지갑은 부모 공공 키와 자식 체인 코드 사이의 관계를 “깨는” 강화된 파생이라고 불리는 대안의 파생 함수를 사용한다. 강화된 파생 함수는 부모 공공 키 대신에 자식 체인 코드를 얻으려고 부모 개인 키를 사용한다. 이는 부모나 자식 개인 키를 타협하는 데 사용되는 체인 코드와 함께 부모/자식 시퀀스에서 “방화벽”을 만든다.

간단한 용어로, 만약 당신이 유출된 체인 코드의 위험에 노출시키지 않고 공공 키들의 가지를 얻으려고 xpub의 편리함을 사용하길 원한다면, 일반적인 부모말고 강화된 부모로부터 얻는 것이 낫다. 최고의 연습은 늘 강화된 파생에 의해 얻어지는 마스터 키들의 1레벨 자식을 얻어 마스터 키의 타협을 막는 것이다.


Index numbers for normal and hardened derivation

주어진 부모 키로 부터 하나 이상의 자식 키를 얻는 것을 가능하게 하는 것은 매우 바람직하다. 이를 관리하기 위해서, 인덱스 숫자가 사용된다. 특별한 자식 파생 함수를 사용하는 부모 키와 조합될 때, 각 인덱스 숫자는 다른 자식 키를 준다. BIP-32부모에서 자식 파생 함수에서 사용되는 인덱스 숫자는 32비트 정수이다. 일반적인 파생 함수를 통해 얻어진 키와 강화된 파생을 통해 얻어진 키사이를 쉽게 구별하기 위해서 인덱스 숫자는 두 범위로 나뉜다. 0과 2^31-1(0x0 ~ 0x7FFFFFFF)사이에 인덱스 숫자들은 일반적인 파생에 오직 사용된다. 2^31과 2^32-1(0x80000000 ~ 0xFFFFFFFF)사이에 인덱스 숫자들은 강화된 파생에서 오직 사용된다. 그러므로, 만약 인덱스 숫자가 2^31보다 작으면, 자식은 일반적이며,

반면에 만약 인덱스 숫자가 2^31보다 크거나 같으면, 자식은 강화된 것이다.

인덱스 숫자를 읽고 보여주기 쉽게 하려면, 강화된 자식을 위한 인덱스 숫자는 0으로 부터 시작하며 기본적인 상징과 함께 보여진다. 첫 번째 일반적인 자식은 0으로 보여지는 반면에, 첫 강화된 자식은 0&#x27;로 보여진다. 그래서 시퀀스에서, 두 번째 강화된 키는 인덱스 0x80000001를 가지고 있고 1&#x27;로 보여진다. 만약 당신이 i&#x27;를 HD지갑에서 본다면, 이는 2^31 + i를 뜻한다.


HD wallet key identifier (path)

HD지갑에서 슬래쉬(/)에 의해 분리된 각 트리의 레벨에서 키는 “경로”라고 불리는 규칙을 사용하여 식별된다. 마스터 개인 키로 부터 얻어진 개인 키들은 “m”으로 시작된다. 마스터 공공 키로 부터 얻어진 공공 키들은 “M”으로 시작된다. 그러므로, 마스터 개인 키의 첫 자식 개인 키는 m/0이다. 첫 자식 공공 키는 M/0이다. 첫 자식의 두 번째 손자는 m/0/1이다.

파생된 마스터 키에 도달할 때 까지, 키의 “가계”는 왼쪽에서 오른쪽으로 읽어진다. 예를 들어, m/x/y/z는 키 m/x/y의 z번째 자식 키, m/x의 y번째 키, m의 x번째 자식인 키를 표현한다.




HD path

Key described

m/0

The first (0) child private key from the master private key (m)

m/0/0

The first grandchild private key of the first child (m/0)

m/0'/0

The first normal grandchild of the first hardened child (m/0')

m/1/0

The first grandchild private key of the second child (m/1)

M/23/17/0/0

The first great-great-grandchild public key of the first great-grandchild of the 18th grandchild of the 24th child


Navigating the HD wallet tree structure

HD지갑 트리 구조는 매우 유연하다. 이것의 반대 부분은 무한한 복잡성을 가능하게 한다: 각 확장된 키는 40억 개의 자식을 가지고 있다: 20억개의 일반 자식과 20억개의 강화된 자식이다. 이 자식들 각각은 다른 40억개의 자식들을 가지고 있다. 잠재적인 무한한 수의 생성과 함께 당신이 원하는 만큼 트리는 깊어질 수 있다. 그러므로, 이러한 모든 잠재성과 함께, 이렇게 매우 큰 트리를 탐색하는 것은 꽤 까다롭다.

두 BIP는 HD지갑 트리의 구조에 대한 표준을 만듦으로서 이러한 잠재적인 복잡성을 관리하는 방법을 제공한다. BIP-43은 트리 구조의 “목적”을 나타내는 특별한 식별자로써 첫 강화된 자식 인덱스의 사용을 제안한다. BIP-43을 기반으로,  나머지 트리의 구조와 명칭 공간(namespace)를 확인함으로써 지갑의 목적을 정의하는 인덱스 숫자와 함께, 트리의 오직 1개의 레벨-1 가지를 사용한다. 더 구체적으로, 오직 m/i&#x27;/...를 사용하는 HD지갑은 구체적인 목적을 나타내는 데 의도되었으며 그 목적은 인덱스 숫자 “i”에 의해 확인된다.

이러한 명시를 확장해서, BIP-44는 “목적”을 44’로 설정해서 나타나는 다중화폐 다계정 구조를 제안한다. 모든 HD지갑은 트리의 한 가지를 사용하는 사실에 의해 확인된 BIP-44 구조를 따른다: m/44’/*

BIP-44는 다섯 가지 정의된 트리 레벨로 구성하는 구조를 명시한다:

m / purpose’ / coin_type’ / account’ / change / address_index


첫 번째 레벨인 “목적”은 늘 44’로 설정되어있다. 두 번째 레벨인 “coin_type”은 암호화폐의 종류를 명시하며, 각 화폐가 그 자체의 두 번째 레벨아래에 서브트리를 가지고 있는 다중화폐 HD지갑을 가능하게 해준다. SLIP0044라고 불리는 표준 문서에서 정의된 다양한 화폐가 있다:

https://github.com/satoshilabs/slips/blob/master/slip-0044.md

몇 개의 예시: 이더리움은 m/44&#x27;/60&#x27;, 이더리움 클래식은 m/44@#x27;/61&#x27;이며 비트코인은 m/44&#x27;/0&#x27;이고 모든 화폐의 테스트넷은 m/44&#x27;/1&#x27;이다.

트리의 세 번째 레벨은 “account”이며, 사용자로 하여금 그들의 지갑을 분리된 논리적 부계정으로 나눈다. 예를 들어, HD지갑은 두 이더리움 “account”를 포함한다:

m/44&#x27;/60&#x27;/0&#x27;과 m/44&#x27;/60&#x27;/1&#x27;이다. 각 계정은 그들의 서브트리의 루트이다.

BIP-44가 원래 비트코인을 위해 만들어졌기 때문에, 이더리움 세계와 관련 없는 “기이한 일”을 가지고 있다. 경로의 네 번째 레벨 “change”에서, HD지갑은 두 서브트리를 가지고 있다. 하나는 수신 주소를 만드는 것이고 하나는 변화 주소를 만드는 것이다. 오직 “receive” 경로가 이더리움에 사용되며, 비트코인 처럼 변화 주소에 대한 필요성은 없다. 이전 레벨이 강화된 파생을 사용해도, 이 레벨은 일반적인 파생을 사용하는 것을 기억해라. 이는 트리의 계정 레벨이 비안전한 환경에서 사용을 위해 확장된 공공 키들을 수출하게 해준다. 사용가능한 주소는 트리의 다섯 번째 레벨을 “address_index”로 만드는 네 번째 레벨의 자식으로서 HD지갑에 의해 얻어진다. 예를 들어, 기본적인 계정에서 이더리움 지불을 위한 세 번째 수신 주소는 M/44&#x27;/60&#x27;/0&#x27;/0/2이다.


HD path

Key described

M/44&#x27;/60&#x27;/0&#x27;/0/2

The third receiving public key for the primary Ethereum account

M/44&#x27;/0&#x27;/3&#x27;/1/14

The fifteenth change-address public key for the fourth Bitcoin account

m/44&#x27;/2&#x27;/0&#x27;/0/1

The second private key in the Litecoin main account, for signing transactions


Conclusions

지갑은 사용자 직면 블록체인 어플리케이션의 기초이다. 그들은 키와 주소의 수집 관리를 사용자가 가능하게 해준다. 지갑은 또한 사용자로 하여금 디지털 서명을 승인함으로써 그들의 이더 소유권를 입증하고 트랜잭션을 검증해준다.


Comments