Jason Dev
About
[bitcoind] 트랜잭션 생성하기
published: 2024-01-14
bitcoind
bitcoin-cli
sendtoaddress
createrawtransaction
fundrawtransaction
curl

bitcoind를 이용해서 트랜잭션을 생성하는 방법을 알아보자. 편리하지만 제한된 기능만 사용할 수 있는 방법부터 불편하지만 강력한 기능을 사용할 수 있는 방법까지 다양하게 알아보자.

주로 bitcoin-cli를 활용하며 마지막에 curl을 사용하는 방법도 가볍게 다룬다.

사전 준비

초기 설정은 이전 글에서 다룬 내용을 참고하자.

이번 글에서는 로컬에서 비트코인 노드 2개를 띄운 상태를 가정한다. 아래와 같이 각 노드에서 편하게 명령어를 실행해보기 위해 별칭을 등록하자.

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

가장 쉬운 방법: sendtoaddress

bc1 지갑에서 bc2 지갑으로 비트코인을 보내보자. 가장 쉬운 방법은 sendtoaddress 명령어를 이용하는 것이다.

bc2 지갑 주소를 얻기 위해 getnewaddress 명령어를 실행하자.

bc2 getnewaddress
bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq

listunspent 명령어를 통해 현재 bc1 지갑의 UTXO 현황을 확인해보자.

bc1 listunspent
[
{
"txid": "7ed857ae65ed9b647ce975c302098050a43dcb74babe1dd86f2dcc9ac7bafe04",
"vout": 0,
"address": "bcrt1qzgy07scudqgppvx3c5fe0h6yvvh8lcmu4lr3vg",
"scriptPubKey": "00141208ff431c681010b0d1c51397df44632e7fe37c",
"amount": 0.19843440,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/1/6]02376daadc343a464a116ec3afcd58676d2d839de5a79de8ec7cbf468c255f49ba)#0vu2hx0s",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/1/*)#mmhnk5cr"
],
"safe": true
},
{
"txid": "5dd19dc27a29f1cd0b063054511b1205a3c2712c81d1b5d4a00c13e20c44e2a0",
"vout": 0,
"address": "bcrt1qfvdqxtc83nuupkzgjxfc6djhewhjm4wrwsjk8s",
"label": "",
"scriptPubKey": "00144b1a032f078cf9c0d84891938d3657cbaf2dd5c3",
"amount": 2.00000000,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/0/3]027103f4c8edac9bfb89704b3e0e6293c614418da7ab05e7c3c8c22f866c50bb0a)#z9l6wxha",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/0/*)#20jjtpgm"
],
"safe": true
}
]

각각 0.19843440 BTC, 2 BTC가 담긴 UTXO가 있음을 확인할 수 있다. 이제 sendtoaddress 명령어를 이용해서 bc2 지갑으로 0.1 BTC를 보내보자.

bc1 sendtoaddress bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq 0.1
887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a

sendtoaddress 명령어를 실행하면 트랜잭션 생성과 동시에 네트워크로 전파된다. 그리고 해당 트랜잭션 ID가 출력된다.

트랜잭션의 세부 내용을 확인해보기 위해 getrawtransaction, decoderawtransaction 명령어를 순차적으로 실행해보자.

