美文网首页
usdt omni离线签名

usdt omni离线签名

作者: YANG_ad29 | 来源:发表于2019-11-16 17:40 被阅读0次

    usdt omni离线签名

    /**
     * usdt 离线签名
     * @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<Utxo> outputs,Long amount) {
            MainNetParams network = MainNetParams.get();
            Transaction tran = new Transaction(MainNetParams.get());
     
            //这是比特币的限制最小转账金额,所以很多usdt转账会收到一笔0.00000546的btc
            tran.addOutput(Coin.valueOf(546L), Address.fromBase58(network, toAddress));
     
            //构建usdt的输出脚本 注意这里的金额是要乘10的8次方
            String usdtHex = "6a146f6d6e69" + String.format("%016x", 31) + String.format("%016x", amount);
           //与比特币比较只是多了这一个输出
            tran.addOutput(Coin.valueOf(0L), new Script(Utils.HEX.decode(usdtHex)));
     
            //如果有找零就添加找零
            if (changeAmount.compareTo(0L) > 0) {
                tran.addOutput(Coin.valueOf(changeAmount), Address.fromBase58(network, changeAddress));
            }
     
            //先添加未签名的输入,也就是utxo
            for (Utxo output : outputs) {
                tran.addInput(Sha256Hash.wrap(output.getTxHash()), output.getVout(), new Script(HexUtil.decodeHex(output.getScriptPubKey()))).setSequenceNumber(TransactionInput.NO_SEQUENCE - 2);
            }
     
            //下面就是签名
            for (int i = 0; i < outputs.size(); i++) {
                Utxo output = outputs.get(i);
                ECKey ecKey = DumpedPrivateKey.fromBase58(network, privateKey).getKey();
                TransactionInput transactionInput = tran.getInput(i);
                Script scriptPubKey = ScriptBuilder.createOutputScript(Address.fromBase58(network, output.getAddress()));
                Sha256Hash hash = tran.hashForSignature(i, scriptPubKey, Transaction.SigHash.ALL, false);
                ECKey.ECDSASignature ecSig = ecKey.sign(hash);
                TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
                transactionInput.setScriptSig(ScriptBuilder.createInputScript(txSig, ecKey));
            }
            //这是签名之后的原始交易,直接去广播就行了
            String signedHex = HexUtil.encodeHexStr(tran.bitcoinSerialize());
            //这是交易的hash
            String txHash = HexUtil.encodeHexStr(Utils.reverseBytes(Sha256Hash.hash(Sha256Hash.hash(tran.bitcoinSerialize()))));
            return signedHex;
    }
    

    也可以

     public void send(String address, BigInteger value, List<String> mnemonicWords, String passPhrase, String data) {
            //如果需要指定交易费账户 可用获取指定账户的utxo来支付交易费 但是最小金额min必须有发送方支付 
            int num = checkNetStatus() ? 0 : CoinType.BTC.ordinal();
            ECKey bip44Address = createBip44Address(mnemonicWords, "", num);//实现方法在上一篇
            String from = bip44Address.toAddress(params).toBase58();
            UsdtRpc instance = UsdtRpc.getInstance();
            List<BtcUnspent> utxo = null;
            try {
                utxo = instance.getListUnspent(CoinConstant.MIN_COMFIRMATION, CoinConstant.MAX_COMFIRMATION, Arrays.asList(from));
            } catch (Throwable throwable) {
                return new WalletManagerReturnDto(throwable.getMessage(),false,20020);
            }
            if (utxo == null) {
                return ;
            }
          //  BigDecimal reduce = utxo.stream().map(bchListUnspent -> bchListUnspent.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigInteger balance = BigInteger.ZERO;
            try {
                OmniBalance omniBalance = instance.getOmniBalance(from, propertyid);
                balance = new BigDecimal(omniBalance.getBalance()).multiply(BigDecimal.valueOf(CoinConstant.BTC_UNIT)).toBigInteger();
            } catch (Throwable throwable) {
                return new WalletManagerReturnDto(throwable.getMessage(),false,20020);
            }
            if (value.compareTo(balance) > 0) {
                return new WalletManagerReturnDto("余额不足",false,20020);
            }
            utxo.sort(Comparator.comparing(BtcUnspent::getConfirmations).reversed());
            Transaction transaction = new Transaction(params);
            BigInteger select = BigInteger.ZERO;
            List<BtcUnspent> spend = new ArrayList<>();
            for (BtcUnspent btcUnspent : utxo) {
                if (select.compareTo(min.add(mbfee)) >= 0) {
                    break;
                } else {
                    select = select.add(btcUnspent.getAmount().multiply(BigDecimal.valueOf(CoinConstant.BTC_UNIT)).toBigInteger());
                    spend.add(btcUnspent);
                }
            }
            if (select.compareTo(min.add(mbfee)) < 0) {
                return ;
            }
            String usdtHex = "6a146f6d6e69" + String.format("%016x", propertyid) + String.format("%016x", value.longValue());
            BigInteger change = select.subtract(min).subtract(mbfee);
            transaction.addOutput(Coin.valueOf(min.longValue()), Address.fromBase58(params, address));
            transaction.addOutput(Coin.valueOf(0L), new Script(HEX.decode(usdtHex)));
            if (change.compareTo(BigInteger.ZERO) > 0) {
                transaction.addOutput(Coin.valueOf(change.longValue()), bip44Address.toAddress(params));
            }
            spend.stream().forEach(btcUnspent -> {
                TransactionOutPoint transactionOutPoint = new TransactionOutPoint(params, btcUnspent.getVout(), Sha256Hash.wrap(btcUnspent.getTxid()));
                Script utxo_script = (new Script(HEX.decode(btcUnspent.getScriptPubKey())));
                //如果输入是不同私钥 anyoneCanPay true (最后一个参数)
                transaction.addSignedInput(transactionOutPoint, utxo_script, bip44Address, Transaction.SigHash.ALL, true);
            });
            // ECKey ecKey = DumpedPrivateKey.fromBase58(params, pk).getKey();
            byte[] spendBytes = transaction.bitcoinSerialize();
            String signDataStr = HEX.encode(spendBytes);
            String txhash = instance.sendrawtransaction(signDataStr);
            System.out.println(txhash);
            if (txhash.isEmpty()){
             
            }
            
    

    依赖和比特币是一样的
    参考https://blog.csdn.net/qq_38052781/article/details/85234947

    https://blog.csdn.net/tjl373725/article/details/90643113

    相关文章

      网友评论

          本文标题:usdt omni离线签名

          本文链接:https://www.haomeiwen.com/subject/rigyictx.html