在币圈中, 使用自己的钱包给他人发币时, 就跟平常的微信, 支付宝扫码付款类似, 输入 BTC 地址和金额, 再输入支付密码, 不管对方是否在地球的另一端, 不需要任何银行的中介, 10 分钟到几小时之后, BTC 就可以到账了.
发币需要支付少量的交易手续费, 如果给许多人发币, 上述操作就比较吃亏了. 还好, 许多钱包软件都支持给多人同时转账的功能, 添加多个地址, 金额, 再输入支付口令, 稍微麻烦一些, 细心操作即可.
以 Bitcoin Core 为例, 点击底部的 "添加收款人" 即可给多人发币.
但是如果同时给几百人发币呢? 一般人遇不到这类问题, 矿场老板需要面对这个棘手的问题. 用手机版的钱包会把手指头划肿的, 即使用电脑操作, 也非常容易出错. 这时必须用编程来解决, RPC 调用是一种比较方便的解决办法.
以下内容是写给程序员的, 如果不是程序员, 请直接跳到最后, 那里是炒币内容.
跑通 RPC 调用
1)配置 bitcoin core
首先需要修改 bitcoin core 数据文件夹中的 bitcoin.conf 文件, 加三行文字(请自行更换用户名和密码):
- server=1
- rpcuser=shenlongbin
rpcpassword = 申龙斌的程序人生
2)下载 BitcoinLib
用我上一篇文章Bitcoin Core 钱包常用的命令行参数的 - datadir 参数启动 Bitcoin Core 之后, 我们就可以编程进行 RPC 调用了. 网上现成的 bitcoin RPC 函数库很多, 各种编程语言都支持, 这里以 C# 为例, 比较全的类库是 BitcoinLib, 下载地址:
https://github.com/GeorgeKimionis/BitcoinLib
3)加上引用
在 VisualStudio 中可以用 nuget 添加引用, 再加上常用的 using 语句.
- using BitcoinLib.ExceptionHandling.Rpc;
- using BitcoinLib.Requests.CreateRawTransaction;
- using BitcoinLib.Requests.SignRawTransaction;
- using BitcoinLib.Responses;
- using BitcoinLib.Services.Coins.Base;
- using BitcoinLib.Services.Coins.Bitcoin;
4)先声明一个 rpc 变量
ICoinService rpc = new BitcoinService(useTestnet: false);
这个类库不仅支持 BTC, 还支持其它竞争币, 我曾经试过 BCH, 也一样可用.
5)用户名和密码要一致
程序默认从资源文件中读入 RPC 的用户名和密码, 也可以在代码中直接修改:
- rpc.Parameters.RpcUsername = "shenlongbin";
- rpc.Parameters.RpcPassword = "申龙斌的程序人生"
6)测试 rpc 是否连通
rpc.Ping();
如果这条语句抛出异常, 说明 RPC 连接中存在问题, 请依次检查 bitcoin core 是否启动, 配置的用户名和密码是否正确等等.
如果以上过程都通过, 则说明 RPC 功能已经可以工作, 下面的任务就是构造交易数据, 签名和广播消息了.
读出钱包中的 UTXO
UTXO 就是指钱包中的未花费的交易记录.
List utxos = rpc.ListUnspent(0);
每一笔未花费记录的挖矿时间, 数量, 确认数, 地址都可以查到.
- for (int i = 0; i < utxos.Count; i++) {
- ListUnspentResponse uns = utxos[i];
- GetTransactionResponse response = rpc.GetTransaction(uns.TxId);
- // response.BlockTime
- // uns.Amount.ToString("0.00000000")
- // uns.Confirmations
- // uns.Address
- }
构建交易
比特币的一条交易由输入和输出构成, 用下面语句构成:
- CreateRawTransactionRequest req = new CreateRawTransactionRequest();
- req.AddInput(utxos[0].TxId, utxos[0].Vout);
- req.AddInput(utxos[1].TxId, utxos[1].Vout);
- ... ...
选择哪几笔 UTXO, 是你自己的责任, 以前都是 Bitcoin Core 钱包帮你做了, 现在是自己编程来解决.
添加输出项:
- req.AddOutput("1BPCVbLf7Xz6Y9cKQn7WbuBbDLX6nAhtLr", (decimal)0.002);
- req.AddOutput("15H6LPBMEx46U6ryDUnKJoZDAqmmBMpNV6", (decimal)0.002);
- req.AddOutput("1DqvWgjp5i9QUzkg1B44crHUkdoRrdrrww", (decimal)0.002);
- req.AddOutput("19DBjYq1mgMz63axBfbViqPxWyR5vXd9Zf", (decimal)0.002);
- req.AddOutput("3JvYRhX3fghSqFPM4kQ3a7i8bbbaHa8Pnn", (decimal)0.002);
如果有找零地址, 也需要程序员自己添加 AddOutput()语句来解决, 否则就当手续费被矿工赚走了, 这点编程时务必要注意.
现在可以生成交易数据了, 这里的 raw 是指未经过加工的数据, 也就是未签名的交易数据.
string rawTX = rpc.CreateRawTransaction(req);
构建出来的交易是否有问题, 可以用解码功能来验证, 涉及成千上万元的转账操作, 得谨慎一些.
DecodeRawTransactionResponse response = rpc.DecodeRawTransaction(rawTX);
签名交易
这里需要取出钱包里的私钥对你构建好的交易数据进行签名, 先要用钱包密码解锁钱包.
rpc.WalletPassphrase(bitcoin_core_wallet_password, 20);
为了安全, 20 秒之后钱包自动重新锁住 .
签名操作很简单:
- SignRawTransactionResponse response = rpc.SignRawTransaction(new SignRawTransactionRequest(rawTX));
- string signedTX = response.Hex
发送交易
签名之后的交易数据就可以拿到全网进行广播了, 返回的字符串就是交易 ID.
string txid = rpc.SendRawTransaction(signedTX);
如果交易成功, 马上在 blockchain.info 网站上可以查到刚才的 TXID.
声明: 本文只是介绍了 BitcoinLib 编程中的主要步骤, 省略了大量有关异常处理的代码. 利用 BitcoinLib 不仅可以发币, 还可以完成 Bitcoin Core 的几乎所有功能, 这里不细述了.
我以前完成的发币程序的主界面是这样的:
来源: http://zhuanlan.51cto.com/art/201807/580120.htm