bc1 getrawtransaction 887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a
0200000000010104febac79acc2d6fd81dbeba74cb3da450800902c375e97c649bed65ae57d87e0000000000fdffffff02ec279600000000001600142bacf9415745c638c88a62657330686c70c9842c8096980000000000160014dda1377b0ce22db168f22ec95a9e809637938a31024730440220104ae824a20f2d2dc8f5392599056f343e24730b01c690b098f5ec4d766a523d0220331dcf9fb29c7b63b859fe610ba000a4b9155765c36dc0118cf0b7065e728642012102376daadc343a464a116ec3afcd58676d2d839de5a79de8ec7cbf468c255f49baef000000
bc1 decoderawtransaction 0200000000010104febac79acc2d6fd81dbeba74cb3da450800902c375e97c649bed65ae57d87e0000000000fdffffff02ec279600000000001600142bacf9415745c638c88a62657330686c70c9842c8096980000000000160014dda1377b0ce22db168f22ec95a9e809637938a31024730440220104ae824a20f2d2dc8f5392599056f343e24730b01c690b098f5ec4d766a523d0220331dcf9fb29c7b63b859fe610ba000a4b9155765c36dc0118cf0b7065e728642012102376daadc343a464a116ec3afcd58676d2d839de5a79de8ec7cbf468c255f49baef000000
{
"txid": "887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a",
"hash": "fb959693023eccccce646a8bfe025f5b9601d0c85d81bbff9dd00c869d16674d",
"version": 2,
"size": 222,
"vsize": 141,
"weight": 561,
"locktime": 239,
"vin": [
{
"txid": "7ed857ae65ed9b647ce975c302098050a43dcb74babe1dd86f2dcc9ac7bafe04",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"txinwitness": [
"30440220104ae824a20f2d2dc8f5392599056f343e24730b01c690b098f5ec4d766a523d0220331dcf9fb29c7b63b859fe610ba000a4b9155765c36dc0118cf0b7065e72864201",
"02376daadc343a464a116ec3afcd58676d2d839de5a79de8ec7cbf468c255f49ba"
],
"sequence": 4294967293
}
],
"vout": [
{
"value": 0.09840620,
"n": 0,
"scriptPubKey": {
"asm": "0 2bacf9415745c638c88a62657330686c70c9842c",
"desc": "addr(bcrt1q9wk0js2hghrr3jy2vfjhxvrgd3cvnppv7n6dh0)#x74la3us",
"hex": "00142bacf9415745c638c88a62657330686c70c9842c",
"address": "bcrt1q9wk0js2hghrr3jy2vfjhxvrgd3cvnppv7n6dh0",
"type": "witness_v0_keyhash"
}
},
{
"value": 0.10000000,
"n": 1,
"scriptPubKey": {
"asm": "0 dda1377b0ce22db168f22ec95a9e809637938a31",
"desc": "addr(bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq)#d8pafqy3",
"hex": "0014dda1377b0ce22db168f22ec95a9e809637938a31",
"address": "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq",
"type": "witness_v0_keyhash"
}
}
]
}

입력으로 0.19843440 BTC가 담긴 UTXO가 사용되었고, bc2 지갑으로 보내고 남은 비트코인은 bcrt1q9wk0js2hghrr3jy2vfjhxvrgd3cvnppv7n6dh0(내 지갑 주소)로 보냈다.

입력에서 모든 출력을 뺀 (0.19843440 - 0.09840620 - 0.1 = 0.0000282) 비트코인은 수수료로 사용된다.

다시 bc1 지갑의 UTXO를 확인해보자.

bc1 listunspent
[
{
"txid": "5dd19dc27a29f1cd0b063054511b1205a3c2712c81d1b5d4a00c13e20c44e2a0",
"vout": 0,
"address": "bcrt1qfvdqxtc83nuupkzgjxfc6djhewhjm4wrwsjk8s",
"label": "",
"scriptPubKey": "00144b1a032f078cf9c0d84891938d3657cbaf2dd5c3",
"amount": 2.00000000,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/0/3]027103f4c8edac9bfb89704b3e0e6293c614418da7ab05e7c3c8c22f866c50bb0a)#z9l6wxha",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/0/*)#20jjtpgm"
],
"safe": true
}
]

bc2 지갑으로 보내고 남은 UTXO는 보이지 않는다. 그것은 해당 트랜잭션이 블록에 포함된 후에 확인할 수 있다.

아직 블록에 포함되지 않은 트랜잭션을 확인해보자.

bc1 getrawmempool
[
"887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a"
]
bc2 getrawmempool
[
"887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a"
]

bc1 노드와 bc2 노드 모두 방금 전 생성된 트랜잭션이 멤풀에 있다는 것을 알고 있다.

