하드웨어 월렛 HWI

HWI (Bitcoin Hardware Wallet Interface)

HWI(Bitcoin Hardware Wallet Interface)는 Bitcoin Core 팀에서 만든 하드웨어 월렛 인터페이스 오픈 소스 프로그램으로 소스 코드는 https://github.com/bitcoin-core/HWI 에 있다. HWI는 Python 3로 작성되어 있으며, HWI 설치 후 hwilib 폴더에 파이썬 라이브러리들이 있고, HWI 폴더에 hwi.py 라는 실행 파일이 있다.

HWI 설치

HWI 깃허브 레파지토리에 각 OS별 설치 방법이 자세히 나와 있는데, Ubuntu에 설치하는 방법은 다음과 같다.

(1) HWI 설치
$ sudo apt install libusb-1.0-0-dev libudev-dev python3-dev
$ git clone https://github.com/bitcoin-core/HWI.git
$ cd HWI
$ pip3 install .

(2) udev rules 추가
$ cd hwilib     (HWI/hwilib folder)
$ sudo cp udev/*.rules /etc/udev/rules.d/ && \
    sudo udevadm trigger && \
    sudo udevadm control --reload-rules  && \
    sudo groupadd plugdev && \
    sudo usermod -aG plugdev `whoami`

HWI 사용

HWI 설치가 완료된 후, Ledger, Trezor 등과 같은 하드웨어 월렛을 연결하고, PIN 번호를 넣어 Unlock 한 후, 아래와 같은 HWI 명령은 하드웨어 월렛을 Detect 한다. enumerate 명령의 출력에서 중요한 것은 fingerprint 로서 이는 그 하드웨어의 ID 역활을 한다.

$ ./hwi.py enumerate
[{"type": "ledger", "model": "ledger_nano_x", "label": null, "path": "1-8:1.0", 
"fingerprint": "d8fb486b", "needs_pin_sent": false, "needs_passphrase_sent": false}]

하드웨어가 Detect 되었으면, H/W Wallet의 public key들(즉, 비트코인 주소들)을 가져올 수 있는데, 아래 명령은 Bitcoin Testnet을 사용하는 것으로 이를 위해 우선 하드웨어 월렛에 Bitcoin Testnet App을 설치해야 하고 또한 Bitcoin Testnet App을 실행해 주어야 한다.

다음으로 HWI 프로그램에서 하드웨어 fingerprint를 -f (혹은 --fingerprint) 옵션으로 지정하고, getkeypool 명령을 사용하여 주소 키 범위 (0 ~ 10)를 지정하면 아래와 같이 Extended Public Key를 포함하는 Descriptor를 출력하게 된다. 이 Descriptor를 사용하면 Child Key들을 생성하고 Watch only 주소들을 자동 생성할 수 있다.

$ ./hwi.py --chain test -f d8fb486b getkeypool 0 10
[{"desc": "wpkh([d8fb486b/84h/1h/0h]tpubDDVAHV7k1K3tUQbjf4D1bfuNv7wKQVMiXWAwWCpUqgrBY5Cvpki5jf6rjPd1VkKupWhcVJxFMU67YfnQ1oJaaT9WFgswyQxziJR7jEDjvxX/0/*)#9y4rpzay", "range": [0, 10], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([d8fb486b/84h/1h/0h]tpubDDVAHV7k1K3tUQbjf4D1bfuNv7wKQVMiXWAwWCpUqgrBY5Cvpki5jf6rjPd1VkKupWhcVJxFMU67YfnQ1oJaaT9WFgswyQxziJR7jEDjvxX/1/*)#5sszuhdu", "range": [0, 10], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}]    

HWI 프로그램으로부터 Descriptor를 얻은 후에는, bitcoin-cli에서 importmulti 명령을 사용하여 주소들을 생성하고 import 할 수 있다. 아래는 새로운 월렛을 만들고 그 안에 공개키 주소들을 import하는 예이다. 이렇게 Import된 주소로 코인을 보내면, 이는 개인키를 가진 하드웨어 월렛으로 코인을 보내는 것과 같게 된다.

$ bitcoin-cli --named createwallet wallet_name="ledger1" disable_private_keys=true 
$ bitcoin-cli -rpcwallet=ledger1 importmulti '[{"desc": "wpkh([d8fb486b/84h/1h/0h]tpubDDVAHV7k1K3tUQbjf4D1bfuNv7wKQVMiXWAwWCpUqgrBY5Cvpki5jf6rjPd1VkKupWhcVJxFMU67YfnQ1oJaaT9WFgswyQxziJR7jEDjvxX/0/*)#9y4rpzay", "range": [0, 10], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([d8fb486b/84h/1h/0h]tpubDDVAHV7k1K3tUQbjf4D1bfuNv7wKQVMiXWAwWCpUqgrBY5Cvpki5jf6rjPd1VkKupWhcVJxFMU67YfnQ1oJaaT9WFgswyQxziJR7jEDjvxX/1/*)#5sszuhdu", "range": [0, 10], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}]'
$ bitcoin-cli -rpcwallet=ledger1 getaddressesbylabel "" 
{
    "tb1q53682xqc93yylv8syydr9qw8crxfclj700twru": {
        "purpose": "receive"
    },
    "tb1qyxpde6h75qcg59tct6fz4m6a4rf6zlyty87tc2": {
    "purpose": "receive"
    },
    "tb1q06p88r7p9u8k49576va5zjn3qqhwm3csvswcy4": {
    "purpose": "receive"
    },
    ...생략...
}

PSBT과 하드웨어 월렛 사용

PSBT를 활용하여 서명을 요하는 트랜잭션을 생성하고 이를 하드웨어 월렛에서 서명한 후, 완료된 트랜잭션을 전송할 수 있다. PSBT 트랜잭션 생성은 UTXO를 지정하는 createpsbt 명령을 사용할 수도 있고, UTXO를 자동으로 선택하도록 하는 walletcreatefundedpsbt 명령을 사용할 수도 있다. 하드웨어에서의 서명은 HWI의 signtx 명령을 사용하여 PSBT를 서명하게 되고, 그 결과를 finalize 하고(finalizepsbt) Raw Transaction을 전송하면 된다.

// (1) psbt 생성
$ psbt=$(bitcoin-cli -rpcwallet=ledger1 walletcreatefundedpsbt '[]' '{"tb1q8z7fkxccgagc3y77gdp73cuygqh0uajujw5w5d":0.0009}' | jq -r '.psbt')

// (2) psbt 체크
//$ bitcoin-cli decodepsbt $psbt
//$ bitcoin-cli analyzepsbt $psbt

// (3) 하드웨어 월렛에서 서명
$ ./hwi.py --chain test -f d8fb486b signtx $psbt
{"psbt": "cHNidP8BAHECAAAAABEGBB...", "signed": true}

// (4) 완성된 TX 보내기 
$ signedpsbt="cHNidP8BAHECAAAAABEGBB..."
$ hex=$(bitcoin-cli finalizepsbt $signedpsbt | jq -r '.hex') 
$ bitcoin-cli sendrawtransaction $hex

스텝(3) 하드웨어 월렛 서명에서 코인이 Testnet 코인이므로 --chain test 옵션을 지정해 주어야 하며, 이 명령이 실행되면 하드웨어 월렛에서 Approve 버튼을 눌러 주어야 한다. 정상적으로 처리되면, 출력 결과에서 "signed"가 true가 리턴된다.

본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.