PSBT(Partially Signed Bitcoin Transactions)는 부분적으로만 서명되어 완전한 상태가 아닌 트랜잭션을 말한다. 한 사람이 하나의 기기에서 트랜잭션을 만든다면 PSBT를 사용할 이유는 없다. PSBT는 여러 사람 혹은 여러 기기가 서로 협력해서 하나의 트랜잭션을 만드는 상황에 적합하다. 그 중 Multisig가 여러 사람이 협력해서 하나의 트랜잭션을 만드는 대표적인 예다. 또는 하드웨어 지갑 처럼 여러 기기가 협력해서 하나의 트랜잭션을 만드는 것도 PSBT의 대표적인 활용 예다. 트랜잭션 생성과 전송은 다른 기기가 담당하면서 하드웨어 지갑은 서명만 담당하게 된다.
PSBT는 사실상의 표준으로써 비트코인 생태계에서 널리 사용된다. 대부분의 하드웨어 지갑이 PSBT 방식으로 트랜잭션을 처리한다.
PSBT의 Multisig 방식은 PSBT 이전의 Multisig에 비해 두드러지는 장점이 있다. PSBT 이전의 Multisig는 하나의 트랜잭션을 만들기 위해 참여자들이 순차적으로 서명을 진행해야 했다. 하지만 PSBT의 Multisig 방식은 병렬로 서명을 진행할 수 있다. 트랜잭션 초안을 모든 참여자들에게 전송하고 각자 서명한 내용을 한 사람이 모아서 제출할 수 있다. 따라서 훨씬 간편하고 빠르게 Multisig 트랜잭션을 완성할 수 있다.
bitcoind 명령어를 이용해서 PSBT 트랜잭션을 만들어보자.
초기 설정은 이전 글에서 다룬 내용을 참고하자.
하나의 노드에서 여러 지갑을 관리할 예정이므로 아래와 같이 지갑별 별칭을 만들어놓자.
❯ alias bc1="bitcoin-cli -rpcuser=w1 -rpcpassword=w1 -rpcport=1111 -rpcwallet=w1"❯ alias bc2="bitcoin-cli -rpcuser=w2 -rpcpassword=w2 -rpcport=2222 -rpcwallet=w2"❯ alias bcm1="bitcoin-cli -rpcuser=w1 -rpcpassword=w1 -rpcport=1111 -rpcwallet=multisig1"❯ alias bcm2="bitcoin-cli -rpcuser=w2 -rpcpassword=w2 -rpcport=2222 -rpcwallet=multisig2"
multisig1, multisig2 지갑은 잠시후에 생성한다.
HD 지갑에서 지갑 정보를 다룰 때는 descriptor를 이용하는 게 좋다.
listdescriptors 명령어를 이용해서 descriptor 정보를 확인해보자.
❯ bc1 listdescriptors{"wallet_name": "w1","descriptors": [{"desc": "wpkh([bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*)#r0sae4rz","timestamp": 1704524797,"active": true,"internal": false,"range": [0,1014],"next": 15,"next_index": 15},...❯ bc2 listdescriptors{"wallet_name": "w2","descriptors": [{"desc": "wpkh([3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*)#2pvq6j4r","timestamp": 1704527030,"active": true,"internal": false,"range": [0,1040],"next": 41,"next_index": 41},...
descriptors 목록에 많은 항목이 출력되는데 우리는 그 중에서 84로 시작하는 P2WPKH 주소 유형을 이용하자.
desc 속성에서 wpkh 괄호 안에 있는 내용만 복사하자. 마지막이 0/*
로 끝나면 외부 주소. 1/*
로 끝나면 내부(change) 주소를 의미한다.
Multisig descriptor는 아래 형식을 따른다.
wsh(sortedmulti(n, wallet_1, ..., wallet_m))#checksum
n은 필요한 서명의 갯수를 의미한다. 우리는 2개의 지갑으로 2개의 서명을 요구하는 Multisig 지갑을 만들자.
위에서 복사한 값을 wallet_1, wallet_2 부분에 사용하자. checksum을 제외하고 지금까지 계산된 값을 변수에 저장하자.
❯ d1="wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*))"❯ d2="wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/1/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/1/*))"
외부/내부 주소를 위한 Multisig descriptor를 각각 d1, d2 변수에 저장했다.
getdescriptorinfo 명령어를 이용해서 checksum 값을 얻을 수 있다.
❯ bc1 getdescriptorinfo $d1{"descriptor": "wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*))#7fdwfx0a","checksum": "7fdwfx0a","isrange": true,"issolvable": true,"hasprivatekeys": false}❯ bc1 getdescriptorinfo $d2{"descriptor": "wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/1/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/1/*))#hp9up5nq","checksum": "hp9up5nq","isrange": true,"issolvable": true,"hasprivatekeys": false}
descriptor 속성에서 checksum이 붙은 최종 값을 확인할 수 있다. 이 값을 변수에 저장하자.
❯ desc1="wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*))#7fdwfx0a"❯ desc2="wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/1/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/1/*))#hp9up5nq"
이제 Multisig를 위한 지갑을 생성하자.
❯ bc1 -named createwallet wallet_name="multisig1" disable_private_keys=true blank=true{"name": "multisig1"}❯ bc2 -named createwallet wallet_name="multisig2" disable_private_keys=true blank=true{"name": "multisig2"}
descriptor에는 개인키 정보가 없으므로 disable_private_keys 옵션에 true를 입력했다. multisig1, multisig2 지갑에는 개인키가 없으므로 서명은 w1, w2 지갑에서 해야한다.
importdescriptors 명령어를 이용해서 multisig1, multisig2 지갑에 이전에 생성한 Multisig 지갑 정보를 입력하자.
❯ bcm1 importdescriptors '[{ "desc": "'$desc1'", "timestamp":"now", "internal": false, "active": true},{ "desc": "'$desc2'", "timestamp":"now", "internal": true, "active": true}]'[{"success": true,"warnings": ["Range not given, using default keypool range"]},{"success": true,"warnings": ["Range not given, using default keypool range"]}]❯ bcm2 importdescriptors '[{ "desc": "'$desc1'", "timestamp":"now", "internal": false, "active": true},{ "desc": "'$desc2'", "timestamp":"now", "internal": true, "active": true}]'[{"success": true,"warnings": ["Range not given, using default keypool range"]},{"success": true,"warnings": ["Range not given, using default keypool range"]}]
배열에는 외부/내부 주소 정보를 각각 넣어줬다. 이렇게 하면 주소가 필요한 경우 bitcoind가 외부/내부 주소 중에 적절한 주소를 가져다 사용한다.
multisig1, multisig2 지갑에 똑같은 descriptor 정보를 입력했다.
descriptor가 잘 추가되었는지 확인해보자.
❯ bcm1 listdescriptors{"wallet_name": "multisig1","descriptors": [{"desc": "wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*))#7fdwfx0a","timestamp": 1705725737,"active": true,"internal": false,"range": [0,1001],"next": 2,"next_index": 2},{"desc": "wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/1/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/1/*))#hp9up5nq","timestamp": 1705725737,"active": true,"internal": true,"range": [0,1001],"next": 2,"next_index": 2}]}
우리가 생성했던 descriptor 정보가 추가된 것을 확인할 수 있다.
Multisig 지갑 주소를 하나 생성하자.
❯ bcm1 getnewaddressbcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5
위에서 생성한 주소로 비트코인을 보내자.
❯ bc1 sendtoaddress bcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5 0.001e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f❯ bc2 -generate 1{"address": "bcrt1q4j3h06l9kmpzr2emqedvl7yemfvansmce4de94","blocks": ["49617118e868ef55e2de6d9dd3f02c5823190703a9279cf99b79b0a740eed055"]}
Multisig 지갑의 UTXO를 확인해보자.
❯ bcm1 listunspent[{"txid": "e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f","vout": 1,"address": "bcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5","label": "","witnessScript": "522102191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f210311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d52ae","scriptPubKey": "002055aa278435d1f846329dbef4c7c04f878e9c06375cbecf6aea9337b02702ce46","amount": 0.00100000,"confirmations": 1,"spendable": true,"solvable": true,"desc": "wsh(multi(2,[bd28eb6d/84'/1'/0'/0/0]02191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f,[3011c15a/84'/1'/0'/0/0]0311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d))#hexyqs0l","parent_descs": ["wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*))#7fdwfx0a"],"safe": true}]
0.001 BTC가 잘 입금된 것을 확인할 수 있다.
비트코인을 받을 주소를 하나 준비하자.
❯ bc1 getnewaddressbcrt1qnj5qtna6ny48vy5zwsn4qk2450xncvypvukemk
walletcreatefundedpsbt 명령어를 이용해서 PSBT 트랜잭션을 생성하자.
❯ bcm1 -named walletcreatefundedpsbt outputs='''{"bcrt1qnj5qtna6ny48vy5zwsn4qk2450xncvypvukemk": 0.0005}'''{"psbt": "cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYBBUdSIQIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RHyEDEfw8lXXJwRJtJgk7Hg1EOGNpxiTPAUBnJhswOWPcFG1SriIGAhkcBkS8LtdbV7JFiB1R9ZjFLsdmsJOvdqAf7yNhzhEfGL0o621UAACAAQAAgAAAAIAAAAAAAAAAACIGAxH8PJV1ycESbSYJOx4NRDhjacYkzwFAZyYbMDlj3BRtGDARwVpUAACAAQAAgAAAAIAAAAAAAAAAAAABAUdSIQMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKyED2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3hSriICAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErGL0o621UAACAAQAAgAAAAIABAAAAAAAAACICA9nqUXJaiM2MmfpCvqJhvhVSS2dv0x7P7gMm2Qnv0It4GDARwVpUAACAAQAAgAAAAIABAAAAAAAAAAAA","fee": 0.00003620,"changepos": 0}❯ psbt=cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYBBUdSIQIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RHyEDEfw8lXXJwRJtJgk7Hg1EOGNpxiTPAUBnJhswOWPcFG1SriIGAhkcBkS8LtdbV7JFiB1R9ZjFLsdmsJOvdqAf7yNhzhEfGL0o621UAACAAQAAgAAAAIAAAAAAAAAAACIGAxH8PJV1ycESbSYJOx4NRDhjacYkzwFAZyYbMDlj3BRtGDARwVpUAACAAQAAgAAAAIAAAAAAAAAAAAABAUdSIQMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKyED2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3hSriICAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErGL0o621UAACAAQAAgAAAAIABAAAAAAAAACICA9nqUXJaiM2MmfpCvqJhvhVSS2dv0x7P7gMm2Qnv0It4GDARwVpUAACAAQAAgAAAAIABAAAAAAAAAAAA
walletcreatefundedpsbt 명령어는 UTXO로부터 입력을 자동으로 구성해준다. 따라서 우리는 편하게 출력값만 입력했다.
트랜잭션을 psbt 변수에 저장했다.
analyzepsbt 명령어를 이용해서 현재 상태를 확인해보자.
❯ bcm1 analyzepsbt $psbt{"inputs": [{"has_utxo": true,"is_final": false,"next": "signer","missing": {"signatures": ["00e0b2e84502676d2efaa24609443882bcde8d30","53c9f5492276604b701db3d84abaed5b230a20f3"]}}],"estimated_vsize": 180,"estimated_feerate": 0.00020111,"fee": 0.00003620,"next": "signer"}
next 속성을 통해 서명이 필요하다는 것을 알 수 있다.
decodepsbt 명령어를 이용해서 좀 더 자세한 내용을 확인해보자.
❯ bcm1 decodepsbt $psbt{"tx": {"txid": "95a2bda06f83a0074232e0229a5d555bd9e2b4511a289d60bdebfaef93d1ac75","hash": "95a2bda06f83a0074232e0229a5d555bd9e2b4511a289d60bdebfaef93d1ac75","version": 2,"size": 125,"vsize": 125,"weight": 500,"locktime": 0,"vin": [{"txid": "e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f","vout": 1,"scriptSig": {"asm": "","hex": ""},"sequence": 4294967293}],"vout": [{"value": 0.00046380,"n": 0,"scriptPubKey": {"asm": "0 86619970e0a58b265a25453887639a2c8e59d19686350707097cc2efd38dc6c7","desc": "addr(bcrt1qseseju8q5k9jvk39g5ugwcu69j89n5vksc6swpcf0npwl5udcmrsy200yh)#tdhve4jj","hex": "002086619970e0a58b265a25453887639a2c8e59d19686350707097cc2efd38dc6c7","address": "bcrt1qseseju8q5k9jvk39g5ugwcu69j89n5vksc6swpcf0npwl5udcmrsy200yh","type": "witness_v0_scripthash"}},{"value": 0.00050000,"n": 1,"scriptPubKey": {"asm": "0 9ca805cfba992a7612827427505955a3cd3c3081","desc": "addr(bcrt1qnj5qtna6ny48vy5zwsn4qk2450xncvypvukemk)#9vmdphup","hex": "00149ca805cfba992a7612827427505955a3cd3c3081","address": "bcrt1qnj5qtna6ny48vy5zwsn4qk2450xncvypvukemk","type": "witness_v0_keyhash"}}]},"global_xpubs": [],"psbt_version": 0,"proprietary": [],"unknown": {},"inputs": [{"witness_utxo": {"amount": 0.00100000,"scriptPubKey": {"asm": "0 55aa278435d1f846329dbef4c7c04f878e9c06375cbecf6aea9337b02702ce46","desc": "addr(bcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5)#uwsnszvn","hex": "002055aa278435d1f846329dbef4c7c04f878e9c06375cbecf6aea9337b02702ce46","address": "bcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5","type": "witness_v0_scripthash"}},"non_witness_utxo": {"txid": "e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f","hash": "e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f","version": 2,"size": 137,"vsize": 137,"weight": 548,"locktime": 251,"vin": [{"txid": "6ffad10ecfb024d2d81a351118a306e0f24fd384a0c78aa0bdcdd65b1a055cbd","vout": 1,"scriptSig": {"asm": "","hex": ""},"sequence": 4294967293}],"vout": [{"value": 0.08686380,"n": 0,"scriptPubKey": {"asm": "1 5d2cecbe38c2d2cd3c23e5922f2137a424332d9addb9ead72e874131b6080e29","desc": "rawtr(5d2cecbe38c2d2cd3c23e5922f2137a424332d9addb9ead72e874131b6080e29)#33ftp85s","hex": "51205d2cecbe38c2d2cd3c23e5922f2137a424332d9addb9ead72e874131b6080e29","address": "bcrt1pt5kwe03cctfv60prukfz7gfh5sjrxtv6mku744ewsaqnrdsgpc5sttkekl","type": "witness_v1_taproot"}},{"value": 0.00100000,"n": 1,"scriptPubKey": {"asm": "0 55aa278435d1f846329dbef4c7c04f878e9c06375cbecf6aea9337b02702ce46","desc": "addr(bcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5)#uwsnszvn","hex": "002055aa278435d1f846329dbef4c7c04f878e9c06375cbecf6aea9337b02702ce46","address": "bcrt1q2k4z0pp468uyvv5ahm6v0sz0s78fcp3htjlv76h2jvmmqfczeerqwa6ll5","type": "witness_v0_scripthash"}}]},"witness_script": {"asm": "2 02191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f 0311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d 2 OP_CHECKMULTISIG","hex": "522102191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f210311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d52ae","type": "multisig"},"bip32_derivs": [{"pubkey": "02191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f","master_fingerprint": "bd28eb6d","path": "m/84'/1'/0'/0/0"},{"pubkey": "0311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d","master_fingerprint": "3011c15a","path": "m/84'/1'/0'/0/0"}]}],"outputs": [{"witness_script": {"asm": "2 03178e97ff06cdfddf36cb812059a5bae81d5f27ca66473c140f006530bae9c12b 03d9ea51725a88cd8c99fa42bea261be15524b676fd31ecfee0326d909efd08b78 2 OP_CHECKMULTISIG","hex": "522103178e97ff06cdfddf36cb812059a5bae81d5f27ca66473c140f006530bae9c12b2103d9ea51725a88cd8c99fa42bea261be15524b676fd31ecfee0326d909efd08b7852ae","type": "multisig"},"bip32_derivs": [{"pubkey": "03178e97ff06cdfddf36cb812059a5bae81d5f27ca66473c140f006530bae9c12b","master_fingerprint": "bd28eb6d","path": "m/84'/1'/0'/1/0"},{"pubkey": "03d9ea51725a88cd8c99fa42bea261be15524b676fd31ecfee0326d909efd08b78","master_fingerprint": "3011c15a","path": "m/84'/1'/0'/1/0"}]},{}],"fee": 0.00003620}
하나의 UTXO가 입력으로 사용됐고 잔돈을 포함해서 2개의 출력이 있는 것을 확인할 수 있다. inputs, outputs 속성은 PSBT 데이터에 해당하는 부분이며 최종 트랜잭션에 포함되는 내용은 아니다.
walletprocesspsbt 명령어를 이용해서 두 지갑에서 각각 서명하자.
❯ bc1 walletprocesspsbt $psbt{"psbt": "cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYiAgIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RH0cwRAIgPaGSzm0HH6Q3bkEJrXDpXj1HhEbnx8YxU+xzvDY1/DcCIBqy22rfQ2SSMNxq8wdtpfGdgFc0XNMFmDioUHnIqHIhAQEFR1IhAhkcBkS8LtdbV7JFiB1R9ZjFLsdmsJOvdqAf7yNhzhEfIQMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbVKuIgYCGRwGRLwu11tXskWIHVH1mMUux2awk692oB/vI2HOER8YvSjrbVQAAIABAACAAAAAgAAAAAAAAAAAIgYDEfw8lXXJwRJtJgk7Hg1EOGNpxiTPAUBnJhswOWPcFG0YMBHBWlQAAIABAACAAAAAgAAAAAAAAAAAAAEBR1IhAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErIQPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeFKuIgIDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSsYvSjrbVQAAIABAACAAAAAgAEAAAAAAAAAIgID2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3gYMBHBWlQAAIABAACAAAAAgAEAAAAAAAAAACICA66nzaHtxT2vcw4lsFyuqWt/SyFYMJo75j1pzSgg4h6ZGL0o621UAACAAQAAgAAAAIAAAAAACgAAAAA=","complete": false}❯ bc2 walletprocesspsbt $psbt{"psbt": "cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYiAgMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbUcwRAIgAOF1AQGMlp+VrNP4DR7NvxUxYA0Lhr3kvKuZL+pcw6kCIDgTKfITTyWeLeDcAVokDw77WOMndOuPJzMf+EP2Rf3kAQEFR1IhAhkcBkS8LtdbV7JFiB1R9ZjFLsdmsJOvdqAf7yNhzhEfIQMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbVKuIgYCGRwGRLwu11tXskWIHVH1mMUux2awk692oB/vI2HOER8YvSjrbVQAAIABAACAAAAAgAAAAAAAAAAAIgYDEfw8lXXJwRJtJgk7Hg1EOGNpxiTPAUBnJhswOWPcFG0YMBHBWlQAAIABAACAAAAAgAAAAAAAAAAAAAEBR1IhAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErIQPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeFKuIgIDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSsYvSjrbVQAAIABAACAAAAAgAEAAAAAAAAAIgID2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3gYMBHBWlQAAIABAACAAAAAgAEAAAAAAAAAAAA=","complete": false}
위 과정을 통해 서명은 각자 병렬로 처리된다는 것을 알 수 있다.
서명된 PSBT를 변수에 저장하자.
❯ psbt1=cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYiAgIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RH0cwRAIgPaGSzm0HH6Q3bkEJrXDpXj1HhEbnx8YxU+xzvDY1/DcCIBqy22rfQ2SSMNxq8wdtpfGdgFc0XNMFmDioUHnIqHIhAQEFR1IhAhkcBkS8LtdbV7JFiB1R9ZjFLsdmsJOvdqAf7yNhzhEfIQMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbVKuIgYCGRwGRLwu11tXskWIHVH1mMUux2awk692oB/vI2HOER8YvSjrbVQAAIABAACAAAAAgAAAAAAAAAAAIgYDEfw8lXXJwRJtJgk7Hg1EOGNpxiTPAUBnJhswOWPcFG0YMBHBWlQAAIABAACAAAAAgAAAAAAAAAAAAAEBR1IhAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErIQPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeFKuIgIDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSsYvSjrbVQAAIABAACAAAAAgAEAAAAAAAAAIgID2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3gYMBHBWlQAAIABAACAAAAAgAEAAAAAAAAAACICA66nzaHtxT2vcw4lsFyuqWt/SyFYMJo75j1pzSgg4h6ZGL0o621UAACAAQAAgAAAAIAAAAAACgAAAAA=❯ psbt2=cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYiAgMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbUcwRAIgAOF1AQGMlp+VrNP4DR7NvxUxYA0Lhr3kvKuZL+pcw6kCIDgTKfITTyWeLeDcAVokDw77WOMndOuPJzMf+EP2Rf3kAQEFR1IhAhkcBkS8LtdbV7JFiB1R9ZjFLsdmsJOvdqAf7yNhzhEfIQMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbVKuIgYCGRwGRLwu11tXskWIHVH1mMUux2awk692oB/vI2HOER8YvSjrbVQAAIABAACAAAAAgAAAAAAAAAAAIgYDEfw8lXXJwRJtJgk7Hg1EOGNpxiTPAUBnJhswOWPcFG0YMBHBWlQAAIABAACAAAAAgAAAAAAAAAAAAAEBR1IhAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErIQPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeFKuIgIDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSsYvSjrbVQAAIABAACAAAAAgAEAAAAAAAAAIgID2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3gYMBHBWlQAAIABAACAAAAAgAEAAAAAAAAAAAA=
combinepsbt 명령어를 이용해서 서명된 각 PSBT를 하나로 합치자.
❯ bc1 combinepsbt '''["'$psbt1'","'$psbt2'"]'''cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYiAgIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RH0cwRAIgPaGSzm0HH6Q3bkEJrXDpXj1HhEbnx8YxU+xzvDY1/DcCIBqy22rfQ2SSMNxq8wdtpfGdgFc0XNMFmDioUHnIqHIhASICAxH8PJV1ycESbSYJOx4NRDhjacYkzwFAZyYbMDlj3BRtRzBEAiAA4XUBAYyWn5Ws0/gNHs2/FTFgDQuGveS8q5kv6lzDqQIgOBMp8hNPJZ4t4NwBWiQPDvtY4yd0648nMx/4Q/ZF/eQBAQVHUiECGRwGRLwu11tXskWIHVH1mMUux2awk692oB/vI2HOER8hAxH8PJV1ycESbSYJOx4NRDhjacYkzwFAZyYbMDlj3BRtUq4iBgIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RHxi9KOttVAAAgAEAAIAAAACAAAAAAAAAAAAiBgMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbRgwEcFaVAAAgAEAAIAAAACAAAAAAAAAAAAAAQFHUiEDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSshA9nqUXJaiM2MmfpCvqJhvhVSS2dv0x7P7gMm2Qnv0It4Uq4iAgMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKxi9KOttVAAAgAEAAIAAAACAAQAAAAAAAAAiAgPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeBgwEcFaVAAAgAEAAIAAAACAAQAAAAAAAAAAIgIDrqfNoe3FPa9zDiWwXK6pa39LIVgwmjvmPWnNKCDiHpkYvSjrbVQAAIABAACAAAAAgAAAAAAKAAAAAA==
finalizepsbt 명령어를 이용해서 최종 트랜잭션을 생성하자.
❯ bc1 finalizepsbt cHNidP8BAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAABAIkCAAAAAb1cBRpb1s29oIrHoITTT/LgBqMYETUa2NIksM8O0fpvAQAAAAD9////AiyLhAAAAAAAIlEgXSzsvjjC0s08I+WSLyE3pCQzLZrduerXLodBMbYIDimghgEAAAAAACIAIFWqJ4Q10fhGMp2+9MfAT4eOnAY3XL7PauqTN7AnAs5G+wAAAAEBK6CGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkYiAgIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RH0cwRAIgPaGSzm0HH6Q3bkEJrXDpXj1HhEbnx8YxU+xzvDY1/DcCIBqy22rfQ2SSMNxq8wdtpfGdgFc0XNMFmDioUHnIqHIhASICAxH8PJV1ycESbSYJOx4NRDhjacYkzwFAZyYbMDlj3BRtRzBEAiAA4XUBAYyWn5Ws0/gNHs2/FTFgDQuGveS8q5kv6lzDqQIgOBMp8hNPJZ4t4NwBWiQPDvtY4yd0648nMx/4Q/ZF/eQBAQVHUiECGRwGRLwu11tXskWIHVH1mMUux2awk692oB/vI2HOER8hAxH8PJV1ycESbSYJOx4NRDhjacYkzwFAZyYbMDlj3BRtUq4iBgIZHAZEvC7XW1eyRYgdUfWYxS7HZrCTr3agH+8jYc4RHxi9KOttVAAAgAEAAIAAAACAAAAAAAAAAAAiBgMR/DyVdcnBEm0mCTseDUQ4Y2nGJM8BQGcmGzA5Y9wUbRgwEcFaVAAAgAEAAIAAAACAAAAAAAAAAAAAAQFHUiEDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSshA9nqUXJaiM2MmfpCvqJhvhVSS2dv0x7P7gMm2Qnv0It4Uq4iAgMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKxi9KOttVAAAgAEAAIAAAACAAQAAAAAAAAAiAgPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeBgwEcFaVAAAgAEAAIAAAACAAQAAAAAAAAAAIgIDrqfNoe3FPa9zDiWwXK6pa39LIVgwmjvmPWnNKCDiHpkYvSjrbVQAAIABAACAAAAAgAAAAAAKAAAAAA=={"hex": "020000000001019f8b01dbe2d04964a5b40cd9ed08c490298235fb338baf96b47b105409cd54e50100000000fdffffff022cb500000000000022002086619970e0a58b265a25453887639a2c8e59d19686350707097cc2efd38dc6c750c30000000000001600149ca805cfba992a7612827427505955a3cd3c3081040047304402203da192ce6d071fa4376e4109ad70e95e3d478446e7c7c63153ec73bc3635fc3702201ab2db6adf43649230dc6af3076da5f19d8057345cd3059838a85079c8a8722101473044022000e17501018c969f95acd3f80d1ecdbf1531600d0b86bde4bcab992fea5cc3a90220381329f2134f259e2de0dc015a240f0efb58e32774eb8f27331ff843f645fde40147522102191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f210311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d52ae00000000","complete": true}
생성된 트랜잭션을 전송하고 Multisig 지갑의 잔고를 확인해보자.
❯ bc1 sendrawtransaction 020000000001019f8b01dbe2d04964a5b40cd9ed08c490298235fb338baf96b47b105409cd54e50100000000fdffffff022cb500000000000022002086619970e0a58b265a25453887639a2c8e59d19686350707097cc2efd38dc6c750c30000000000001600149ca805cfba992a7612827427505955a3cd3c3081040047304402203da192ce6d071fa4376e4109ad70e95e3d478446e7c7c63153ec73bc3635fc3702201ab2db6adf43649230dc6af3076da5f19d8057345cd3059838a85079c8a8722101473044022000e17501018c969f95acd3f80d1ecdbf1531600d0b86bde4bcab992fea5cc3a90220381329f2134f259e2de0dc015a240f0efb58e32774eb8f27331ff843f645fde40147522102191c0644bc2ed75b57b245881d51f598c52ec766b093af76a01fef2361ce111f210311fc3c9575c9c1126d26093b1e0d44386369c624cf014067261b303963dc146d52ae0000000095a2bda06f83a0074232e0229a5d555bd9e2b4511a289d60bdebfaef93d1ac75❯ bc2 -generate 1{"address": "bcrt1qzt6fh3e73a7pw9apg9gldg4gczhe635sejs2zy","blocks": ["071e7876d23d6cd7fa6f8516f363a0a5dde86a4e876226a180c7eef294ec72f2"]}❯ bcm1 getbalance0.00046380
보낸 0.0005 BTC와 수수료를 제외한 금액이 남았다
병렬로 서명하지 않고 순차적으로 서명하면 combinepsbt 명령어를 사용하지 않고 트랜잭션을 생성할 수 있다.
이전과 마찬가지로 walletcreatefundedpsbt 명령어를 이용해서 PSBT를 생성하자.
❯ bc1 getnewaddressbcrt1qh0v5scwc7l820kdfrucrm5az6ak9vzh4nz6z7z❯ bcm1 -named walletcreatefundedpsbt outputs='''{"bcrt1qh0v5scwc7l820kdfrucrm5az6ak9vzh4nz6z7z": 0.0002}'''{"psbt": "cHNidP8BAH0CAAAAAXWs0ZPv+uu9YJ0oGlG04tlbVV2aIuAyQgegg2+gvaKVAAAAAAD9////AuhYAAAAAAAAIgAghgk3+CtagWiOzcAW2utE3OVCQBlAYOCk5OI93VU89HAgTgAAAAAAABYAFLvZSGHY986n2akfMD3TotdsVgr1AAAAAAABAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAEBKyy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxscBBUdSIQMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKyED2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3hSriIGAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErGL0o621UAACAAQAAgAAAAIABAAAAAAAAACIGA9nqUXJaiM2MmfpCvqJhvhVSS2dv0x7P7gMm2Qnv0It4GDARwVpUAACAAQAAgAAAAIABAAAAAAAAAAABAUdSIQJt/GdDoj46t8nOb4qSAk320vPRzkf1OFGBLtqpIxFpliEC65n0frLTr9SgwSVsKvi2SN06+XTZW3YHnmNrh/HAKTJSriICAm38Z0OiPjq3yc5vipICTfbS89HOR/U4UYEu2qkjEWmWGDARwVpUAACAAQAAgAAAAIABAAAAAQAAACICAuuZ9H6y06/UoMElbCr4tkjdOvl02Vt2B55ja4fxwCkyGL0o621UAACAAQAAgAAAAIABAAAAAQAAAAAA","fee": 0.00003620,"changepos": 0}
walletprocesspsbt 명령어를 이용해서 서명하자. 1번 노드의 출력을 2번 노드가 받아서 순차적으로 서명한다.
❯ bc1 walletprocesspsbt cHNidP8BAH0CAAAAAXWs0ZPv+uu9YJ0oGlG04tlbVV2aIuAyQgegg2+gvaKVAAAAAAD9////AuhYAAAAAAAAIgAghgk3+CtagWiOzcAW2utE3OVCQBlAYOCk5OI93VU89HAgTgAAAAAAABYAFLvZSGHY986n2akfMD3TotdsVgr1AAAAAAABAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAEBKyy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxscBBUdSIQMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKyED2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3hSriIGAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErGL0o621UAACAAQAAgAAAAIABAAAAAAAAACIGA9nqUXJaiM2MmfpCvqJhvhVSS2dv0x7P7gMm2Qnv0It4GDARwVpUAACAAQAAgAAAAIABAAAAAAAAAAABAUdSIQJt/GdDoj46t8nOb4qSAk320vPRzkf1OFGBLtqpIxFpliEC65n0frLTr9SgwSVsKvi2SN06+XTZW3YHnmNrh/HAKTJSriICAm38Z0OiPjq3yc5vipICTfbS89HOR/U4UYEu2qkjEWmWGDARwVpUAACAAQAAgAAAAIABAAAAAQAAACICAuuZ9H6y06/UoMElbCr4tkjdOvl02Vt2B55ja4fxwCkyGL0o621UAACAAQAAgAAAAIABAAAAAQAAAAAA{"psbt": "cHNidP8BAH0CAAAAAXWs0ZPv+uu9YJ0oGlG04tlbVV2aIuAyQgegg2+gvaKVAAAAAAD9////AuhYAAAAAAAAIgAghgk3+CtagWiOzcAW2utE3OVCQBlAYOCk5OI93VU89HAgTgAAAAAAABYAFLvZSGHY986n2akfMD3TotdsVgr1AAAAAAABAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAEBKyy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsciAgMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBK0cwRAIgQLt8qnOWJraCp4jZbPvzecxsGtTEgQZtMcobPVAh3RgCIF4ZBYGdS5WyeoZyO+GzeEEwEtJJHomunhCC18Ktc8UZAQEFR1IhAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErIQPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeFKuIgYDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSsYvSjrbVQAAIABAACAAAAAgAEAAAAAAAAAIgYD2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3gYMBHBWlQAAIABAACAAAAAgAEAAAAAAAAAAAEBR1IhAm38Z0OiPjq3yc5vipICTfbS89HOR/U4UYEu2qkjEWmWIQLrmfR+stOv1KDBJWwq+LZI3Tr5dNlbdgeeY2uH8cApMlKuIgICbfxnQ6I+OrfJzm+KkgJN9tLz0c5H9ThRgS7aqSMRaZYYMBHBWlQAAIABAACAAAAAgAEAAAABAAAAIgIC65n0frLTr9SgwSVsKvi2SN06+XTZW3YHnmNrh/HAKTIYvSjrbVQAAIABAACAAAAAgAEAAAABAAAAACICAyR77jrbzjcPqUWByWTjFWRvZ8WjW315VXq3+edRrxLcGL0o621UAACAAQAAgAAAAIAAAAAACwAAAAA=","complete": false}❯ bc2 walletprocesspsbt cHNidP8BAH0CAAAAAXWs0ZPv+uu9YJ0oGlG04tlbVV2aIuAyQgegg2+gvaKVAAAAAAD9////AuhYAAAAAAAAIgAghgk3+CtagWiOzcAW2utE3OVCQBlAYOCk5OI93VU89HAgTgAAAAAAABYAFLvZSGHY986n2akfMD3TotdsVgr1AAAAAAABAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAEBKyy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsciAgMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBK0cwRAIgQLt8qnOWJraCp4jZbPvzecxsGtTEgQZtMcobPVAh3RgCIF4ZBYGdS5WyeoZyO+GzeEEwEtJJHomunhCC18Ktc8UZAQEFR1IhAxeOl/8Gzf3fNsuBIFmluugdXyfKZkc8FA8AZTC66cErIQPZ6lFyWojNjJn6Qr6iYb4VUktnb9Mez+4DJtkJ79CLeFKuIgYDF46X/wbN/d82y4EgWaW66B1fJ8pmRzwUDwBlMLrpwSsYvSjrbVQAAIABAACAAAAAgAEAAAAAAAAAIgYD2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3gYMBHBWlQAAIABAACAAAAAgAEAAAAAAAAAAAEBR1IhAm38Z0OiPjq3yc5vipICTfbS89HOR/U4UYEu2qkjEWmWIQLrmfR+stOv1KDBJWwq+LZI3Tr5dNlbdgeeY2uH8cApMlKuIgICbfxnQ6I+OrfJzm+KkgJN9tLz0c5H9ThRgS7aqSMRaZYYMBHBWlQAAIABAACAAAAAgAEAAAABAAAAIgIC65n0frLTr9SgwSVsKvi2SN06+XTZW3YHnmNrh/HAKTIYvSjrbVQAAIABAACAAAAAgAEAAAABAAAAACICAyR77jrbzjcPqUWByWTjFWRvZ8WjW315VXq3+edRrxLcGL0o621UAACAAQAAgAAAAIAAAAAACwAAAAA={"psbt": "cHNidP8BAH0CAAAAAXWs0ZPv+uu9YJ0oGlG04tlbVV2aIuAyQgegg2+gvaKVAAAAAAD9////AuhYAAAAAAAAIgAghgk3+CtagWiOzcAW2utE3OVCQBlAYOCk5OI93VU89HAgTgAAAAAAABYAFLvZSGHY986n2akfMD3TotdsVgr1AAAAAAABAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAEBKyy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxscBCNoEAEcwRAIgQLt8qnOWJraCp4jZbPvzecxsGtTEgQZtMcobPVAh3RgCIF4ZBYGdS5WyeoZyO+GzeEEwEtJJHomunhCC18Ktc8UZAUcwRAIgKtfA/fAvKQpUjmY2PoTaUqM94e6fgDimLVtUgCQ0CZICIBBOABEq2yh0uVp4nFMxo0uTi9ohe2YHohF5ueO672E3AUdSIQMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKyED2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3hSrgABAUdSIQJt/GdDoj46t8nOb4qSAk320vPRzkf1OFGBLtqpIxFpliEC65n0frLTr9SgwSVsKvi2SN06+XTZW3YHnmNrh/HAKTJSriICAm38Z0OiPjq3yc5vipICTfbS89HOR/U4UYEu2qkjEWmWGDARwVpUAACAAQAAgAAAAIABAAAAAQAAACICAuuZ9H6y06/UoMElbCr4tkjdOvl02Vt2B55ja4fxwCkyGL0o621UAACAAQAAgAAAAIABAAAAAQAAAAAiAgMke+462843D6lFgclk4xVkb2fFo1t9eVV6t/nnUa8S3Bi9KOttVAAAgAEAAIAAAACAAAAAAAsAAAAA","complete": true}
combinepsbt 명령어 없이 finalizepsbt 명령어만 사용하면 된다.
❯ bc1 finalizepsbt cHNidP8BAH0CAAAAAXWs0ZPv+uu9YJ0oGlG04tlbVV2aIuAyQgegg2+gvaKVAAAAAAD9////AuhYAAAAAAAAIgAghgk3+CtagWiOzcAW2utE3OVCQBlAYOCk5OI93VU89HAgTgAAAAAAABYAFLvZSGHY986n2akfMD3TotdsVgr1AAAAAAABAH0CAAAAAZ+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAQAAAAD9////Aiy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxsdQwwAAAAAAABYAFJyoBc+6mSp2EoJ0J1BZVaPNPDCBAAAAAAEBKyy1AAAAAAAAIgAghmGZcOCliyZaJUU4h2OaLI5Z0ZaGNQcHCXzC79ONxscBCNoEAEcwRAIgQLt8qnOWJraCp4jZbPvzecxsGtTEgQZtMcobPVAh3RgCIF4ZBYGdS5WyeoZyO+GzeEEwEtJJHomunhCC18Ktc8UZAUcwRAIgKtfA/fAvKQpUjmY2PoTaUqM94e6fgDimLVtUgCQ0CZICIBBOABEq2yh0uVp4nFMxo0uTi9ohe2YHohF5ueO672E3AUdSIQMXjpf/Bs393zbLgSBZpbroHV8nymZHPBQPAGUwuunBKyED2epRclqIzYyZ+kK+omG+FVJLZ2/THs/uAybZCe/Qi3hSrgABAUdSIQJt/GdDoj46t8nOb4qSAk320vPRzkf1OFGBLtqpIxFpliEC65n0frLTr9SgwSVsKvi2SN06+XTZW3YHnmNrh/HAKTJSriICAm38Z0OiPjq3yc5vipICTfbS89HOR/U4UYEu2qkjEWmWGDARwVpUAACAAQAAgAAAAIABAAAAAQAAACICAuuZ9H6y06/UoMElbCr4tkjdOvl02Vt2B55ja4fxwCkyGL0o621UAACAAQAAgAAAAIABAAAAAQAAAAAiAgMke+462843D6lFgclk4xVkb2fFo1t9eVV6t/nnUa8S3Bi9KOttVAAAgAEAAIAAAACAAAAAAAsAAAAA{"hex": "0200000000010175acd193effaebbd609d281a51b4e2d95b555d9a22e0324207a0836fa0bda2950000000000fdffffff02e858000000000000220020860937f82b5a81688ecdc016daeb44dce54240194060e0a4e4e23ddd553cf470204e000000000000160014bbd94861d8f7cea7d9a91f303dd3a2d76c560af50400473044022040bb7caa739626b682a788d96cfbf379cc6c1ad4c481066d31ca1b3d5021dd1802205e1905819d4b95b27a86723be1b378413012d2491e89ae9e1082d7c2ad73c5190147304402202ad7c0fdf02f290a548e66363e84da52a33de1ee9f8038a62d5b5480243409920220104e00112adb2874b95a789c5331a34b938bda217b6607a21179b9e3baef61370147522103178e97ff06cdfddf36cb812059a5bae81d5f27ca66473c140f006530bae9c12b2103d9ea51725a88cd8c99fa42bea261be15524b676fd31ecfee0326d909efd08b7852ae00000000","complete": true}
complete 속성을 통해 트랜잭션이 잘 생성된 것을 확인할 수 있다.
두 사람이 0.1 BTC 씩 Multisig 지갑으로 돈을 모으기로 했다고 가정해보자. PSBT 이전의 Multisig에서는 각자 Multisig 주소로 자금을 보낸다. 이때 첫 번째로 보내는 사람은 두 번째 사람도 같은 금액을 보낼거라는 믿음이 필요하다.
PSBT Multisig에서는 서로에 대한 신뢰 없이도 자금을 모을 수 있다.
서로의 UTXO 정보를 이용해서 트랜잭션을 생성할 예정이다. UTXO 정보를 확인해보자.
❯ bc1 listunspent[{"txid": "0d25fb831a36388b211bc6bd18f573c30ac68ac0868e59ac7e078bfe5bcedb68","vout": 1,"address": "bcrt1qg9zy3044w0q8g7vpzqqjxkuy5t50vpcvpx6mtd","label": "","scriptPubKey": "0014414448beb573c07479811001235b84a2e8f6070c","amount": 0.10000000,"confirmations": 1,"spendable": true,"solvable": true,"desc": "wpkh([bd28eb6d/84'/1'/0'/0/14]03e6ca36c93d7d01706280f2c9781cedb081c3ee67ee1fecc70a8ba18b64c511e4)#s0yh4msw","parent_descs": ["wpkh(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/84'/1'/0'/0/*)#20jjtpgm"],"safe": true},...]❯ bc2 listunspent[{"txid": "294f31257edf6ec0fb1c72277908c73dcbca4904bc8ea7243d37a56c7f4e24e9","vout": 1,"address": "bcrt1qax748gt2mwn5xjl6gtexefypkytqzylmswxatm","label": "","scriptPubKey": "0014e9bd53a16adba7434bfa42f26ca481b1160113fb","amount": 0.10000000,"confirmations": 152,"spendable": true,"solvable": true,"desc": "wpkh([3011c15a/84'/1'/0'/0/5]036ae034f42f26aa037eeb7ff18cf1868b6c3743e2ebf0a9ac8d8ecf6aadd8c1cb)#t5f79u0u","parent_descs": ["wpkh(tpubD6NzVbkrYhZ4XmJwzmK3QLJhka3XskhsGUJv824t48PLPzeooGRMhFG6d8VPtKgcLb5SMhvmBMxFWCSWmSdRTGZzFgCq6c98iSX2qC4eqZp/84'/1'/0'/0/*)#565kq45d"],"safe": true},...]
비트코인을 받을 주소를 생성하자.
❯ bcm1 getnewaddressbcrt1qk7qxac67yqe3y6yj4hzpymycv7l98q7llanuxsg5g853v6wsvv7spyutet
createpsbt 명령어를 이용해서 PSBT를 생성하자. 직접 UTXO 정보를 입력에 사용한다.
❯ bc1 -named createpsbt inputs='''[ { "txid": "0d25fb831a36388b211bc6bd18f573c30ac68ac0868e59ac7e078bfe5bcedb68", "vout": 1 }, { "txid": "294f31257edf6ec0fb1c72277908c73dcbca4904bc8ea7243d37a56c7f4e24e9", "vout": 1 } ]''' outputs='''{ "bcrt1qk7qxac67yqe3y6yj4hzpymycv7l98q7llanuxsg5g853v6wsvv7spyutet": 0.19999 }'''cHNidP8BAIcCAAAAAmjbzlv+iwd+rFmOhsCKxgrDc/UYvcYbIYs4NhqD+yUNAQAAAAD9////6SROf2ylNz0kp468BEnKyz3HCHknchz7wG7ffiUxTykBAAAAAP3///8BGCkxAQAAAAAiACC3gG7jXiAzEmiSrcQSbJhnvlOD3/9nw0EUQekWadBjPQAAAAAAAAAA
0.00001 BTC를 수수료로 사용하고 남은 0.19999 BTC를 Multisig 주소로 할당했다.
각자 서명을 진행한다.
❯ bc1 walletprocesspsbt cHNidP8BAIcCAAAAAmjbzlv+iwd+rFmOhsCKxgrDc/UYvcYbIYs4NhqD+yUNAQAAAAD9////6SROf2ylNz0kp468BEnKyz3HCHknchz7wG7ffiUxTykBAAAAAP3///8BGCkxAQAAAAAiACC3gG7jXiAzEmiSrcQSbJhnvlOD3/9nw0EUQekWadBjPQAAAAAAAAAA{"psbt": "cHNidP8BAIcCAAAAAmjbzlv+iwd+rFmOhsCKxgrDc/UYvcYbIYs4NhqD+yUNAQAAAAD9////6SROf2ylNz0kp468BEnKyz3HCHknchz7wG7ffiUxTykBAAAAAP3///8BGCkxAQAAAAAiACC3gG7jXiAzEmiSrcQSbJhnvlOD3/9nw0EUQekWadBjPQAAAAAAAQBxAgAAAAH4fnuUmGz5jQWGusiwGT5tN3cZg4jMQMY92HSpnaUKiwAAAAAA/f///wJ4ZHcjAQAAABYAFD+uJCCnZUaAbJAqz9MhnPn+IlNjgJaYAAAAAAAWABRBREi+tXPAdHmBEAEjW4Si6PYHDAEBAAABAR+AlpgAAAAAABYAFEFESL61c8B0eYEQASNbhKLo9gcMAQhrAkcwRAIgVyZ+OKsM7vB1dwPEXT0aHDfyMvFn7IQTiPZF19mgmbECIA32MSR7CIVGvZ+sShzP8hdb7EdwR2KqJ5r94V4Gb1tsASED5so2yT19AXBigPLJeBztsIHD7mfuH+zHCouhi2TFEeQAAQBxAgAAAAEjRPoy026hUH8v7VYZUnsuXq4kfqHpMLjvM6Y6hkaqlwAAAAAA/f///wJ8UG0pAQAAABYAFK0XOsJB/WbdeJVCSx9kZ5ABGnJNgJaYAAAAAAAWABTpvVOhatunQ0v6QvJspIGxFgET+2gAAAABAR+AlpgAAAAAABYAFOm9U6Fq26dDS/pC8mykgbEWARP7AAA=","complete": false}❯ bc2 walletprocesspsbt cHNidP8BAIcCAAAAAmjbzlv+iwd+rFmOhsCKxgrDc/UYvcYbIYs4NhqD+yUNAQAAAAD9////6SROf2ylNz0kp468BEnKyz3HCHknchz7wG7ffiUxTykBAAAAAP3///8BGCkxAQAAAAAiACC3gG7jXiAzEmiSrcQSbJhnvlOD3/9nw0EUQekWadBjPQAAAAAAAQBxAgAAAAH4fnuUmGz5jQWGusiwGT5tN3cZg4jMQMY92HSpnaUKiwAAAAAA/f///wJ4ZHcjAQAAABYAFD+uJCCnZUaAbJAqz9MhnPn+IlNjgJaYAAAAAAAWABRBREi+tXPAdHmBEAEjW4Si6PYHDAEBAAABAR+AlpgAAAAAABYAFEFESL61c8B0eYEQASNbhKLo9gcMAQhrAkcwRAIgVyZ+OKsM7vB1dwPEXT0aHDfyMvFn7IQTiPZF19mgmbECIA32MSR7CIVGvZ+sShzP8hdb7EdwR2KqJ5r94V4Gb1tsASED5so2yT19AXBigPLJeBztsIHD7mfuH+zHCouhi2TFEeQAAQBxAgAAAAEjRPoy026hUH8v7VYZUnsuXq4kfqHpMLjvM6Y6hkaqlwAAAAAA/f///wJ8UG0pAQAAABYAFK0XOsJB/WbdeJVCSx9kZ5ABGnJNgJaYAAAAAAAWABTpvVOhatunQ0v6QvJspIGxFgET+2gAAAABAR+AlpgAAAAAABYAFOm9U6Fq26dDS/pC8mykgbEWARP7AAA={"psbt": "cHNidP8BAIcCAAAAAmjbzlv+iwd+rFmOhsCKxgrDc/UYvcYbIYs4NhqD+yUNAQAAAAD9////6SROf2ylNz0kp468BEnKyz3HCHknchz7wG7ffiUxTykBAAAAAP3///8BGCkxAQAAAAAiACC3gG7jXiAzEmiSrcQSbJhnvlOD3/9nw0EUQekWadBjPQAAAAAAAQBxAgAAAAH4fnuUmGz5jQWGusiwGT5tN3cZg4jMQMY92HSpnaUKiwAAAAAA/f///wJ4ZHcjAQAAABYAFD+uJCCnZUaAbJAqz9MhnPn+IlNjgJaYAAAAAAAWABRBREi+tXPAdHmBEAEjW4Si6PYHDAEBAAABAR+AlpgAAAAAABYAFEFESL61c8B0eYEQASNbhKLo9gcMAQhrAkcwRAIgVyZ+OKsM7vB1dwPEXT0aHDfyMvFn7IQTiPZF19mgmbECIA32MSR7CIVGvZ+sShzP8hdb7EdwR2KqJ5r94V4Gb1tsASED5so2yT19AXBigPLJeBztsIHD7mfuH+zHCouhi2TFEeQAAQBxAgAAAAEjRPoy026hUH8v7VYZUnsuXq4kfqHpMLjvM6Y6hkaqlwAAAAAA/f///wJ8UG0pAQAAABYAFK0XOsJB/WbdeJVCSx9kZ5ABGnJNgJaYAAAAAAAWABTpvVOhatunQ0v6QvJspIGxFgET+2gAAAABAR+AlpgAAAAAABYAFOm9U6Fq26dDS/pC8mykgbEWARP7AQhrAkcwRAIgZd3VVouISpficCFEekDggu7zZrtmsHuKhg00Zc9mOGQCIBbhaxayqnx7YGGEMDgprp4U1maFo4qCmdnO+XVxBBtdASEDauA09C8mqgN+63/xjPGGi2w3Q+Lr8KmsjY7Paq3YwcsAAA==","complete": true}
순차적으로 서명했으므로 combinepsbt 명령어는 필요 없다.
finalizepsbt 명령어로 최종 트랜잭션을 생성하고 블록에 포함시키자.
❯ bc1 finalizepsbt cHNidP8BAIcCAAAAAmjbzlv+iwd+rFmOhsCKxgrDc/UYvcYbIYs4NhqD+yUNAQAAAAD9////6SROf2ylNz0kp468BEnKyz3HCHknchz7wG7ffiUxTykBAAAAAP3///8BGCkxAQAAAAAiACC3gG7jXiAzEmiSrcQSbJhnvlOD3/9nw0EUQekWadBjPQAAAAAAAQBxAgAAAAH4fnuUmGz5jQWGusiwGT5tN3cZg4jMQMY92HSpnaUKiwAAAAAA/f///wJ4ZHcjAQAAABYAFD+uJCCnZUaAbJAqz9MhnPn+IlNjgJaYAAAAAAAWABRBREi+tXPAdHmBEAEjW4Si6PYHDAEBAAABAR+AlpgAAAAAABYAFEFESL61c8B0eYEQASNbhKLo9gcMAQhrAkcwRAIgVyZ+OKsM7vB1dwPEXT0aHDfyMvFn7IQTiPZF19mgmbECIA32MSR7CIVGvZ+sShzP8hdb7EdwR2KqJ5r94V4Gb1tsASED5so2yT19AXBigPLJeBztsIHD7mfuH+zHCouhi2TFEeQAAQBxAgAAAAEjRPoy026hUH8v7VYZUnsuXq4kfqHpMLjvM6Y6hkaqlwAAAAAA/f///wJ8UG0pAQAAABYAFK0XOsJB/WbdeJVCSx9kZ5ABGnJNgJaYAAAAAAAWABTpvVOhatunQ0v6QvJspIGxFgET+2gAAAABAR+AlpgAAAAAABYAFOm9U6Fq26dDS/pC8mykgbEWARP7AQhrAkcwRAIgZd3VVouISpficCFEekDggu7zZrtmsHuKhg00Zc9mOGQCIBbhaxayqnx7YGGEMDgprp4U1maFo4qCmdnO+XVxBBtdASEDauA09C8mqgN+63/xjPGGi2w3Q+Lr8KmsjY7Paq3YwcsAAA=={"hex": "0200000000010268dbce5bfe8b077eac598e86c08ac60ac373f518bdc61b218b38361a83fb250d0100000000fdffffffe9244e7f6ca5373d24a78ebc0449cacb3dc7087927721cfbc06edf7e25314f290100000000fdffffff011829310100000000220020b7806ee35e2033126892adc4126c9867be5383dfff67c3411441e91669d0633d02473044022057267e38ab0ceef0757703c45d3d1a1c37f232f167ec841388f645d7d9a099b102200df631247b088546bd9fac4a1ccff2175bec47704762aa279afde15e066f5b6c012103e6ca36c93d7d01706280f2c9781cedb081c3ee67ee1fecc70a8ba18b64c511e402473044022065ddd5568b884a97e27021447a40e082eef366bb66b07b8a860d3465cf663864022016e16b16b2aa7c7b606184303829ae9e14d66685a38a8299d9cef97571041b5d0121036ae034f42f26aa037eeb7ff18cf1868b6c3743e2ebf0a9ac8d8ecf6aadd8c1cb00000000","complete": true}❯ bc1 sendrawtransaction 0200000000010268dbce5bfe8b077eac598e86c08ac60ac373f518bdc61b218b38361a83fb250d0100000000fdffffffe9244e7f6ca5373d24a78ebc0449cacb3dc7087927721cfbc06edf7e25314f290100000000fdffffff011829310100000000220020b7806ee35e2033126892adc4126c9867be5383dfff67c3411441e91669d0633d02473044022057267e38ab0ceef0757703c45d3d1a1c37f232f167ec841388f645d7d9a099b102200df631247b088546bd9fac4a1ccff2175bec47704762aa279afde15e066f5b6c012103e6ca36c93d7d01706280f2c9781cedb081c3ee67ee1fecc70a8ba18b64c511e402473044022065ddd5568b884a97e27021447a40e082eef366bb66b07b8a860d3465cf663864022016e16b16b2aa7c7b606184303829ae9e14d66685a38a8299d9cef97571041b5d0121036ae034f42f26aa037eeb7ff18cf1868b6c3743e2ebf0a9ac8d8ecf6aadd8c1cb000000000e0acb2b7f8f171abb2c332ce4118aff2b6ec69118b9afc85008989a67d104e4❯ bc2 -generate 1{"address": "bcrt1q2nfd4ntj95hz4mysv4z5u43h2d5wqyzj3aggwf","blocks": ["7086fd558b1fac1822e8f9cb5b5ae9de03609134951c64d2ad48630a5b8d5ab7"]}
UTXO를 확인해서 비트코인을 잘 받았는지 확인해보자.
❯ bcm1 listunspent[{"txid": "0e0acb2b7f8f171abb2c332ce4118aff2b6ec69118b9afc85008989a67d104e4","vout": 0,"address": "bcrt1qk7qxac67yqe3y6yj4hzpymycv7l98q7llanuxsg5g853v6wsvv7spyutet","label": "","witnessScript": "5221032d5ccddc7567c917dfb0aff9dd1a68d035ff37ff4685f13030c4c1a62d4f399821033c5c91a52f8fb0db4330d4875ffb4c24ecec3e823db87f8f845b8bc35acff9c552ae","scriptPubKey": "0020b7806ee35e2033126892adc4126c9867be5383dfff67c3411441e91669d0633d","amount": 0.19999000,"confirmations": 1,"spendable": true,"solvable": true,"desc": "wsh(multi(2,[3011c15a/84'/1'/0'/0/1]032d5ccddc7567c917dfb0aff9dd1a68d035ff37ff4685f13030c4c1a62d4f3998,[bd28eb6d/84'/1'/0'/0/1]033c5c91a52f8fb0db4330d4875ffb4c24ecec3e823db87f8f845b8bc35acff9c5))#cehxs0de","parent_descs": ["wsh(sortedmulti(2,[bd28eb6d/84'/1'/0']tpubDD3E21w6xwRSU4AbQ9vdJddZ3YzVsMP5CEyk4pX1wi7NAV3QEdsQ4Fy3GELEzFeX7wSCAkJAHTP7xf2uyR3mpaCy72fWHxnfhMDvmm5Jnx4/0/*,[3011c15a/84'/1'/0']tpubDDH5J2iKBmpgctNWw46WFCFPb4GPBoSBLFjxWZsXCGJH9pSaCStrQbehSBC5rXC46eBp4Jc7Eyh6D5wR2C8egAyJpkWGa1pMhu9mGbhbHCz/0/*))#7fdwfx0a"],"safe": true},...]
무신뢰(trustless) 기반으로 자금을 모으는데 성공했다.
CoinJoin은 비트코인 트랜잭션의 프라이버시와 익명성을 향상시키기 위한 방법 중 하나다. 기본 아이디어는 여러 사용자들이 자신들의 트랜잭션을 결합하여 하나의 큰 트랜잭션을 만드는 것이다. 이 과정에서 각 사용자의 입력과 출력이 혼합되어 개별 트랜잭션을 추적하기가 더 어려워진다.
CoinJoin은 프라이버시를 크게 향상시킬 수 있지만 완벽한 익명성을 보장하지는 않는다. 고급 분석 방법을 사용하면 여전히 트랜잭션의 패턴을 추적할 수 있다.
CoinJoin은 Multisig와는 관련이 없지만 여러 사용자가 협력해서 하나의 트랜잭션을 만든다는 공통점이 있다. CoinJoin 트랜잭션은 다음의 과정을 거친다.
두 노드가 CoinJoin 하는 과정을 실습해보자.
먼저 CoinJoin의 입력에 사용할 UTXO를 확인한다.
❯ bc1 listunspent[{"txid": "e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f","vout": 0,"address": "bcrt1pt5kwe03cctfv60prukfz7gfh5sjrxtv6mku744ewsaqnrdsgpc5sttkekl","scriptPubKey": "51205d2cecbe38c2d2cd3c23e5922f2137a424332d9addb9ead72e874131b6080e29","amount": 0.08686380,"confirmations": 8,"spendable": true,"solvable": true,"desc": "tr([bd28eb6d/86'/1'/0'/1/2]bfa70da9394fd1850912bcc56c827d167906dfef6a05dfe0fff910da9080af19)#e76cp23c","parent_descs": ["tr(tpubD6NzVbkrYhZ4Xq9mJeQj9Y7vgT2nmsY8HnsaGR28ffjPFpopZ3wnntnMNhQ5LvDWjFqduoWqrMs8VuMJTdTV6vHGS7jVzMYo4JwZfGuz14K/86'/1'/0'/1/*)#gn9ckuue"],"safe": true},...]❯ bc2 listunspent[{"txid": "238dac6783f27303d0a3960bf44fdfbbe332b0fb13ed733525e829123b57eb90","vout": 0,"address": "bcrt1qmksnw7cvugkmz68j9my4485qjcme8z3344rggq","label": "","scriptPubKey": "0014dda1377b0ce22db168f22ec95a9e809637938a31","amount": 0.10000000,"confirmations": 155,"spendable": true,"solvable": true,"desc": "wpkh([3011c15a/84'/1'/0'/0/2]02b0f5540007840ac0265bc413d453587a93c73bc25094aff01df711030cbc6a1c)#dk50vrf0","parent_descs": ["wpkh(tpubD6NzVbkrYhZ4XmJwzmK3QLJhka3XskhsGUJv824t48PLPzeooGRMhFG6d8VPtKgcLb5SMhvmBMxFWCSWmSdRTGZzFgCq6c98iSX2qC4eqZp/84'/1'/0'/0/*)#565kq45d"],"safe": true},...]
이번에는 CoinJoin의 출력에 사용할 주소를 생성한다.
❯ bc1 getnewaddressbcrt1q44ddyvn9vk8s2pess9rxhjg342jauutju05rsv❯ bc2 getnewaddressbcrt1qw48fqx0l7fde7khskllcscu0xjh3lenlwzavp4
각자 입력한 금액에서 수수료를 제외한 금액을 위 주소로 돌려받는다. 각자 5,000 sats를 수수료로 지불한다고 가정하면 아래와 같다.
0.08686380
, 출력 0.08681380
0.10000000
, 출력 0.09995000
createpsbt 명령어를 이용해서 PSBT를 만든다.
❯ bc1 -named createpsbt inputs='''[ { "txid": "e554cd0954107bb496af8b33fb35822990c408edd90cb4a56449d0e2db018b9f", "vout": 0 }, { "txid": "238dac6783f27303d0a3960bf44fdfbbe332b0fb13ed733525e829123b57eb90", "vout": 0 } ]''' outputs='''{ "bcrt1q44ddyvn9vk8s2pess9rxhjg342jauutju05rsv": 0.08681380, "bcrt1qw48fqx0l7fde7khskllcscu0xjh3lenlwzavp4": 0.09995000 }'''cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAAAAAA=
생성된 PSBT를 각자 서명한다.
❯ bc1 walletprocesspsbt cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAAAAAA={"psbt": "cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAEAiQIAAAABvVwFGlvWzb2giseghNNP8uAGoxgRNRrY0iSwzw7R+m8BAAAAAP3///8CLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKaCGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkb7AAAAAQErLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKQEIQgFAMHVTSCj0AB66PphOq6V8aeud+Tf/Z8zCju45C6BMIq6DxivFtdpgMefPE71aCh9UF24wNRSqbyWMOcUm91CF4wABAHECAAAAAZtY2mkznfKi09M+Xh/+l4zqKVQXzsVOhNw+FtfJT2muAAAAAAD9////AoCWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijH4VHImAQAAABYAFHaJPHnmH79VeaMR3OLvjb0xrpZ9AAAAAAEBH4CWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijEAIgICdlIGccvP0sgPGopchKuRfkHznAlWnrxBSqxr5mYUDVYYvSjrbVQAAIABAACAAAAAgAAAAAAPAAAAAAA=","complete": false}❯ bc2 walletprocesspsbt cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAAAAAA={"psbt": "cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAABAHECAAAAAZtY2mkznfKi09M+Xh/+l4zqKVQXzsVOhNw+FtfJT2muAAAAAAD9////AoCWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijH4VHImAQAAABYAFHaJPHnmH79VeaMR3OLvjb0xrpZ9AAAAAAEBH4CWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijEBCGsCRzBEAiA2lX3Zes+Dbsdu3zCXnfUr+Jf8PaWBLe0nkCKDnwyPiQIgSOX3s2hecc0wLEARHFp55TJQJOJFNCNXGrjfu0sAM5kBIQKw9VQAB4QKwCZbxBPUU1h6k8c7wlCUr/Ad9xEDDLxqHAAAIgICYUWXTtt26gmNDBVrYoWvIKgrZkGjTyO8BxyIurRsc0EYMBHBWlQAAIABAACAAAAAgAAAAAApAAAAAA==","complete": false}
서명된 PSBT를 각각 쉘 변수에 저장한다.
psbt1=cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAEAiQIAAAABvVwFGlvWzb2giseghNNP8uAGoxgRNRrY0iSwzw7R+m8BAAAAAP3///8CLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKaCGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkb7AAAAAQErLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKQEIQgFAMHVTSCj0AB66PphOq6V8aeud+Tf/Z8zCju45C6BMIq6DxivFtdpgMefPE71aCh9UF24wNRSqbyWMOcUm91CF4wABAHECAAAAAZtY2mkznfKi09M+Xh/+l4zqKVQXzsVOhNw+FtfJT2muAAAAAAD9////AoCWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijH4VHImAQAAABYAFHaJPHnmH79VeaMR3OLvjb0xrpZ9AAAAAAEBH4CWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijEAIgICdlIGccvP0sgPGopchKuRfkHznAlWnrxBSqxr5mYUDVYYvSjrbVQAAIABAACAAAAAgAAAAAAPAAAAAAA=psbt2=cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAABAHECAAAAAZtY2mkznfKi09M+Xh/+l4zqKVQXzsVOhNw+FtfJT2muAAAAAAD9////AoCWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijH4VHImAQAAABYAFHaJPHnmH79VeaMR3OLvjb0xrpZ9AAAAAAEBH4CWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijEBCGsCRzBEAiA2lX3Zes+Dbsdu3zCXnfUr+Jf8PaWBLe0nkCKDnwyPiQIgSOX3s2hecc0wLEARHFp55TJQJOJFNCNXGrjfu0sAM5kBIQKw9VQAB4QKwCZbxBPUU1h6k8c7wlCUr/Ad9xEDDLxqHAAAIgICYUWXTtt26gmNDBVrYoWvIKgrZkGjTyO8BxyIurRsc0EYMBHBWlQAAIABAACAAAAAgAAAAAApAAAAAA==
combinepsbt 명령어를 이용해서 하나의 PSBT로 만든다.
❯ bc1 combinepsbt '''["'$psbt1'","'$psbt2'"]'''cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAEAiQIAAAABvVwFGlvWzb2giseghNNP8uAGoxgRNRrY0iSwzw7R+m8BAAAAAP3///8CLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKaCGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkb7AAAAAQErLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKQEIQgFAMHVTSCj0AB66PphOq6V8aeud+Tf/Z8zCju45C6BMIq6DxivFtdpgMefPE71aCh9UF24wNRSqbyWMOcUm91CF4wABAHECAAAAAZtY2mkznfKi09M+Xh/+l4zqKVQXzsVOhNw+FtfJT2muAAAAAAD9////AoCWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijH4VHImAQAAABYAFHaJPHnmH79VeaMR3OLvjb0xrpZ9AAAAAAEBH4CWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijEBCGsCRzBEAiA2lX3Zes+Dbsdu3zCXnfUr+Jf8PaWBLe0nkCKDnwyPiQIgSOX3s2hecc0wLEARHFp55TJQJOJFNCNXGrjfu0sAM5kBIQKw9VQAB4QKwCZbxBPUU1h6k8c7wlCUr/Ad9xEDDLxqHAAiAgJ2UgZxy8/SyA8ailyEq5F+QfOcCVaevEFKrGvmZhQNVhi9KOttVAAAgAEAAIAAAACAAAAAAA8AAAAAIgICYUWXTtt26gmNDBVrYoWvIKgrZkGjTyO8BxyIurRsc0EYMBHBWlQAAIABAACAAAAAgAAAAAApAAAAAA==
finalizepsbt 명령어를 이용해서 raw transaction으로 변환한다.
❯ bc1 finalizepsbt cHNidP8BAJoCAAAAAp+LAdvi0ElkpbQM2e0IxJApgjX7M4uvlrR7EFQJzVTlAAAAAAD9////kOtXOxIp6CU1c+0T+7Ay47vfT/QLlqPQA3Pyg2esjSMAAAAAAP3///8CpHeEAAAAAAAWABStWtIyZWWPBQcwgUZryRGqpd5xcviCmAAAAAAAFgAUdU6QGf/yW59a8Lf/iGOPNK8f5n8AAAAAAAEAiQIAAAABvVwFGlvWzb2giseghNNP8uAGoxgRNRrY0iSwzw7R+m8BAAAAAP3///8CLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKaCGAQAAAAAAIgAgVaonhDXR+EYynb70x8BPh46cBjdcvs9q6pM3sCcCzkb7AAAAAQErLIuEAAAAAAAiUSBdLOy+OMLSzTwj5ZIvITekJDMtmt256tcuh0ExtggOKQEIQgFAMHVTSCj0AB66PphOq6V8aeud+Tf/Z8zCju45C6BMIq6DxivFtdpgMefPE71aCh9UF24wNRSqbyWMOcUm91CF4wABAHECAAAAAZtY2mkznfKi09M+Xh/+l4zqKVQXzsVOhNw+FtfJT2muAAAAAAD9////AoCWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijH4VHImAQAAABYAFHaJPHnmH79VeaMR3OLvjb0xrpZ9AAAAAAEBH4CWmAAAAAAAFgAU3aE3ewziLbFo8i7JWp6AljeTijEBCGsCRzBEAiA2lX3Zes+Dbsdu3zCXnfUr+Jf8PaWBLe0nkCKDnwyPiQIgSOX3s2hecc0wLEARHFp55TJQJOJFNCNXGrjfu0sAM5kBIQKw9VQAB4QKwCZbxBPUU1h6k8c7wlCUr/Ad9xEDDLxqHAAiAgJ2UgZxy8/SyA8ailyEq5F+QfOcCVaevEFKrGvmZhQNVhi9KOttVAAAgAEAAIAAAACAAAAAAA8AAAAAIgICYUWXTtt26gmNDBVrYoWvIKgrZkGjTyO8BxyIurRsc0EYMBHBWlQAAIABAACAAAAAgAAAAAApAAAAAA=={"hex": "020000000001029f8b01dbe2d04964a5b40cd9ed08c490298235fb338baf96b47b105409cd54e50000000000fdffffff90eb573b1229e8253573ed13fbb032e3bbdf4ff40b96a3d00373f28367ac8d230000000000fdffffff02a477840000000000160014ad5ad23265658f05073081466bc911aaa5de7172f882980000000000160014754e9019fff25b9f5af0b7ff88638f34af1fe67f01403075534828f4001eba3e984eaba57c69eb9df937ff67ccc28eee390ba04c22ae83c62bc5b5da6031e7cf13bd5a0a1f54176e303514aa6f258c39c526f75085e302473044022036957dd97acf836ec76edf30979df52bf897fc3da5812ded279022839f0c8f89022048e5f7b3685e71cd302c40111c5a79e5325024e2453423571ab8dfbb4b003399012102b0f5540007840ac0265bc413d453587a93c73bc25094aff01df711030cbc6a1c00000000","complete": true}
sendrawtransaction 명령어를 이용해서 raw transaction을 전송한다.
❯ bc1 sendrawtransaction 020000000001029f8b01dbe2d04964a5b40cd9ed08c490298235fb338baf96b47b105409cd54e50000000000fdffffff90eb573b1229e8253573ed13fbb032e3bbdf4ff40b96a3d00373f28367ac8d230000000000fdffffff02a477840000000000160014ad5ad23265658f05073081466bc911aaa5de7172f882980000000000160014754e9019fff25b9f5af0b7ff88638f34af1fe67f01403075534828f4001eba3e984eaba57c69eb9df937ff67ccc28eee390ba04c22ae83c62bc5b5da6031e7cf13bd5a0a1f54176e303514aa6f258c39c526f75085e302473044022036957dd97acf836ec76edf30979df52bf897fc3da5812ded279022839f0c8f89022048e5f7b3685e71cd302c40111c5a79e5325024e2453423571ab8dfbb4b003399012102b0f5540007840ac0265bc413d453587a93c73bc25094aff01df711030cbc6a1c00000000ba63047bb301db37c74375917c82bbc8b8a26d712e06a33cf11f0b519d169f53
이처럼 Mutisig가 아니더라도 PSBT를 이용해서 여러 사용자가 협력해서 하나의 트랜잭션을 생성할 수 있다.
앞에서는 쉬운 설명을 위해 한 사람이 하나의 입력과 출력만 생성했지만 CoinJoin의 목적에 맞게 추적이 더 힘들게 하려면 한 사람의 입력과 출력을 다양하게 구성하는 게 좋다. 이때 출력에 들어가는 비트코인 수량은 단순 산술 연산에 불과하다.