이제 블록을 채굴해보자.

bc2 -generate 1
{
"address": "bcrt1quv3na0x20a0k8fgwfzf78a4v9kphl254qqdzk8",
"blocks": [
"492c8d2fd0d94c8eb2c755a9893e4984014fc551e0f68bb1380199d7de480d43"
]
}
bc1 getrawmempool
[
]
bc1 listunspent
[
{
"txid": "887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a",
"vout": 0,
"address": "bcrt1q9wk0js2hghrr3jy2vfjhxvrgd3cvnppv7n6dh0",
"scriptPubKey": "00142bacf9415745c638c88a62657330686c70c9842c",
"amount": 0.09840620,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/1/7]03aac0ff2208c45795d8d9b43015140a2235f003c1e855375ebe0b4bc43bfd823e)#4m7vep9j",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/1/*)#mmhnk5cr"
],
"safe": true
},
{
"txid": "5dd19dc27a29f1cd0b063054511b1205a3c2712c81d1b5d4a00c13e20c44e2a0",
"vout": 0,
"address": "bcrt1qfvdqxtc83nuupkzgjxfc6djhewhjm4wrwsjk8s",
"label": "",
"scriptPubKey": "00144b1a032f078cf9c0d84891938d3657cbaf2dd5c3",
"amount": 2.00000000,
"confirmations": 2,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/0/3]027103f4c8edac9bfb89704b3e0e6293c614418da7ab05e7c3c8c22f866c50bb0a)#z9l6wxha",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/0/*)#20jjtpgm"
],
"safe": true
}
]

블록 채굴 후 멤풀은 비워졌으며 bc1 지갑의 UTXO에 사용하고 남은 비트코인이 잘 들어온 것을 확인할 수 있다.

가장 어려운 방법: createrawtransaction

sendtoaddress 명령어는 받는 사람의 주소와 보내는 비트코인 수량만 입력하면 자동으로 트랜잭션이 생성되고 네트워크로 전파되었다. 하지만 입력으로 사용될 UTXO를 선택하는 등의 세부적인 기능을 제공하지 않는다.

createrawtransaction 명령어를 사용하면 트랜잭션의 세부적인 내용을 입력할 수 있다.

아래는 createrawtransaction 명령어를 사용해서 2 BTC가 남은 UTXO를 입력으로 사용한다.

bc1 -named createrawtransaction inputs='''[ { "txid": "5dd19dc27a29f1cd0b063054511b1205a3c2712c81d1b5d4a00c13e20c44e2a0", "vout": 0 } ]''' outputs='''{ "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq": 1.9995 }'''
0200000001a0e2440ce2130ca0d4b5d1812c71c2a305121b515430060bcdf1297ac29dd15d0000000000fdffffff01b0feea0b00000000160014dda1377b0ce22db168f22ec95a9e809637938a3100000000

이 외에도 sequence, locktime 등의 필드를 입력할 수도 있다.

한 가지 주의할 점은 createrawtransaction 명령어는 수수료 계산을 자동으로 해주지 않는다는 점이다. 출력에서 사용한 비트코인을 제외하고 남은 잔금은 모두 수수료로 사용된다. 따라서 잔금이 발생하는 경우 이를 위한 출력도 추가해주어야 한다. 이에 대한 자세한 내용은 뒤에서 다룬다.

createrawtransaction 명령어는 트랜잭션 생성만 하고 네트워크로 전파하지는 않는다. decoderawtransaction 명령어를 이용해서 트랜잭션이 제대로 생성됐는지 확인해보자.

