Tron波场区块链 | 使用Java将Tron钱包助记词转私钥 全网独门一份

如何使用Java将Tron钱包助记词转换为私钥?

本来想着这个问题挺简单,可是查了半天,不是,不止半天查了好长时间,看了半天官网文档,全网Java就没有实现的。

咋办。。。咋办呢?

好巧,官网我看到了一个Tronweb的东东。

呦呵。。。再细细的看下,找到一个接口。

fromMnemonic

但是咱们这个Tronweb是前端项目啊,先不管了,我们来先看是否能实现,然后看看Js的实现是否能转换为Java语言。

创建完Vue项目,我们来导入TronWeb

npm install tronweb

写一个简单的vue来实现,我在想:Tron可以离线创建私钥、地址以及助记词。它的生成也是加密解密的关系,那么这里我们使用tronweb其实并不需要实例化,只要引入它的组件包,包含加解密应该就行了,那么代码其实很简单。

扫描二维码关注公众号,回复: 17603970 查看本文章
// 导入
import Tronweb from "tronweb";
// 直接调用接口查看
Tronweb.fromMnemonic(this.zjc)

写web我们就必须要可视化,那么我们写一个简单的页面。

输入助记词,点击解析后,我们看等到了私钥、公钥还有地址信息。

那么让我们来分析一下他的实现:

import {ethersHDNodeWallet, Mnemonic} from './ethersUtils'
const account =  ethersHDNodeWallet.fromMnemonic(Mnemonic.fromPhrase(mnemonic, null, wordlist), path);
    const result = {
        mnemonic: account.mnemonic,
        privateKey: account.privateKey,
        publicKey: account.signingKey.publicKey,
        address: pkToAddress(account.privateKey.replace(/^0x/, ''))
    }

看到实际的实现是ethersHDNodeWallet、Mnemonic俩个类。然后我们再看下ethersUtils那的实现。

import {
    Mnemonic,
    HDNodeWallet as ethersHDNodeWallet
} from 'ethers';

​​​​​​​看到ethers,这里我们就可以知道了。

哦,原来Tron波场链其实也是以太坊的分支链,那么按照理论上来说Tron的加解密方式其实也是ETH的加密方式。

看到了这里,我们这里转到Java。

先理解下ETH创建离线地址的过程:

1.生成一个随机的助记词

2.使用助记词生成一串种子

3.进行路径(BIP30)加密后产出地址等信息。

那么现在我们已经有了助记词,是不是直接用当前的助记词来生成种子,就可以产出私钥、地址等了呢?

publicstatic void main(String[] args) {
    String mnemonic = "program repair next claw rival slight spider tennis begin cute daring fancy";
    //使用助记词生成钱包种子
    List<String> mnemonics = Splitter.on(" ").splitToList(mnemonic);
    System.out.println(mnemonics.get(0));
    byte[] seed = MnemonicCode.toSeed(mnemonics, "");

    DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
    DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(masterPrivateKey);
    DeterministicKey deterministicKey = deterministicHierarchy
            .deriveChild(BIP44_ETH_ACCOUNT_ZERO_PATH, false, true, new ChildNumber(0));
    byte[] bytes = deterministicKey.getPrivKeyBytes();
    ECKeyPair keyPair = ECKeyPair.create(bytes);
    System.out.println("0x" + keyPair.getPrivateKey().toString(16));
}

​​​​​​​运行程序后,结果是错的。

那么到底是哪里错了呢?

再看看代码前面的TronWeb接口:

图片

哦哦哦。。。原来的path是BIP44(m/44'/195'/0'/0/0),那么我们把这个Path参数修改下,看是否可行?

之前试了好几次,都没有达到最终正确的生成。

快要绝望的时候,我直接按了一下IDEA的快捷键俩下SHIFT+SHIFT,有了新的机会!

图片

这不是我要找的工具类吗?打开类看了它的内部实现,其实还不能完全适用,但是逻辑咱们清楚了,我们就来实现吧

public static final int HARDENED_BIT = 0x80000000;

public static void main(String[] args) throws MnemonicException.MnemonicLengthException {
    String mnemonic = "program repair next claw rival slight spider tennis begin cute daring fancy";
    byte[] seed = MnemonicUtils.generateSeed(mnemonic, "");
    Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
    // m/44'/195'/0'/0/0
    final int[] path = {44 | HARDENED_BIT, 195 | HARDENED_BIT, 0 | HARDENED_BIT, 0, 0};
    Bip32ECKeyPair bip44Keypair = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path);
    Credentials credentials = Credentials.create(bip44Keypair);
    String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16);
    System.out.println(privateKey);

    KeyPair keyPair = new KeyPair(privateKey);
    String base58CheckAddress = keyPair.toBase58CheckAddress();
    String publicKey = keyPair.toPublicKey();
    System.out.println(publicKey);
    System.out.println(base58CheckAddress);
}

​​​​​​​运行结果正确,完美。

解决这个问题其实花了好长时间,查百度、Google还有官网接口文档,部署开发Web前端的解决方案,试图找到门路。

写到这里,可以能帮到其他开发人员。

假如还是没有办法实现,关注我,联系我,帮您解决。