区块链钱包之ETH钱包生成

2,404 阅读2分钟

这篇文章我们就来讲讲ETH钱包地址生成方式吧

前面说了一些关于区块链生成钱包地址的方法说了一下, 那么该如何用代码去生成钱包地址呢? 之前我在做钱包的时候, 搜了很多资料, 很少有写如何去生成钱包地址, 当然英文资料也不多. 最后还是去gayhub里面看了开源钱包, 才搞清楚了一些方法. 我们这里使用的是bitcoinj来生成. 一般都是分几个步骤: 生成助记词, 根据助记词生成地址

配置环境

首先我们这里使用的Android studio 3.0, 直接在app/build.gradle里面添加依赖

implementation group: 'org.bitcoinj', name: 'bitcoinj-core', version: '0.14.6'
implementation 'org.web3j:core:3.3.1-android'

先填坑, 生成助记词需要使用到MnemonicUtils这个类, 但是有坑, 加载助记词列表文件的方式在Android上面根本不行, 会导致Crash

 private static List<String> populateWordList() {
        URL url = Thread.currentThread().getContextClassLoader()
                .getResource("en-mnemonic-word-list.txt");
        try {
            return readAllLines(url.toURI().getSchemeSpecificPart());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

懂的人都看出来了吧, 这是java的加载资源方式, 但是安卓需要做平台适配. 我们把en-mnemonic-word-list.txt这个文件放到assets之下, 然后用符合安卓的姿势加载. Good, 没问题了

private fun populateWordList(): List<String> {
        try {
            val fis = App.instance.assets?.open("en-mnemonic-word-list.txt")
            return readAllLines(fis!!)
        } catch (e: IOException) {
            e.printStackTrace()
        }

        return emptyList()
    }

生成助记词

生成助记词需要使用到MnemonicUtils这个类, 要生成助记词很简单, 需要如下代码生成助记词, 助记词的格式就是12个单词

//average green proud remember advance trick estate oblige trouble when cube person
private val secureRandom = MySecureRandomUtils.secureRandom()
fun makeMnemonic(): String {
        val initialEntropy = ByteArray(16)
        secureRandom.nextBytes(initialEntropy)
        return MyMnemonicUtils.generateMnemonic(initialEntropy)
    }

生成ETH地址

先根据生成的助记词, 生成一些列的种, 运用了 BIP32确定性钱包算法(deterministic wallet algorithm)

private fun createETHWalletFromWords(words: String): TianWallet {
        val wordsList = Arrays.asList(*words.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
        val deterministicSeed = DeterministicSeed(wordsList, null, "", 0)
        val deterministicKeyChain = DeterministicKeyChain.builder().seed(deterministicSeed).build()
        //DERIVATION_PATH = "m/44'/60'/0'/0/0"
        val privateKey = deterministicKeyChain.getKeyByPath(parsePath(DERIVATION_PATH), true).privKey

        val ecKeyPair = ECKeyPair.create(privateKey)
        val address = Keys.getAddress(ecKeyPair)
        return TianWallet("0x$address", Numeric.toHexStringWithPrefix(ecKeyPair.privateKey), Numeric.toHexStringWithPrefix(ecKeyPair.publicKey), words)
    }

更多教程请访问爱去玩的专栏