bc1 decoderawtransaction 0200000001a0e2440ce2130ca0d4b5d1812c71c2a305121b515430060bcdf1297ac29dd15d0000000000fdffffff01b0feea0b00000000160014dda1377b0ce22db168f22ec95a9e809637938a3100000000
{
"txid": "57839a34e8fdbbdcb04fd4120397145f4f382a9b7a99988d1624a553f26836fa",
"hash": "57839a34e8fdbbdcb04fd4120397145f4f382a9b7a99988d1624a553f26836fa",
"version": 2,
"size": 82,
"vsize": 82,
"weight": 328,
"locktime": 0,
"vin": [
{
"txid": "5dd19dc27a29f1cd0b063054511b1205a3c2712c81d1b5d4a00c13e20c44e2a0",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967293
}
],
"vout": [
{
"value": 1.99950000,
"n": 0,
"scriptPubKey": {
"asm": "0 dda1377b0ce22db168f22ec95a9e809637938a31",
"desc": "addr(bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq)#d8pafqy3",
"hex": "0014dda1377b0ce22db168f22ec95a9e809637938a31",
"address": "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq",
"type": "witness_v0_keyhash"
}
}
]
}

입력과 출력이 의도한대로 잘 적용되었다. sequence 4294967293은 16진수로 0xFFFFFFFF이며 RBF(트랜잭션 수수료 인상 기능)가 불가능한 상태를 의미한다.

해당 트랜잭션을 네트워크로 전파하기 위해서는 서명을 해야한다. signrawtransactionwithwallet 명령어를 이용해서 서명을 하자.

bc1 signrawtransactionwithwallet 0200000001a0e2440ce2130ca0d4b5d1812c71c2a305121b515430060bcdf1297ac29dd15d0000000000fdffffff01b0feea0b00000000160014dda1377b0ce22db168f22ec95a9e809637938a3100000000
{
"hex": "02000000000101a0e2440ce2130ca0d4b5d1812c71c2a305121b515430060bcdf1297ac29dd15d0000000000fdffffff01b0feea0b00000000160014dda1377b0ce22db168f22ec95a9e809637938a31024730440220561ba43a072b7fe088ac38dddbe8c40df88e9597823010d00d10186447dbce4302207bf21bd2829a9b65e6921e294a90000fe8db9382b19aafd71271a6bada7ab6480121027103f4c8edac9bfb89704b3e0e6293c614418da7ab05e7c3c8c22f866c50bb0a00000000",
"complete": true
}

sendrawtransaction 명령어를 이용해서 서명된 데이터를 네트워크로 전파하자.

bc1 sendrawtransaction 02000000000101a0e2440ce2130ca0d4b5d1812c71c2a305121b515430060bcdf1297ac29dd15d0000000000fdffffff01b0feea0b00000000160014dda1377b0ce22db168f22ec95a9e809637938a31024730440220561ba43a072b7fe088ac38dddbe8c40df88e9597823010d00d10186447dbce4302207bf21bd2829a9b65e6921e294a90000fe8db9382b19aafd71271a6bada7ab6480121027103f4c8edac9bfb89704b3e0e6293c614418da7ab05e7c3c8c22f866c50bb0a00000000
57839a34e8fdbbdcb04fd4120397145f4f382a9b7a99988d1624a553f26836fa

bc2 노드에서 채굴한 후에 bc1 지갑의 UTXO를 확인해보자.

bc2 -generate 1
{
"address": "bcrt1qcj57qdae5d5chkzcqkjcj5ylgysfxgptjsffm0",
"blocks": [
"79b5414019770d16521bc711904a96e5da21b1a533034ee5b583832b56ce8f79"
]
}
bc1 listunspent
[
{
"txid": "887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a",
"vout": 0,
"address": "bcrt1q9wk0js2hghrr3jy2vfjhxvrgd3cvnppv7n6dh0",
"scriptPubKey": "00142bacf9415745c638c88a62657330686c70c9842c",
"amount": 0.09840620,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/1/7]03aac0ff2208c45795d8d9b43015140a2235f003c1e855375ebe0b4bc43bfd823e)#4m7vep9j",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/1/*)#mmhnk5cr"
],
"safe": true
}
]

2 BTC UTXO가 사라진 것을 확인할 수 있다.

change address 사용하기

이전 예제에서는 출력이 하나만 존재했지만 실사용 예와는 거래가 멀다. 이전 예제는 자신의 지갑을 (자신의) 다른 지갑으로 이동시키는 경우 말고는 발생하기 힘든 예다.

