Jason Dev
About
[bitcoind] 로컬에서 실행해보기
published: 2024-01-07
bitcoind
bitcoin-cli
regtest

bitcoind을 이용해서 로컬에서 비트코인 테스트 환경을 구축해보자.

bitcoind 설치하기

brew를 이용해서 bitcoind를 설치한다.

brew install bitcoin

혹은 사이트에서 직접 다운로드 받고 설치해도 된다.

주요 명령어 사용해보기

bitcoind 설치에 성공했다면 아래 명령어로 실행해보자.

bitcoind -regtest

테스트 환경에서 실행하기 위해 regtest 옵션을 입력했다. bitcoind 실행을 통해 하나의 비트코인 노드가 실행된다. 이제부터 bitcoin-cli를 통해 이 노드의 API를 호출할 수 있다.

블록 정보 확인하기

getblockchaininfo를 호출하면 블록체인의 일반적인 정보를 확인할 수 있다.

bitcoin-cli -regtest getblockchaininfo
{
"chain": "regtest",
"blocks": 0,
"headers": 0,
"bestblockhash": "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206",
"difficulty": 4.656542373906925e-10,
"time": 1296688602,
"mediantime": 1296688602,
"verificationprogress": 1,
"initialblockdownload": true,
"chainwork": "0000000000000000000000000000000000000000000000000000000000000002",
"size_on_disk": 293,
"pruned": false,
"warnings": ""
}

x번째 블록의 정보를 출력하기 위해서는 getblockhash으로 해시값을 가져오고 그 값을 getblock에 입력하면 된다.

bitcoin-cli -regtest getblockhash 0
0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206
bitcoin-cli -regtest getblock 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206
{
"hash": "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206",
"confirmations": 1,
"height": 0,
"version": 1,
"versionHex": "00000001",
"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
"time": 1296688602,
"mediantime": 1296688602,
"nonce": 2,
"bits": "207fffff",
"difficulty": 4.656542373906925e-10,
"chainwork": "0000000000000000000000000000000000000000000000000000000000000002",
"nTx": 1,
"strippedsize": 285,
"size": 285,
"weight": 1140,
"tx": [
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
]
}

첫 번째 블록은 제네시스 블록을 의미하며 이미 채굴된 상태로 존재한다.

지갑 생성 및 정보 확인

createwallet 명령어로 지갑을 생성할 수 있다.

bitcoin-cli -regtest createwallet wallet1
{
"name": "wallet1"
}
bitcoin-cli -regtest listwallets
[
"wallet1"
]

getnewaddress 명령어를 호출하면 HD지갑으로 생성된 주소를 순차적으로 반환한다. getnewaddress를 호출할 때마다 새로운 주소가 반환된다.

bitcoin-cli -regtest -rpcwallet="wallet1" getnewaddress
bcrt1qa9hd4y5gln6sws5zmgwqujf2e0nmwu26ug2fcj
bitcoin-cli -regtest getaddressinfo bcrt1qa9hd4y5gln6sws5zmgwqujf2e0nmwu26ug2fcj
{
"address": "bcrt1qa9hd4y5gln6sws5zmgwqujf2e0nmwu26ug2fcj",
"scriptPubKey": "0014e96eda9288fcf5074282da1c0e492acbe7b7715a",
"ismine": true,
"solvable": true,
"desc": "wpkh([ae549538/84'/1'/0'/0/0]03f4457e8f8949d3e795f3772f13c7f8c118b675d9a92ffc3a80cea222bb621e15)#548ygrkk",
"parent_desc": "wpkh([ae549538/84'/1'/0']tpubDCJq48m7WAqGMAEJck3wgzafvoxssX4TE8uR1Cm3dY8kSH6qv27kbPL9WWbP2WPFSip9jepjXoZGzUcBvSf7zo9hj8nPSiEPbQAuvS9BKi1/0/*)#l60c6kmw",
"iswatchonly": false,
"isscript": false,
"iswitness": true,
"witness_version": 0,
"witness_program": "e96eda9288fcf5074282da1c0e492acbe7b7715a",
"pubkey": "03f4457e8f8949d3e795f3772f13c7f8c118b675d9a92ffc3a80cea222bb621e15",
"ischange": false,
"timestamp": 1704547407,
"hdkeypath": "m/84'/1'/0'/0/0",
"hdseedid": "0000000000000000000000000000000000000000",
"hdmasterfingerprint": "ae549538",
"labels": [
""
]
}
bitcoin-cli -regtest -rpcwallet="wallet1" getnewaddress
bcrt1qjys8x6fcrx68wc6062pp9kc0czfp660kvhdmsr

