区块链钱包开发之BCH(BSV)Java版本离线签名

前言

        大家好,我是凉凉,距离上一篇博客有一段时间了,中间也一直在做其他事情,没时间更新博客,现在就来说下BCH(BSV)的java版本的离线签名,我发这篇博客的原因也是因为之前在对接BCH(BSV)的时候没有找到什么好的资料,后面通过一些开源项目和之前BTC的经验把这个搞定了,现在就来分享下.

正文

1.原理部分(BCH(BSV)和BTC的区别)

就目前来说,BCH和BSV在交易转账方面的是完全一样的,同时也导致了重放攻击(一笔交易能在两条链上都广播生效)的问题,不过现在不要考虑这个问题了,BCH和BSV可以用一套代码,运行不同的节点.

BCH是由BTC分叉下来的,当初为了重放保护就在签名的时候加了一些参数,这样就导致了我们用BTC那套代码不能用在BCH上面了,这也是我写这篇博客的原因

2.代码部分

我这边都是用的BCH的地址是1开头的,至于q开头的新地址,可以去找对应的项目转换,原理都是一样的

签名部分和BTC的区别就是加了SIGHASH_FORKID(0x40) 详情请看连接https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/abc/replay-protected-sighash.md

需要引的依赖项目是 https://github.com/bitcoincash-wallet/bitcoinj  分支选择 addsingedinputs

/**
 * bch bsv 离线签名
 *
 * @param privateKey
 * @param changeAddress
 * @param changeAmount
 * @param toAddress
 * @param outputs
 * @param amount
 * @return
 */
public String sign(String privateKey, String changeAddress, Long changeAmount, String toAddress, List outputs, Long amount) {
    MainNetParams netParams = MainNetParams.get();
    Transaction tran = new Transaction(netParams);

    //这里是交易的版本就是分叉之后的版本
    tran.setVersion(Transaction.FORKID_VERSION);

    //这是添加输出的地址和金额
    tran.addOutput(Coin.valueOf(amount), Address.fromBase58(netParams, toAddress));

    //这是添加找零地址和金额
    if (changeAmount.compareTo(0L) > 0) {
        tran.addOutput(Coin.valueOf(changeAmount), Address.fromBase58(netParams, changeAddress));
    }

    //签名
    for (int i = 0; i < outputs.size(); i++) {
        Utxo output = outputs.get(i);
        ECKey ecKey = DumpedPrivateKey.fromBase58(netParams, privateKey).getKey();
        TransactionOutPoint transactionOutPoint = new TransactionOutPoint(netParams, output.getVout(), Sha256Hash.wrap(output.getTxHash()));
        //这个添加签名输入的最后一个参数就是添加了SIGHASH_FORKID(0x40)
        tran.addSignedInput(transactionOutPoint, Coin.valueOf(output.getAmount().longValue()), new Script(HexUtil.decodeHex(output.getScriptPubKey())), ecKey, Transaction.SigHash.ALL, true, true);
    }

    //这是签名之后的原始交易,直接去广播就行了
    String signedHex = HexUtil.encodeHexStr(tran.bitcoinSerialize());
    //这是交易的hash
    String txHash = HexUtil.encodeHexStr(Utils.reverseBytes(Sha256Hash.hash(Sha256Hash.hash(tran.bitcoinSerialize()))));
    return signedHex;
}

如果有什么不明白的直接下面留言,或者加我qq:520283995

你可能感兴趣的:(区块链,钱包)