보통은 보내고자 하는 금액이 UTXO 목록에 있는 숫자와 일치하지 않으므로 보내고 남은 잔돈을 다시 자신의 지갑으로 보낸다. 이렇게 잔돈을 위해 사용되는 주소를 change address라고 부른다.

createrawtransaction 명령어를 이용해서 change address를 포함하는 트랜잭션을 만들어보자.

getrawchangeaddress 명령어를 이용해서 본인의 change address를 생성하자.

bc1 getrawchangeaddress
bcrt1q4n5dq56vr0qkwxjgsfasuf4h5z8pqn0g6kmhrc

createrawtransaction 명령어를 이용해서 change address를 포함하는 트랜잭션을 생성하자.

bc1 -named createrawtransaction inputs='''[ { "txid": "887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a", "vout": 0 } ]''' outputs='''{ "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq": 0.02, "bcrt1q4n5dq56vr0qkwxjgsfasuf4h5z8pqn0g6kmhrc": 0.0783 }'''
02000000012a25849d99876373e90645e5c9bd8ccc5d64bcc7c3da2db671ba705b5e9d7b880000000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a31f079770000000000160014ace8d0534c1bc1671a48827b0e26b7a08e104de800000000

change address를 포함하므로 출력이 2개가 되었다.

생성된 트랜잭션을 서명하고 네트워크로 전파하자.

bc1 signrawtransactionwithwallet 02000000012a25849d99876373e90645e5c9bd8ccc5d64bcc7c3da2db671ba705b5e9d7b880000000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a31f079770000000000160014ace8d0534c1bc1671a48827b0e26b7a08e104de800000000
{
"hex": "020000000001012a25849d99876373e90645e5c9bd8ccc5d64bcc7c3da2db671ba705b5e9d7b880000000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a31f079770000000000160014ace8d0534c1bc1671a48827b0e26b7a08e104de80247304402206ba17938c75134c0476186e8f04fe60a6452f0899c263d36762a981826b3744e02201f76a0cddbc42bf1f34f979099547cdae879d7095ae110990e9b85e802c3a963012103aac0ff2208c45795d8d9b43015140a2235f003c1e855375ebe0b4bc43bfd823e00000000",
"complete": true
}
bc1 sendrawtransaction 020000000001012a25849d99876373e90645e5c9bd8ccc5d64bcc7c3da2db671ba705b5e9d7b880000000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a31f079770000000000160014ace8d0534c1bc1671a48827b0e26b7a08e104de80247304402206ba17938c75134c0476186e8f04fe60a6452f0899c263d36762a981826b3744e02201f76a0cddbc42bf1f34f979099547cdae879d7095ae110990e9b85e802c3a963012103aac0ff2208c45795d8d9b43015140a2235f003c1e855375ebe0b4bc43bfd823e00000000
6231643c6cbe97e916a7e974f4575c832186b976135b0a36483a276899f69c85

생성된 트랜잭션을 포함하는 블록을 채굴하고 bc1 지갑의 UTXO를 확인해보자.

bc2 -generate 1
{
"address": "bcrt1qc26ulzxhmppve2pygkda5up4k78d5ycsr27wyh",
"blocks": [
"52481e5cc14eaa72208e1d135af4f839df308ce8afd5a23513542eda0fbca7f6"
]
}
bc1 listunspent
[
{
"txid": "6231643c6cbe97e916a7e974f4575c832186b976135b0a36483a276899f69c85",
"vout": 1,
"address": "bcrt1q4n5dq56vr0qkwxjgsfasuf4h5z8pqn0g6kmhrc",
"scriptPubKey": "0014ace8d0534c1bc1671a48827b0e26b7a08e104de8",
"amount": 0.07830000,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/1/8]02633b22afd2ff8168404a164900943c6843fefa4ff9d7a3a79c868b0e522b64a2)#mwlrtk8k",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/1/*)#mmhnk5cr"
],
"safe": true
}
]

