我们可以在比特币交易中附加上一个OP_RETURN输出,OP_RETURN可以填入任意字符,可以是誓言,可以是证据,也可以是情人节表白,一经写入,就会永久保存在区块链上,不可删除,不可篡改。
Bitcoin的OP_Return可以写入40个字节的内容,曾经放开到83个字节,后来为了防止开发者滥用这个功能,又改回40个字节的限制。不过,这40个字节也足够写入一个SHA256的存证信息,这种证据也被法院承认。
下面用C#编程在OP_RETURN里写入一段文字。教程主要参考了这篇文章:https://programmingblockchain.gitbook.io/programmingblockchain/bitcoin_transfer/spend_your_coin
从钱包里找到一笔未花费的COIN,用bitcoin core的listunspent命令可以很容易地找到,建立一笔交易,并添加输入项:
代码语言:javascript复制Transaction tx = Transaction.Create(Network.Main);
tx.Inputs.Add(new TxIn()
{
PrevOut = new OutPoint(new uint256("814f20c21478942fca71241dd58c696e30d83e5c827a3c521cf60810e9f82c98"), 1)
});
这笔输入项共有0.0843 BTC,计划转给programming blockchain的作者0.0004,找零0.08389,交易手续费为0.00001。
代码语言:javascript复制0.00040000 给作者, out 0
0.08389000 找零给自己, out 1
0.00000000 op_return, out 2
0.00001000 手续费,给矿工
==========
0.0843
这样总共三个输出,这里千万别忘了添加给自己的找零输出,否则学个技术花费有点大。
代码语言:javascript复制var programmingBlockchain = BitcoinAddress.Create("1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB", Network.Main);
tx.Outputs.Add(
new TxOut()
{
Value = Money.Satoshis(40000),
ScriptPubKey = programmingBlockchain.ScriptPubKey
});
tx.Outputs.Add(
new TxOut()
{
Value = Money.Coins(0.08389m),
ScriptPubKey = BitcoinAddress.Create("15NnixfXKraJycQ4HTDfJjvPefmvwkCE6R", Network.Main).ScriptPubKey
});
下面开始添加op_return输出项,NBitcoin的作者已经写好了一个TxNullDataTemplate类,可以非常方便地把message封装到op_return中。
代码语言:javascript复制var message = "Thanks from Shen Longbin 申龙斌";
var bytes = Encoding.UTF8.GetBytes(message);
tx.Outputs.Add(new TxOut()
{
Value = Money.Zero,
ScriptPubKey = TxNullDataTemplate.Instance.GenerateScriptPubKey(bytes)
});
给交易签名:
代码语言:javascript复制BitcoinSecret secret = new BitcoinSecret("L17n5******k4rE");
tx.Inputs[0].ScriptSig = secret.ScriptPubKey;
tx.Sign(secret.PrivateKey, assumeP2SH: false);
看一下交易的二进制输出:
代码语言:javascript复制version: 01 00 00 00
input count: 01
PrevOut TXID: 98 2c f8 ... 20 4f 81
PrevOut index: 01 00 00 00
script length: 6a (十进制:106)
ScriptSig: 47 30 44 02 20 ... 7e dc a8 fd 10
Sequence: ff ff ff ff
Output count: 3
Value 0 : 40 9c 00 00 00 00 00 00
Script Length: 19 (十进制:25)
ScriptPubKey: 76 a9 14 ... 15 92 88 ac
Value 1 : 88 01 80 00 00 00 00 00
Script Length: 19 (十进制:25)
ScriptPubKey: 76 a9 14 2f ... 41 75 88 ac
Value 2 : 00 00 00 00 00 00 00 00
Script Length: 24 (十进制:36)
ScriptPubKey: 6a 22 54 68 61 ... 96 8c
Lock Time: 00 00 00 00
我们的信息封装在最后的value 2里,op_return不发送BTC,所以value为0,
我写的信息"Thanks from Shen Longbin 申龙斌"转换为UTF8之后总共占34个字节,对应的内容为
54 68 61 6e 6b 73 20 66 72 6f 6d 20 53 68 65 6e 20 4c 6f 6e 67 62 69 6e 20 e7 94 b3 e9 be 99 e6 96 8c
前面的0x6a表示OP_RETURN的标识符,0x22表示34个字节的消息内容。
最后把交易广播出去:
代码语言:javascript复制QBitNinjaClient client = new QBitNinjaClient(Network.Main);
client.Broadcast(tx);
很快就可以在区块链浏览器查询到这条消息。
https://www.blockchain.com/zh/btc/tx/f5a527513d2a18d5f622cab26828343e95088052b3286aebc26e3c23ecb4d2a7
你敢把结婚誓言写在区块链上吗?