블럭체인에 데이타 넣기
비트코인 블럭체인에 임의의 데이타를 넣을 수 있는데, 넣을 수 있는 데이타의 최대 크기는 80 바이트이다. Bitcoin은 기본적으로 Finance 관련 트랜잭션을 저장하는 것을 주요 기능으로 하고 있으므로, 초기에 임의의 데이타를 블럭체인에 허용하는 것에 반대하는 논쟁이 있었으며, 결국 중간 지점의 합의로서 80 바이트로 데이타 크기를 제한하기로 하였다.
OP_RETURN
비트코인 블럭체인에 임의의 데이타를 넣는 기능은 Bitcoin 스크립트 중 OP_RETURN 명령(opcode)을 사용한다. OP_RETURN (0x6a)은 원래 트랜잭션을 Invalid로 만드는 Opcode인데, 블럭체인에 임의의 데이타를 넣는 기능에 활용되고 있다.
Transaction Output에 "OP_RETURN + Data Size + Data"와 같은 포맷으로 데이타는 넣게되는데, 여기서 데이타는 80 바이트까지 허용된다. Transaction Output에 OP_RETURN 을 넣는 트랜잭션은 TX1 이라 했을 때, TX1을 아무 문제없이 broadcasting 할 수 있다. 하지만, 어느 유저가 OP_RETURN 이 들어 있는 Transaction Output을 사용하는 트랜잭션 TX2를 만들어 broadcasting 하면, 이때 Unlocking Script + Locking Script 가 실행될 것이고, Locking Script 중 OP_RETURN 코드를 만나게 될 것이고, 곧바로 TX2가 Invalid Transaction이 될 것이다.
이러한 이유에서 OP_RETURN가 있는 Transaction Output (txid + vout)은 Unspendable 즉 소비할 수 없는 UTXO가 된다. OP_RETURN가 있는 Transaction Output은 UTXO set 메모리에 들어가지 않게 되어 지속적으로 UTXO set 안에 머물러서 체크해야 하는 부담을 줄이게 된다.
데이타 넣기
bitcoin-cli 에서 OP_RETURN 을 사용하기 위해서는 outputs 파라미터에 "data": "hex-data-here" 을 넣으면 된다. 예를 들어, outputs 파라미터에 {"data":"436F6E747261637401020304050607080910", "tb1q0n38v7rfjcnnmfy585suvpzvhf0z7xrghqe5vv":0.00389} 와 같이 "data" 요소를 지정하고, change address 에 Fee를 제외한 금액을 넣으면 된다. UTXO에 0.0039 BTC가 있다고 가정하고, 여기서 0.00001 BTC를 Fee로 지불하고자 한다면, change address에 0.0039 - 0.00001 = 0.00389를 넣으면 된다.
// data가 있는 Raw Transaction 생성 $ bitcoin-cli createrawtransaction '[{"txid":"3ffc0c5381f967d2acd7e0e2b2740ef5e47d410f3ee91c124df8d5cc2b977803", "vout":0}]' '{"data":"436F6E747261637401020304050607080910", "tb1q0n38v7rfjcnnmfy585suvpzvhf0z7xrghqe5vv":0.00389}'
생성된 Raw Transaction을 Decode 해보면, vout의 첫번째 엔트리에 value = 0 인 OP_RETURN 데이타가 들어 있다. 데이타는 "OP_RETURN(0x6a) + 데이타크기(0x12) + HEX데이타(436f6e747261637401020304050607080910)" 형식으로 들어 있다. 여기서 데이타의 크기는 0x12 즉 18 바이트이다.
$ bitcoin-cli decoderawtransaction 02000000010378972bccd5f84d121ce93e0f417de4f50e ... 생략 ... "vout": [ { "value": 0.00000000, "n": 0, "scriptPubKey": { "asm": "OP_RETURN 436f6e747261637401020304050607080910", "hex": "6a12436f6e747261637401020304050607080910", <=== "type": "nulldata" } }, { "value": 0.00389000, "n": 1, "scriptPubKey": { "asm": "0 7ce276786996273da4943d21c6044cba5e2f1868", "hex": "00147ce276786996273da4943d21c6044cba5e2f1868", "reqSigs": 1, "type": "witness_v0_keyhash", "addresses": [ "tb1q0n38v7rfjcnnmfy585suvpzvhf0z7xrghqe5vv" ] } } ]
생성된 Raw Transaction은 서명후에 전송하면 된다.
// Raw Transaction 서명 $ bitcoin-cli signrawtransactionwithwallet 02000000010378972bccd5f84d121ce93e0f417de4f50e... // Raw Transaction 전송 $ bitcoin-cli sendrawtransaction 020000000001010378972bccd5f84d121ce93e0f417de4f50e...