change address에 잔금이 들어온 것을 확인할 수 있다.

중간 난이도: fundrawtransaction

createrawtransaction 명령어는 강력하지만 수수료 계산이나 UTXO를 선택하는 과정이 번거롭고 실수의 여지가 있다는 위험도 있다. fundrawtransaction 명령어는 이런 단점을 보완해준다.

아래 createrawtransaction 명령어에서는 입력값을 빈 배열로 입력하고 있다. 또한 잔금(change address)에 대한 처리도 하지 않고 있다.

bc1 -named createrawtransaction inputs='''[]''' outputs='''{ "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq": 0.02 }'''
02000000000180841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a3100000000

이렇게 생성된 트랜잭션을 fundrawtransaction 명령어에 입력하면 입력하지 않았던 부분을 자동으로 채워준다.

bc1 fundrawtransaction 02000000000180841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a3100000000
{
"hex": "0200000001859cf69968273a48360a5b1376b98621835c57f474e9a716e997be6c3c6431620100000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a316cea580000000000160014e87bec21f4cb26a24e75a2950fe243e99868bd0200000000",
"fee": 0.00002820,
"changepos": 1
}

fundrawtransaction 명령어가 생성한 트랜잭션을 확인해보자.

bc1 decoderawtransaction 0200000001859cf69968273a48360a5b1376b98621835c57f474e9a716e997be6c3c6431620100000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a316cea580000000000160014e87bec21f4cb26a24e75a2950fe243e99868bd0200000000
{
"txid": "033129c3e660abe2ee6a36cb054751a94aab048668f157e179b982036b51e990",
"hash": "033129c3e660abe2ee6a36cb054751a94aab048668f157e179b982036b51e990",
"version": 2,
"size": 113,
"vsize": 113,
"weight": 452,
"locktime": 0,
"vin": [
{
"txid": "6231643c6cbe97e916a7e974f4575c832186b976135b0a36483a276899f69c85",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967293
}
],
"vout": [
{
"value": 0.02000000,
"n": 0,
"scriptPubKey": {
"asm": "0 dda1377b0ce22db168f22ec95a9e809637938a31",
"desc": "addr(bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq)#d8pafqy3",
"hex": "0014dda1377b0ce22db168f22ec95a9e809637938a31",
"address": "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq",
"type": "witness_v0_keyhash"
}
},
{
"value": 0.05827180,
"n": 1,
"scriptPubKey": {
"asm": "0 e87bec21f4cb26a24e75a2950fe243e99868bd02",
"desc": "addr(bcrt1qapa7cg05evn2ynn4522slcjraxvx30gz0uz8qz)#5mkeydxd",
"hex": "0014e87bec21f4cb26a24e75a2950fe243e99868bd02",
"address": "bcrt1qapa7cg05evn2ynn4522slcjraxvx30gz0uz8qz",
"type": "witness_v0_keyhash"
}
}
]
}

fundrawtransaction 명령어가 자동으로 UTXO에서 하나를 선택해서 입력에 넣었다는 것을 확인할 수 있다. 또한 출력이 두 개인 것을 통해 change address도 자동으로 입력된 것을 확인할 수 있다. 이는 곧 수수료 계산도 자동으로 되었다는 것을 의미한다.

수수료 = 0.07830000 - 0.02000000 - 0.05827180 = 0.0000282 BTC

fundrawtransaction 명령어가 생성한 트랜잭션을 서명하고 네트워크로 전파하자.

