본문으로 바로가기

이전에 작성한 HD Wallet 클래스를 사용하여 사용자에게 메뉴를 제공하여 대화형으로 키를 생성하는 프로그램을 작성하도록 하겠습니다.

하기 샘플코드는 하기의 Tutorial을 참고로 하여 사용하였습니다.

http://aaronjaramillo.org/libbitcoin-interactive-hd-keychain-part-22


하기에 작성한 코드는 다음 github 에서 다운로드할수 있습니다.

https://github.com/ihpark92/Libbitcoin_Tutorial


하기와 같이 Libbitcoin 라이브러리를 포함하고 이전에 작성한 HD_Wallet 클래스화일을 인클루드 합니다.

#include <bitcoin/bitcoin.hpp>
#include <string.h>
#include <iostream>
#include "HD_Wallet.cpp"
using namespace bc;


다음으로 사용자에게 보여주기위한 메뉴를 출력하는 함수를 작성합니다.


void mainMenu()
{
std::cout << "\n==========================" << std::endl;
std::cout << "1. Generate New Wallet" << std::endl;
std::cout << "2. Import Wallet" << std::endl;
std::cout << "3. display" << std::endl;
std::cout << "4. Exit" << std::endl;
std::cout << "==========================" << std::endl;
}
void displayMenu()
{
std::cout << "\n==========================" << std::endl;
std::cout << "1. Private Key" << std::endl;
std::cout << "2. Mnemonic" << std::endl;
std::cout << "3. Child Private Key" << std::endl;
std::cout << "4. Payment Address" << std::endl;
std::cout << "5. Address Range" << std::endl;
std::cout << "6. Dump Keys" << std::endl;
std::cout << "7. Exit" << std::endl;
std::cout << "==========================" << std::endl;
}


다음은 사용자 입력을 받기위한 함수입니다.


int getInput()
{
int choice;
std::cout << "Enter a Number: ";
std::cin >> choice;
return choice;
}


다음은 사용자로부터 연상기호 단어열을 입력받아 word list 객체를 생성하여 반환하는 매쏘드입니다.

이와같이 연상기호단어 객체를 사용하여 개인키를 생성할수 있게 됩니다.

wallet::word_list getWordList()
{
std::string mnemonicSeed;
std::cout << "Enter Seed String:";
cin.ignore();
std::getline(cin, mnemonicSeed);
return split(mnemonicSeed);
}


다음은 기본적인 초기화 매쏘드로서 16바이트의 seed 배열을 사용하여 난수를 생성하고, 해당 난수 seed 값을 사용하여 HD wallet 객체를 생성하는 함수입니다.

이 함수를 통해서 최초의 마스터 개인키와 유도된 인덱스 1번의 자식키와 주소를 생성하게 됩니다.

HD_Wallet randomGen()
{
data_chunk entropyChunk = data_chunk(16);
pseudo_random_fill(entropyChunk);
HD_Wallet(entropyChunk).dumpKeys();
return HD_Wallet(entropyChunk);
}


main 함수에서 다음과 같이 사용자에게 메뉴를 출력하고 입력을 받아 처리를 하도록 구성됩니다.


int main()
{
HD_Wallet wallet = randomGen();
int choice = 0;
while(choice != 4)
{
mainMenu();
choice = getInput();
if(choice == 1)
{
wallet = randomGen();
} else if(choice == 2)
{
wallet::word_list mnemonicSeedList = getWordList();
if(wallet::validate_mnemonic(mnemonicSeedList))
{
wallet = HD_Wallet(mnemonicSeedList);
wallet.dumpKeys();
} else {
std::cout << "Mnemonic Invalid!" << std::endl;
}
}


3번 display 메뉴를 통하여 사용자는 생성된 키값을 종류별로 출력하여 확인할수 있습니다.

else if (choice == 3)
{
while(choice != 7){
displayMenu();
choice = getInput();
std::cin.ignore();
int index;
if(choice == 1)
{
wallet.displayPrivateKey();
} else if(choice == 2)
{
wallet.displayMnemonic();
} else if (choice == 3)
{
index = getInput();
wallet.displayChildPrivateKey(index);
} else if (choice == 4)
{
index = getInput();
wallet.displayAddress(index);
} else if (choice == 5)
{
int start = getInput();
int end = getInput();
wallet.addressRange(start, end);
}else if (choice == 6)
{
wallet.dumpKeys();
}else if (choice == 7)
{
std::cout << "Bye" << std::endl;
} else
{
std::cout << "Selection Invalid! " << std::endl;
}
}
} else if (choice == 4)
{
std::cout << "Goodbye" << std::endl;
}else {
std::cout << "Selection Invalid!" << std::endl;
}
}
}


다음과 같이 실행결과를 확인할수 있습니다.

실행을 하게되면 기본 16바이트 seed 값을 사용하여 연상기호 단어열을 생성하여 마스터 개인키를 생성하고 자식키를 유도하여 주소를 생성하여 출력합니다.

2번 Import 메뉴를 통해서는 연상기호 단어열을 입력받아 지갑을 임포트하게 됩니다.

즉, 하기에 상생한 "before wrestle  tank fantasy raven emerge eager eternal believe orchard copy game" 단어열을 입력하게 되면 하기에 생성된 개인키와 자식키, 주소를 동일하게 복구하게 됩니다.


ihpark92@ubuntu:~/work$ ./HDWallet
before wrestle tank fantasy raven emerge eager eternal believe orchard copy game
Private Key:xprv9s21ZrQH143K2juUqFRwYahDAptwKoAzmis5cTFD8RNuDxFR7tVHx7BsCsjdcUNRnwNJ1D6J5pACq2YzjNio87Q65YdFXYUpVWmzgfqEn2p
Child Key: xprv9ubadSbSKSPvttzTSQUaEYewZ4RhRT7z4mjLirNERz9u6uZ2Wghz9Ri7zuR3U8AoevjfjZdbMdAEsdAwACu6WTUch5wFGRvWnSKa7p6vZQs
Address: 18QP8tXUTZKTb4KfxqtekCVKkz3iFMvVNn
==========================
1. Generate New Wallet
2. Import Wallet
3. display
4. Exit
==========================
Enter a Number:


Display 메뉴를 통해서는 다음과 같이 각 키값과 연상기호 단어열, 주소 등을 선택하여 출력 확인할수 있습니다.


==========================
1. Private Key
2. Mnemonic
3. Child Private Key
4. Payment Address
5. Address Range
6. Dump Keys
7. Exit
==========================
Enter a Number: 6
before wrestle tank fantasy raven emerge eager eternal believe orchard copy game
Private Key:xprv9s21ZrQH143K2juUqFRwYahDAptwKoAzmis5cTFD8RNuDxFR7tVHx7BsCsjdcUNRnwNJ1D6J5pACq2YzjNio87Q65YdFXYUpVWmzgfqEn2p
Child Key: xprv9ubadSbSKSPvttzTSQUaEYewZ4RhRT7z4mjLirNERz9u6uZ2Wghz9Ri7zuR3U8AoevjfjZdbMdAEsdAwACu6WTUch5wFGRvWnSKa7p6vZQs
Address: 18QP8tXUTZKTb4KfxqtekCVKkz3iFMvVNn