두 번째 주소인 bcrt1qjys8x6fcrx68wc6062pp9kc0czfp660kvhdmsr의 hdkeypath 값은 m/84'/1'/0'/0/1이다.

getwalletinfo 명령어는 잔액을 포함한 지갑의 자세한 정보를 출력한다.

bitcoin-cli -regtest getwalletinfo
{
"walletname": "wallet1",
"walletversion": 169900,
"format": "sqlite",
"balance": 0.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 0.00000000,
"txcount": 0,
"keypoolsize": 3999,
"keypoolsize_hd_internal": 4000,
"paytxfee": 0.00000000,
"private_keys_enabled": true,
"avoid_reuse": false,
"scanning": false,
"descriptors": true,
"external_signer": false
}

블록 생성하기

generate 명령어를 입력하면 블록이 채굴된다. 처음에는 난이도가 매우 낮은 상태이므로 명령어를 입력하는 순간 바로 채굴에 성공한다.

bitcoin-cli -regtest -generate 1
{
"address": "bcrt1qqk6nhak7nt3e908ga84y9uaj225degvjkv5av4",
"blocks": [
"15bc8efbc8312aef0150d1f4d0d1725297016be2f15a4ae7b6c042fe5739bff2"
]
}

bcrt1qqk6nhak7nt3e908ga84y9uaj225degvjkv5av4 주소로 채굴 보상이 입금된다. 이 주소는 wallet1 HD지갑에 속한 주소다.

getbalances 명령어를 통해 잔액을 확인해보면 immature 속성에서 50 BTC를 확인할 수 있다. 채굴 보상은 100 confirmation이 지나야 사용될 수 있는데 immature 속성은 100 confirmation이 지나지 않은 금액을 나타낸다.

bitcoin-cli -regtest getbalances
{
"mine": {
"trusted": 0.00000000,
"untrusted_pending": 0.00000000,
"immature": 50.00000000
}
}

100번의 채굴을 진행시켜보면 trusted 속성에서 50 BTC를 확인할 수 있다. trusted 속성은 현재 사용 가능한 금액을 나타낸다.

bitcoin-cli -regtest -generate 100
bitcoin-cli -regtest getbalances
{
"mine": {
"trusted": 50.00000000,
"untrusted_pending": 0.00000000,
"immature": 5000.00000000
}
}

로컬에서 노드 여러 개 띄우기

로컬에서 노드 여러 개를 띄워서 트랜잭션과 블록 정보가 노드 간에 동기화가 잘 되는지 확인해보자.

노드 실행하기

원하는 곳에 node1, node2 폴더를 만들자. 그리고 각 폴더 밑에 bitcoin.conf 파일을 만들고 아래 내용을 입력하자.

아래는 /path/to/node1/bitcoin.conf 파일의 내용이다.

chain=regtest
rpcuser=w1
rpcpassword=w1
rpcport=1111
txindex=1
port=8881
fallbackfee=0.0002
server=1
datadir=/path/to/node1

아래는 /path/to/node2/bitcoin.conf 파일의 내용이다.

chain=regtest
rpcuser=w2
rpcpassword=w2
rpcport=2222
txindex=1
port=8882
fallbackfee=0.0002
server=1
datadir=/path/to/node2

