비트코인 블록체인에 낙서하기 (Writing messages on the Bitcoin blockchain using OP_RETURN)

SJ
14 min readApr 24, 2019

--

블록체인에 메시지를 왜 남기나?

잘 알려진 것처럼, 비트코인 블록체인에 기록된 장부는 위조불가능하고(immutable), 장부에 수정이 아닌 추가로 기록하는 것만 가능하기 때문에 한번 씌여지면 영원하고(permanent), 전 세계의 노드에 저장되기 때문에 아무도 지울 수 없어 검열저항성이 있는(censorship-resistant) 등의 특징을 가지고 있습니다.

그래서, 이런 특징들을 개인적으로 활용해보기 위해서 비트코인 블록체인에 임의의 메시지(또는 낙서)를 남겨보기로 했습니다. 정확히는, “홍승진 왔다감”이라는 메시지를 남겨보기로 했습니다. 남산 N타워에 연인들이 자신들만의 메시지를 남긴 사랑의 자물쇠를 걸어 오랫동안 보관하여 두는 것을 생각하시면 될 것 같네요.

출처: 서울경제 (2015. 12. 23.)

메시지를 어떻게 남기나? — OP_RETURN

비트코인에는 여러가지 스크립트(script; 일종의 함수)가 있는데, 그중 “OP_RETURN”이라는 스크립트로 비트코인 블록체인에 메시지를 남길 수 있습니다. OP_RETURN은 Bitcoin Core 0.9 버전부터 들어간 기능인데, 아무래도 비트코인 블록체인은 한 블록의 크기가 1MB로 매우 작게 제한되어 있기 때문에, OP_RETURN과 같이 지불과 관계 없는 임의의 데이터를 블록에 남기는 것은 커뮤니티 내에서 논란이 많습니다. bitcoin.org에서도 OP_RETURN을 소개하면서 블록체인에 임의의 데이터를 저장하는 것을 승인(endorsement)하는 것은 아니다라고 하고 있습니다. 그리고 OP_RETURN 한 번에 최대 80 bytes 밖에 못 쓰도록 되어 있습니다(한글 40자도 채 되지 않는 사이즈입니다).

어쨌든, 저는 낙서를 하고 싶은 것이 목적이므로 커뮤니티 논란은 그냥 무시하고 진행해 보기로 했습니다.

서비스들

