본문으로 바로가기

Libbitcon 라이브러리의 사용법을 익히는 방법중에 "The Web Log of Aaron Jaramillo" 의 Tutorial 을 참고하여 사용법을 익히는 방법이 좋은것 같습니다.

해당 사이트에서 순서대로 사용법을 설명하고 있으며, 비트코인의 블록체인 개념과 연계해서 프로그래밍하여, 블록체인의 개념도 익히고, Bitcoin의 동작원리도 익힐수 있을것 같습니다. 이 Tutorial을 사용하여 라이브러리 사용법을 익히는 방법으로 포스팅을 해보고자 합니다.

이전 블록체인의 개념설명에 libbitcon 사용법의 예로 설명을 간단히 하였지만, 좀더  자세하게 순서대로 진행을 해보고자 합니다.


첫번째로 개인키 생성과 포맷변환 방법에 대해서 알아보도록 하겠습니다.

개인키는 1에서 사이의 값중에서 랜덤하게 선택된 256비트의 숫자입니다.

의사난수 생성기를 사용하여 256비트로 구성된 랜덤하게 생성된 비트열을 사람이 읽기쉬운 포맷인 base58check 알고리즘을 사용하여 읽기쉬운 포맷인 WIF(Wallet Import Format)으로 표현되어 있습니다. 

WIF 포맷은 다음과 같이 구성되어 있습니다.


Version Prefix + Secret Key + Key Type + Checksum


개인키의 Prefix는 0x80이고, Secret key는 Hex로 구성된 32바이트 개인키를 의미하고(64개의 Hex 값), key type은 압축 개인키의 경우, 0x01, 비압축 개인키의 경우 추가되지 않습니다. 그리고 checksum은 Version prefix+Secret key+Key type을 double SHA256  결과값중 첫번째 4바이트를 의미합니다.

이렇게 생성된 WIF 포맷의 개인키는 QR 코드로 쉽게 변경이 가능해집니다.


그럼 Libbitcoin 라이브러리를 사용하여 Hex 포맷의 개인키를 WIF 변환하는 방법에 대해서 알아보겠습니다.

다음의 코드를 privatekey.cpp로 저장합니다.


작성코드는 다음의 github에서 다운받을수 있습니다.

https://github.com/ihpark92/Libbitcoin_Tutorial


#include <bitcoin/bitcoin.hpp>
#include <string.h>
#include <iostream>
using namespace bc;
int main(void)
{
// 의사난수 발생기를 통해서 secret 키를 생성
data_chunk seed(16);
pseudo_random_fill(seed);
ec_secret secretKey = bitcoin_hash(seed);
// 생성된 secret 키(256비트)를 base16 encoing으로 64개의 hex 값으로 변환하여 출력
std::string hexKey = encode_base16(secretKey);;
std::cout << "Hex secret: " << std::endl;
std::cout << hexKey << std::endl;
// 개인키사용을 위한 byte array타입인 ec_secret 선언
ec_secret rawprivateKey;
// 64개의 hex값으로 표현된 secret키를 디코딩하여 raw 포맷으로 변환
decode_base16(rawprivateKey, hexKey);
// raw private키에 WIF Private 키 임을 알려주는 0x80 접두어를 추가하여 WIF 포맷으로 private 키 생성
wallet::ec_private privateKey(rawprivateKey, 0x8000, false);
std::cout << "\nPrivate Key Structure: " << std::endl;
std::cout << privateKey.encoded() << std::endl;
// secret 매쏘드를 통해 WIF 포맷의 private 키에서 secret 키를 추출하여 원본과 동일한지 비교
ec_secret keyTest = privateKey.secret();
std::string keyTestString = encode_base16(keyTest);
if(keyTestString == hexKey){
std::cout << "Confirmed: " <<keyTestString << std::endl;
}
else{
std::cout << "Error!" <<keyTestString << std::endl;
}
hexKey = "80" + hexKey;
std::cout << "\nVersioned Key: " << std::endl;
std::cout << hexKey << std::endl;
data_chunk fullKey;
data_chunk wifVersion;
// WIF 포맷의 private 키를 위한 byte array 선언
// 37바이트 : version prefix(1) + secret key(32) + 비압축 WIF 포맷(0) + checksum(4)
byte_array<37u> versionedKey;
decode_base16(fullKey, hexKey);
decode_base16(wifVersion, "0x80");
// WIF 포맷의 private 키 생성
build_checked_array(versionedKey, { wifVersion, fullKey});
std::string practiceKey = encode_base58(versionedKey);
std::cout<< "\nBy Hand:" << std::endl;
std::cout<< practiceKey << std::endl;
}


위와같이 Libbitcoin 라이브러리를 사용하여 256비트의 secret key를 사용하여 WIF포맷의 private 키를 변환할수 있습니다.


다음과 같이 빌드하여 실행결과를 확인하도록 하겠습니다.


$ g++ -std=c++11 -o privatekey privatekey.cpp $(pkg-config --cflags libbitcoin --libs libbitcoin)