bc1 signrawtransactionwithwallet 0200000001859cf69968273a48360a5b1376b98621835c57f474e9a716e997be6c3c6431620100000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a316cea580000000000160014e87bec21f4cb26a24e75a2950fe243e99868bd0200000000
{
"hex": "02000000000101859cf69968273a48360a5b1376b98621835c57f474e9a716e997be6c3c6431620100000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a316cea580000000000160014e87bec21f4cb26a24e75a2950fe243e99868bd020247304402203684758a6dd679b272e4f12768c2ab4e0fe0a11fb62e3ae2c002b7b57f0384410220762af42ca9eb37693850f27c68e552d0f31c4e5c8aa93eae2b0add693e41f17e012102633b22afd2ff8168404a164900943c6843fefa4ff9d7a3a79c868b0e522b64a200000000",
"complete": true
}
bc1 sendrawtransaction 02000000000101859cf69968273a48360a5b1376b98621835c57f474e9a716e997be6c3c6431620100000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a316cea580000000000160014e87bec21f4cb26a24e75a2950fe243e99868bd020247304402203684758a6dd679b272e4f12768c2ab4e0fe0a11fb62e3ae2c002b7b57f0384410220762af42ca9eb37693850f27c68e552d0f31c4e5c8aa93eae2b0add693e41f17e012102633b22afd2ff8168404a164900943c6843fefa4ff9d7a3a79c868b0e522b64a200000000
033129c3e660abe2ee6a36cb054751a94aab048668f157e179b982036b51e990

블록을 채굴하고 bc1 지갑의 UTXO를 확인해보자.

bc2 -generate 1
{
"address": "bcrt1qz8kuvn60cu3qezkr57wypnp7lu2ws9qakw6xxs",
"blocks": [
"4efcc5930021f48a6d9d65aab04c6a87a382064cbf933ac9c3bfa44e3fe3bd6b"
]
}
bc1 listunspent
[
{
"txid": "033129c3e660abe2ee6a36cb054751a94aab048668f157e179b982036b51e990",
"vout": 1,
"address": "bcrt1qapa7cg05evn2ynn4522slcjraxvx30gz0uz8qz",
"scriptPubKey": "0014e87bec21f4cb26a24e75a2950fe243e99868bd02",
"amount": 0.05827180,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "wpkh([bd28eb6d/84'/1'/0'/1/9]02d09342168e257c8645e3c601b8f3bdce22db64ee616fb7300a2aa92ffe8c7914)#x4dtx4ac",
"parent_descs": [
"wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/1/*)#mmhnk5cr"
],
"safe": true
}
]

잔금이 잘 들어온 것을 확인할 수 있다.

curl 이용 방법

지금까지는 bitcoin-cli를 이용해서 트랜잭션을 생성하고 네트워크로 전파하는 방법에 대해 알아봤다. curl을 이용하면 bitcoin-cli 도움 없이 원격으로 bitcoind와 직접 소통할 수 있다.

curl을 이용해서 bitcoind의 API를 호출하기 위해서는 계정 정보와 포트 번호가 필요하다. 이 정보는 bitcoin.conf 파일에서 확인할 수 있다.

아래는 bitcoin.conf 파일의 일부 내용이다.

rpcuser=w1
rpcpassword=w1
rpcport=1111

아래와 같은 형태로 curl을 이용해서 bitcoind API를 직접 호출할 수 있다.

curl --user {rpcuser}:{rpcpassword} --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:{rpcport}/

위 bitcoin.conf 파일의 내용으로 실제 동작하는 명령어는 다음과 같다.

curl --user w1:w1 --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:1111/
{"result":242,"error":null,"id":"curltest"}

아래는 createrawtransaction 명령어를 호출하고 있다.

curl --user w1:w1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "887b9d5e5b70ba71b62ddac3c7bc645dcc8cbdc9e54506e9736387999d84252a", "vout": 0 } ]'', ''{ "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq": 0.02, "bcrt1q4n5dq56vr0qkwxjgsfasuf4h5z8pqn0g6kmhrc": 0.05}'']}' -H 'content-type: text/plain;' http://127.0.0.1:1111/
{"result":"02000000012a25849d99876373e90645e5c9bd8ccc5d64bcc7c3da2db671ba705b5e9d7b880000000000fdffffff0280841e0000000000160014dda1377b0ce22db168f22ec95a9e809637938a31404b4c0000000000160014ace8d0534c1bc1671a48827b0e26b7a08e104de800000000","error":null,"id":"curltest"}

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