비트코인 블록체인에 임의의 데이터를 기록하려는 시도는 아주 예전부터 있어왔는데, 제가 하려는 것처럼 직접 텍스트와 같은 데이터를 기록하기 보다는, 공증과 비슷하게 문서의 해시값을 계산하여 그 값만을 저장하려는 시도가 주류였습니다: Proof of Existence ( https://proofofexistence.com/), Stampery (https://stampery.com/), diploma.report (http://diploma.report/) 등이 이런 종류의 서비스입니다. 해시값 외에 텍스트 등 랜덤한 데이터를 저장할 수 있도록 하는 서비스는 Eternity Wall (https://eternitywall.it/), bitscribble (https://bitscribble.com/), 국내에는 최근에 생긴 것으로 보이는 ‘포에버잇’(https://www.theforever.it/) 등이 있는 것 같습니다. (*저는 이 서비스들과 관련이 없습니다).

그런데, 이들 서비스는 사용하면 서비스의 웹사이트에 제 낙서가 남아 다른 사람이 볼 수 있기 때문에, 저는 “홍승진 왔다감”이라는 낙서를 몰래 남기기 위해서 직접 기록해보기로 했습니다. 아래는 비개발자가 비트코인 블록체인에 직접 메시지를 남길 수 있는 방법을 상세하게 설명해 두었으니 궁금하신 분은 한 번 따라해 보셔도 좋겠습니다.

비트코인 블록체인에 직접 메시지를 남기는 방법

개발자라면 비트코인 블록체인에 직접 transaction을 날리는 방법은 많이 알고 있겠지만, 저처럼 개발자가 아닌 사람도 쉽게 메시지를 남길 수 있는 방법 중에 제가 찾은 방법은 Bitcoin Core 지갑을 설치하는 방법인 것 같습니다. (*개발자 아닌 사람이 이 방법보다 더 쉽게 메시지를 남길 수 있는 방법을 아시는 분은 알려주세요)

Bitcoin Core 지갑 설치하기

우선 bitcoin.org에 가서 Bitcoin Core 지갑을 설치합니다. 설치하면 2009년부터 지금까지의 블록을 전부 다운받게 되는데, 2019년 4월 기준으로 비트코인 블록체인의 크기는 대략 220 GB입니다. 저는 다 다운받는데 1주일 넘게 걸린 것 같습니다(설정에서 블록 데이터 축소(prune 하기)를 선택하면 하루이틀 만에도 다운 가능합니다). 다 다운 받으면 비트코인 블록체인과 동기화가 되고, transaction을 보낼 수 있습니다. 그리고 passphrase를 설정합니다(암호).

지갑주소 생성하고 비트코인 보내기

블록체인 동기화가 다 되면 프로그램에서 Receive — Request Payment를 눌러 새로운 지갑주소를 생성합니다. 그리고 그 지갑 주소로 거래소 등에 가지고 있는 비트코인을 일부 보냅니다. Miner fee를 지불할 정도의 소량의 비트코인만 있으면 됩니다(0.01 BTC이하도 상관 없습니다). 저는 아래와 같은 지갑주소를 생성하고 이 주소로 0.005 BTC를 보냈더니, 바로 들어옵니다.

생성된 지갑주소: 3GJgPyajALNM2XmBX5ULU3QujPKu66CGCZ

UTXO(Unspent Transaction Output) 확인 — “list unspent”

그 지갑주소의 UTXO(아직 쓰이지 않아서 쓸 수 있는 비트코인 뭉치들)을 확인합니다(listunspent). 프로그램에서 Help — Debug — Console을 열어 명령어 창에 아래와 같이 입력합니다. 0과 999999는 min/max 컨펌숫자를 의미하는데 그냥 그대로 쓰시면 됩니다.

listunspent 0 999999 '["3GJgPyajALNM2XmBX5ULU3QujPKu66CGCZ"]'

결과값이 이렇게 나옵니다. 잔고가 0.005 BTC인 걸 확인할 수 있습니다.

[
{
“txid”: “b10b7fe8624fa40ee99c515e1f906e51feb0ef951de555e60de080e52ffe9c04”,
“vout”: 1,
“address”: “3GJgPyajALNM2XmBX5ULU3QujPKu66CGCZ”,
“label”: “”,
“redeemScript”: “001488dab56c738417589a6240942f870bdcdf80e833”,
“scriptPubKey”: “a914a0506f6d1a1ea7d5d33f690bd47392c7553be48a87”,
“amount”: 0.00500000,
“confirmations”: 0,
“spendable”: true,
“solvable”: true,
“safe”: false
}
]

거래 생성하기 — “create raw transaction”

이제 쓰고 싶은 메시지가 기록된 거래를 생성합니다. 제가 쓰고 싶은 메시지는 “홍승진 왔다감”이므로 이 메시지기 담긴 거래를 생성해야 합니다. 그런데 그 전에 쓰고 싶은 메시지를 hex로 바꿔야 합니다. 이곳에 가서(https://www.online-toolz.com/tools/text-hex-convertor.php), “홍승진 왔다감”을 Hex로 바꾸니 이렇게 나옵니다: ed998dec8ab9eca78420ec9994eb8ba4eab090.

createrawtransaction: 그러면 다시 프로그램의 Console로 가서 아래와 같이 입력합니다. “txid”와 “vout”에는 아까 listunspent로 나왔던 결과값을 넣으면 되고, “data”에는 쓰고 싶은 메시지의 Hex값, 받을 지갑 주소(그냥 아까 생성한 지갑 주소를 쓰면 됩니다), 그리고 miner fee를 제외한 값을 씁니다. 예를 들어, 저는 0.0045를 썼기 때문에, 채굴자에게 0.0005 BTC (잔고인 0.005–0.0045)를 수수료로 지급하는 것입니다(저 정도 수수료는 꽤 짭짤하기 때문에 채굴자들이 빨리 기록해 줄 것 같습니다).

createrawtransaction '[{"txid":"b10b7fe8624fa40ee99c515e1f906e51feb0ef951de555e60de080e52ffe9c04","vout":1}]' '{"data":"ed998dec8ab9eca78420ec9994eb8ba4eab090","3GJgPyajALNM2XmBX5ULU3QujPKu66CGCZ":0.0045}'

그러면 아래와 같은 값이 나오네요.

0200000001049cfe2fe580e00de655e51d95efb0fe516e901f5e519ce90ea44f62e87f0bb10100000000ffffffff020000000000000000156a13ed998dec8ab9eca78420ec9994eb8ba4eab090d0dd06000000000017a914a0506f6d1a1ea7d5d33f690bd47392c7553be48a8700000000

서명하기 — “sign raw transaction with key”

자, 이제 위 거래에 서명을 해야 합니다. 그런데, 서명을 하려면 private key가 필요하겠죠. Console 창에서 아래와 같이 입력하면 private key가 메모리에 60초 동안 떠 있게 되고(아래의 passphrase는 프로그램 설치시 설정한 passphrase를 입력하면 됩니다, 예를 들면 walletpassphrase "abcdefg" 60).

walletpassphrase “passphrase” 60

그 다음 아래와 같이 입력하면 앞서 생성한 지갑주소의 private key를 알려줍니다.

dumpprivkey “3GJgPyajALNM2XmBX5ULU3QujPKu66CGCZ”

signrawtransactionwithkey: 이제 private key를 알았으니, 앞서 생성했던 거래를 그 private key로 서명합니다.

signrawtransactionwithkey "0200000001049cfe2fe580e00de655e51d95efb0fe516e901f5e519ce90ea44f62e87f0bb10100000000ffffffff020000000000000000156a13ed998dec8ab9eca78420ec9994eb8ba4eab090d0dd06000000000017a914a0506f6d1a1ea7d5d33f690bd47392c7553be48a8700000000" '["private key"]'

그러면 아래와 같은 값이 나오네요.

{
“hex”: “02000000000101049cfe2fe580e00de655e51d95efb0fe516e901f5e519ce90ea44f62e87f0bb1010000001716001488dab56c738417589a6240942f870bdcdf80e833ffffffff020000000000000000156a13ed998dec8ab9eca78420ec9994eb8ba4eab090d0dd06000000000017a914a0506f6d1a1ea7d5d33f690bd47392c7553be48a870247304402205201c7b9ad1b3d3a4a24fddb817264b9f4df41da139510596b04383d6094074c022015c975e4a32dc276f143e2d8854083e3da620bc7fe979d560cd6d0134e8f16fa012102f3176d27342208c92635127c26a852525fc4786bc2a5c4723d55f2a5817079d800000000”,
“complete”: true
}

거래 보내기 — “send raw transaction”

sendrawtransaction: 드디어 서명한 거래를 네트워크로 보낼 타이밍입니다. 아래와 같이 거래를 비트코인 네트워크로 날립니다:

sendrawtransaction 02000000000101049cfe2fe580e00de655e51d95efb0fe516e901f5e519ce90ea44f62e87f0bb1010000001716001488dab56c738417589a6240942f870bdcdf80e833ffffffff020000000000000000156a13ed998dec8ab9eca78420ec9994eb8ba4eab090d0dd06000000000017a914a0506f6d1a1ea7d5d33f690bd47392c7553be48a870247304402205201c7b9ad1b3d3a4a24fddb817264b9f4df41da139510596b04383d6094074c022015c975e4a32dc276f143e2d8854083e3da620bc7fe979d560cd6d0134e8f16fa012102f3176d27342208c92635127c26a852525fc4786bc2a5c4723d55f2a5817079d800000000

그러면 방금 보낸 거래의 해시값이 나옵니다.

925be1cd02417937d03d01bfc9f845078ea5894e45ba76802459dbe376b88177

잘 쓰여졌는지 확인

방금 보낸 거래가 네트워크에 잘 전파되고 있는지를 확인하기 위해, 자주 사용하는 블록 익스플로러에 들어가서 위 거래의 해시값을 검색해 봅니다. 잘 전파가 됐네요. 이제 컨펌만 기다리면 됩니다.

낙서 완료!

2019년 4월 24일 오후 1:10(KST)에 572957번째 블록에 잘 기록되었습니다(낙서 성공^^).

txid: 925be1cd02417937d03d01bfc9f845078ea5894e45ba76802459dbe376b88177

저처럼 직접 메시지를 남기고 싶으신 분을 위해 작성했습니다. 쓰여진 내용 중 혹시 잘못된 내용이 있으면 알려주세요. 업데이트 하겠습니다.

참고자료

이 글은 더비체인(THE BCHAIN)에도 기고되었습니다.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

SJ
SJ

No responses yet

Write a response