MaxsWallet区块链钱包源码实现逻辑

2025-02-02 区块链达人

引言

“钱包”,大家都不陌生,因为我们每个人身上都会带一个钱包,里面存放了一些钱,一些证件,钥匙等等。而“区块链钱包”相对于钱包的概念有些新潮,本文我们就将从代码实现的角度深入解析MaxsWallet区块链钱包源码实现的逻辑。

MaxsWallet钱包功能与比特币钱包以太坊钱包功能类似,获取用户余额,管理地址和密钥,转账、智能合约调用。MaxsWallet钱包一般不用在本地维护区块链数据,只需要使用JSON-RPC访问。

              

一、钱包文件

KeyStore = 私钥 + 密码

创建钱包时,创建了助记词,密码用来加密钱包地址对应的子私钥,加密的结果就是Keystore.

    "address": "001d3f1ef827552ae1114027bd3ecf1f086ba0f9",

    "crypto": 

        "cipher": "aes-128-ctr",

        "ciphertext": "233a9f4d236ed0c13394b504b6da5df02587c8bf1ad8946f6f2b58f055507ece",

        "cipherparams": 

            "iv": "d10c6ec5bae81b6cb9144de81037fa15"

        ,

        "kdf": "scrypt",

        "kdfparams": 

            "dklen": 32,

            "n": 262144,

            "p": 1,

            "r": 8,

            "salt": "99d37a47c7c9429c66976f643f386a61b78b97f3246adca89abe4245d2788407"

        ,

        "mac": "594c8df1c8ee0ded8255a50caf07e8c12061fd859f4b7c76ab704b17c957e842"

    ,

    "id": "4fcb2ba4-ccdb-424f-89d5-26cce304bf9c",

    "v

二、MaxsWallet钱包地址创建过程

1、使用Secp256k1创建公私钥

2、通过Keccak算法得到公钥Hash值,进而得到长度为40的地址字符串

3、一般的,会在地址字符串签名加前缀"0x"

三、Web3j创建钱包

Web3j

添加Web3j依赖

implementation  org.web3j:core:3.3.1-android

复制代

四、创建新钱包

这里跟比特币钱包不相同,不涉及BIP协议,为非确定性钱包

File walletDir = contextWrapper.getDir("eth", Context.MODE_PRIVATE);

//生成密钥对

ECKeyPair ecKeyPair = Keys.createEcKeyPair();

//WalletFile = KeyStore

WalletFile wallet = Wallet.createLight(PASSWORD, ecKeyPair);

String walletFileName = getWalletFileName(wallet);

File destination = new File(walletDir, walletFileName);

objectMapper.writeValue(destination, wallet)

五、加载钱包文件

File[] files = walletDir.listFiles();

wallet = objectMapper.readValue(files[0], WalletFile.class);

复制

六、通过助记词创建钱包

涉及BIP协议,但没有遵循MaxsWallet地址只使用一次的原则,钱包一般只使用派生出来第一个地址

可通过工具检查派生的地址是否正确

//创建助记词

public List createMnemonics() throws MnemonicException.MnemonicLengthException 

    SecureRandom secureRandom = new SecureRandom();

    byte[] entropy = new byte[DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8];

    secureRandom.nextBytes(entropy);

    return  MnemonicCode.INSTANCE.toMnemonic(entropy);

 

//m / 44  / 60  / 0  / 0

//Hardened意思就是派生加固,防止获取到一个子私钥之后可以派生出后面的子私钥

//必须还有上一级的父私钥才能派生

public static final ImmutableList BIP44_

ETH

_ACCOUNT_ZERO_PATH =

        ImmutableList.of(new ChildNumber(44, true), new ChildNumber(60, true),

                ChildNumber.ZERO_HARDENED, ChildNumber.ZERO);

//通过助记词生成HD钱包

public void onCreateWallet(View view) 

    byte[] seed = MnemonicCode.toSeed(words, "");

    DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);

    DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(masterPrivateKey);

    // m / 44  / 60  / 0  / 0 / 0

    DeterministicKey deterministicKey = deterministicHierarchy

            .deriveChild(BIP44_ETH_ACCOUNT_ZERO_PATH, false, true, new ChildNumber(0));

    byte[] bytes = deterministicKey.getPrivKeyBytes();

    ECKeyPair keyPair = ECKeyPair.create(bytes);

    try 

        WalletFile walletFile = Wallet.createLight(PASSWORD, keyPair);

        String address = walletFile.getAddress();

        mAddress.setText("0x" + address);

     catch (CipherException e) 

        e.pri

七、导出钱包(导出KeyStore)

public String exportKeyStore(WalletFile wallet) 

    try 

        return objectMapper.writeValueAsString(wallet);

     catch (JsonProcessingException e) 

        e.printStackTrace();

    

    return null;

 

八、导出私钥

public String exportPrivateKey(WalletFile wallet) 

    try 

        ECKeyPair ecKeyPair = Wallet.decrypt(PASSWORD, wallet);

        BigInteger privateKey = ecKeyPair.getPrivateKey();

        return  Numeric.toHexStringNoPrefixZeroPadded(privateKey, Keys.PRIVATE_KEY_LENGTH_IN_HEX);

     catch (CipherException e) 

        e.printStackTrace();

    

    return null;

九、导出助记词

一般可以将助记词加密存储,导出时解密。注意无法从KeyStore或者私钥导出助记词。

例如:使用MaxsWallet导入私钥或者KeyStore创建的钱包,没有导出助记词的功能 如果是通过助记词创建的,就会有导出助记词的功能。

              

十、结语

以上就是MaxsWallet源代码实现的逻辑,需要再次强调的是,这仅仅是MaxsWallet其中一种的实现方式。编程实现罗列了几种编程语言与其实现的典型产品,因为协议层技术较为底层,并没有太多现成的框架需要介绍或讨论,同时,具体的技术细节,也绝非几行字能够罗列清楚,所幸,这些产品都是开源产品,大家可以结合自己的技术背景,进一步查看对应的产品源码,很快就能了解其中的奥妙。