아래 명령어로 비트코인 노드를 실행하자.

bitcoind -conf="/path/to/node1/bitcoin.conf" -rpcport=1111 -port=8881 -wallet="w1" -daemon
bitcoind -conf="/path/to/node2/bitcoin.conf" -rpcport=2222 -port=8882 -wallet="w2" -daemon

deamon 옵션을 이용해서 백그라운드에서 실행되도록 했다.

별칭 등록하기

명령어 입력을 간편하게 하기 위해 별칭을 등록하자.

alias bc1='bitcoin-cli -rpcuser=w1 -rpcpassword=w1 -rpcport=1111'
alias bc2='bitcoin-cli -rpcuser=w2 -rpcpassword=w2 -rpcport=2222'

잘 동작하는지 테스트해보자.

bc1 getblockcount
0
bc2 getblockcount
0

두 노드 연결하기

node1에서 지갑을 생성하고 해당 지갑으로 비트코인을 넣어주기 위해 블록 101개를 생성한다.

bc1 createwallet w1
{
"name": "w1"
}
bc1 -generate 101

node2를 node1로 연결한다.

bc2 addnode 127.0.0.1:8881 add

잘 연결이 되었다면 두 노드의 상태가 동기화된다. 동기화가 잘 되었는지 확인해보자.

bc1 getblockcount
101
bc2 getblockcount
101

블록 개수가 같아졌으니 동기화가 잘 된 것 같다.

트랜잭션 생성해보기

w1 지갑에서 다른 지갑으로 비트코인을 전송해보자. node2에 w2 지갑을 생성한다.

bc2 createwallet w2
{
"name": "w2"
}
bc2 getnewaddress
bcrt1qmnryd74sfk334q8qpxj296qv0nytu9azqu74vg

w1에서 w2로 3 BTC를 전송해보자.

bc1 send '{"bcrt1qmnryd74sfk334q8qpxj296qv0nytu9azqu74vg": 3}'
{
"txid": "2c5088cfb900e13b5eedf45a09f7f298c32e4f9d31d0896d9cd1d612c83fbb54",
"complete": true
}

w2의 잔고를 확인해보자.

bc2 getbalances
{
"mine": {
"trusted": 0.00000000,
"untrusted_pending": 3.00000000,
"immature": 0.00000000
}
}

해당 트랜잭션이 포함된 블록이 아직 채굴되지 않아서 untrusted_pending에서 확인할 수 있다.

pending 상태인 트랜잭션은 mempool에서 확인할 수 있다. 해당 트랜잭션이 node1, node2의 mempool에 잘 들어있는지 확인해보자.

bc1 getrawmempool
[
"2c5088cfb900e13b5eedf45a09f7f298c32e4f9d31d0896d9cd1d612c83fbb54"
]
bc2 getrawmempool
[
"2c5088cfb900e13b5eedf45a09f7f298c32e4f9d31d0896d9cd1d612c83fbb54"
]

이전에 생성했던 트랜잭션이 mempool에 잘 들어있는 것을 확인할 수 있다. node1에서 생성했던 트랜잭션이 node2로 전파가 잘 되었다는 것을 확인할 수 있다.

채굴을 통해 해당 트랜잭션을 블록에 포함시키자.

bc2 -generate 1
{
"address": "bcrt1qzcn8g7pfdw9u5yhunzh0u25a5pxu32st7lth0a",
"blocks": [
"77e52f0ec33ab245c2ddbb55bba3e4385646e55147f174eb088a78ec8e4e3310"
]
}

채굴은 node1, node2 중에 누가 하더라도 (채굴 보상을 받는 사람만 다를 뿐) 결과는 같다.

채굴이 잘 되었는지 확인해보자.

bc2 getrawmempool
[
]
bc2 getbalances
{
"mine": {
"trusted": 3.00000000,
"untrusted_pending": 0.00000000,
"immature": 50.00002820
}
}

댓글 삭제 시 메일 주소가 필요합니다