一、Solana介绍
Solana是一个新兴的高性能的公链,它提供了快速、便宜且可扩展的交易体验,每秒能够处理数千笔交易,并且出块时间达到了亚秒级。它通过拜占庭容错(BFT)共识机制实现了这一点,该机制利用了一种历史证明(PoH)的创新的密码学函数。并且它还支持使用Rust,C++和C语言来编写智能合约。
官网:https://solana.com/zh
之前开了btc、eth、tron等的钱包,现在空闲记录下solana生成离线地址。
钱包
- BIP32:定义 Hierarchical Deterministic wallet (简称 “HD Wallet”),是一个系统可以从单一个 seed 产生一树状结构储存多组 keypairs(私钥和公钥)。好处是可以方便的备份、转移到其他相容装置(因为都只需要 seed),以及分层的权限控制等。
- BIP39:将 seed 用方便记忆和书写的单字表示。一般由 12 个单字组成,称为 mnemonic code(phrase),中文称为助记词或助记码。例如:
soldier dish answer treat exhibit blade diary glory arrange shoe ocean card
- BIP44:基于 BIP32 的系统,赋予树状结构中的各层特殊的意义。让同一个 seed 可以支援多币种、多帐户等。各层定义如下:
m / purpose' / coin_type' / account' / change / address_index //purporse': 固定值44', 代表是BIP44 //coin_type': 这个代表的是币种, 可以兼容很多种币, 比如BTC是0, ETH是60,TRX是195 //account: 代表这个币的账户索引,从0开始 //change: 常量0用于外部(收款地址),常量1用于内部(也称为找零地址)。外部用于在钱包外可见的地址(例如,用于接收付款)。内部链用于在钱包外部不可见的地址,用于返回交易变更。 (所以一般使用0) //address_index: 地址索引,从0开始,代表生成第几个地址 //btc一般是 m/44'/0'/0'/0 //eth一般是 m/44'/60'/0'/0 //trx一般是 m/44'/195'/0'/0
币种类型列表
依赖
<!-- https://mvnrepository.com/artifact/com.portto.solana/web3 --><dependency> <groupId>com.portto.solana</groupId> <artifactId>web3</artifactId> <version>0.1.3</version></dependency>
依赖库编译时遇到的问题:卸载2019版本的idea,装了2022版本
// This class file was compiled with different version of Kotlin compiler and can't be decompiled.//// Current compiler ABI version is 1.1.15// File ABI version is 1.6.0
生成地址及私钥
byte[] seed = MnemonicUtils.generateSeed(mnemonic, "");SolanaBip44 solanaBip44 = new SolanaBip44();//M/44H/501H/0H/0Hbyte[] privateKeyFromSeed = solanaBip44.getPrivateKeyFromSeed(seed, DerivableType.BIP44CHANGE);TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(privateKeyFromSeed);System.out.println("地址0:" + Base58.encode(keyPair.getPublicKey()));System.out.println("私钥0:" + Base58.encode(keyPair.getSecretKey()));Account account = new Account(keyPair);System.out.println("Account地址0:" + account.getPublicKey());System.out.println("Account私钥0:" + Base58.encode(account.getSecretKey()));
BIP44助记词生成N个地址
//拆解 getPrivateKeyFromSeed(seed, DerivableType.BIP44CHANGE);for (int i = 0; i < 10; i++) { HdKeyGenerator hdKeyGenerator = new HdKeyGenerator(); SolanaCoin solanaCoin = new SolanaCoin(); HdAddress masterAddress = hdKeyGenerator.getAddressFromSeed(seed, solanaCoin); HdAddress purposeAddress = hdKeyGenerator.getAddress(masterAddress, solanaCoin.getPurpose(), solanaCoin.getAlwaysHardened());// 44H HdAddress coinTypeAddress = hdKeyGenerator.getAddress(purposeAddress, solanaCoin.getCoinType(), solanaCoin.getAlwaysHardened());// 501H HdAddress accountAddress = hdKeyGenerator.getAddress(coinTypeAddress, i, solanaCoin.getAlwaysHardened());//0H HdAddress changeAddress = hdKeyGenerator.getAddress(accountAddress, 0L, solanaCoin.getAlwaysHardened()); //0H Account account1 = new Account(TweetNaclFast.Signature.keyPair_fromSeed(changeAddress.getPrivateKey().getPrivateKey())); System.out.println("Account地址" + i + ":" + account1.getPublicKey()); System.out.println("Account私钥" + i + ":" + Base58.encode(account1.getSecretKey()));}
私钥转换地址
package com.hlf.test.solana;import com.portto.solana.web3.Account;import com.portto.solana.web3.util.TweetNaclFast;import org.bitcoinj.core.Base58;/** * @ClassName: PrivateKeyAddress * @Author: huanglefei * @CreateDate: 2022/4/2 8:29 PM * @Description: * @Version: 1.0 **/public class PrivateKeyAddress { //地址0:2Hyaw6rryApLpffVYZxvT2BTAAARoJzoCBSs6Zy3bVow //私钥0:3WWsrp38veGfPJcdfmPDwGwqgaGGFQ7uZrk61rcYCbGyKjFXLYWid6CJgBUXTA8Ls2vSS8gMGhjtFrGSLYuAtZ4D public static void main(String[] args) { String privateKey = "3WWsrp38veGfPJcdfmPDwGwqgaGGFQ7uZrk61rcYCbGyKjFXLYWid6CJgBUXTA8Ls2vSS8gMGhjtFrGSLYuAtZ4D"; byte[] decode = Base58.decode(privateKey); Account account1 = new Account(TweetNaclFast.Signature.keyPair_fromSecretKey(decode)); Account account2 = new Account(TweetNaclFast.Signature.keyPair_fromSeed(decode)); System.out.println("私钥转换地址:" + account1.getPublicKey()); System.out.println("私钥转换地址-私钥:" + Base58.encode(account1.getSecretKey())); }}
示例代码
package com.hlf.test.solana;import com.portto.solana.web3.Account;import com.portto.solana.web3.util.TweetNaclFast;import com.portto.solana.web3.wallet.*;import org.apache.commons.lang3.StringUtils;import org.bitcoinj.core.Base58;import org.web3j.crypto.*;import java.io.File;import java.io.IOException;import java.math.BigInteger;/** * @ClassName: MnemonicAddress * @Author: huanglefei * @CreateDate: 2022/4/2 8:19 PM * @Description: * @Version: 1.0 **/public class MnemonicAddress { private static final String KEYSTORE_PATH = "/Users/huanglefei/Downloads/"; public static void main(String[] args) { String mnemonic = "soldier dish answer treat exhibit blade diary glory arrange shoe ocean card"; if (StringUtils.isBlank(mnemonic)) { try { // generate Mnemonic and keystone File Bip39Wallet bip39Wallet = generateBip44Wallet("hlf", KEYSTORE_PATH); //助记词 mnemonic = bip39Wallet.getMnemonic(); System.out.println("助记词:" + mnemonic); } catch (CipherException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } byte[] seed = MnemonicUtils.generateSeed(mnemonic, ""); SolanaBip44 solanaBip44 = new SolanaBip44(); //M/44H/501H/0H/0H byte[] privateKeyFromSeed = solanaBip44.getPrivateKeyFromSeed(seed, DerivableType.BIP44CHANGE); TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(privateKeyFromSeed); System.out.println("地址0:" + Base58.encode(keyPair.getPublicKey())); System.out.println("私钥0:" + Base58.encode(keyPair.getSecretKey())); Account account = new Account(keyPair); System.out.println("Account地址0:" + account.getPublicKey()); System.out.println("Account私钥0:" + Base58.encode(account.getSecretKey())); System.out.println(); //M/44H/501H/0H/0H //通过助记词生成n个地址及私钥 //拆解 getPrivateKeyFromSeed(seed, DerivableType.BIP44CHANGE); for (int i = 0; i < 10; i++) { HdKeyGenerator hdKeyGenerator = new HdKeyGenerator(); SolanaCoin solanaCoin = new SolanaCoin(); HdAddress masterAddress = hdKeyGenerator.getAddressFromSeed(seed, solanaCoin); HdAddress purposeAddress = hdKeyGenerator.getAddress(masterAddress, solanaCoin.getPurpose(), solanaCoin.getAlwaysHardened());// 44H HdAddress coinTypeAddress = hdKeyGenerator.getAddress(purposeAddress, solanaCoin.getCoinType(), solanaCoin.getAlwaysHardened());// 501H HdAddress accountAddress = hdKeyGenerator.getAddress(coinTypeAddress, i, solanaCoin.getAlwaysHardened());//0H HdAddress changeAddress = hdKeyGenerator.getAddress(accountAddress, 0L, solanaCoin.getAlwaysHardened()); //0H Account account1 = new Account(TweetNaclFast.Signature.keyPair_fromSeed(changeAddress.getPrivateKey().getPrivateKey())); System.out.println("Account地址" + i + ":" + account1.getPublicKey()); System.out.println("Account私钥" + i + ":" + Base58.encode(account1.getSecretKey())); } } public static Bip39Wallet generateBip44Wallet(String pwd, String dirPath) throws CipherException, IOException { File dir = new File(dirPath); if (!dir.exists()) { if (!dir.mkdirs()) { throw new RuntimeException("make wallet dir error"); } } return Bip44WalletUtils.generateBip44Wallet(pwd, dir); } public static String generateMnemonicFile(String pwd, String mnemonic, String dirPath) throws CipherException, IOException { // make dir File dir = new File(dirPath); if (!dir.exists()) { if (!dir.mkdirs()) { throw new RuntimeException("make wallet dir error"); } } // string to pk byte[] entBytes = MnemonicUtils.generateEntropy(mnemonic); BigInteger entBigInteger = new BigInteger(entBytes); ECKeyPair entEcKeyPair = ECKeyPair.create(entBigInteger); return WalletUtils.generateWalletFile(pwd, entEcKeyPair, dir, false); }}
控制台
Connected to the target VM, address: '127.0.0.1:56354', transport: 'socket'地址0:2Hyaw6rryApLpffVYZxvT2BTAAARoJzoCBSs6Zy3bVow私钥0:3WWsrp38veGfPJcdfmPDwGwqgaGGFQ7uZrk61rcYCbGyKjFXLYWid6CJgBUXTA8Ls2vSS8gMGhjtFrGSLYuAtZ4DAccount地址0:2Hyaw6rryApLpffVYZxvT2BTAAARoJzoCBSs6Zy3bVowAccount私钥0:3WWsrp38veGfPJcdfmPDwGwqgaGGFQ7uZrk61rcYCbGyKjFXLYWid6CJgBUXTA8Ls2vSS8gMGhjtFrGSLYuAtZ4DAccount地址0:2Hyaw6rryApLpffVYZxvT2BTAAARoJzoCBSs6Zy3bVowAccount私钥0:3WWsrp38veGfPJcdfmPDwGwqgaGGFQ7uZrk61rcYCbGyKjFXLYWid6CJgBUXTA8Ls2vSS8gMGhjtFrGSLYuAtZ4DAccount地址1:HwKQF8979cc1pwpGD8xD1GppJJTbvzbSXxQgjP5hmjCEAccount私钥1:4JAgHSGvBnSeNNiwk17eqHMdLXFqw53mmiRL8ef9rpL1ZXzVJ4GUPgYbWcRhpaZnohpt7fYe45thJKJfEed8FMrAAccount地址2:5iCnsERHGXMHApMC1J4EsTnEqcWfSew2yGmAGEjsr12ZAccount私钥2:2V9wRtqRZYAeyTHx99sKN3BNxpbVgt82TrejpmBLNR593ZqnxhteC2m9mWQuiEg9VFbttBhE4YzmxZSxZdQwaVrqAccount地址3:22ogk3ArAet5SL43zVYT4Ej8FaBfgZyFwFG8biJx9VBbAccount私钥3:3dEwx6otjGzvmXm4dB518dHpGX1cxdfnm5E4V9r1Hw4gjyDPWRARariQ293TNdojbGRWbhawLgWET58HF5dZufkqAccount地址4:CnmxbaWTKqKWvCnMSJgaAP8axfxL3udy7kLkgAU32qVMAccount私钥4:2JSvZYqaxxg92VxfpTBNonR8xQUjKoADudjzquZ33FSiMbhcdk2dfawgWMBF2NXtGReLXiz3D1678EEPsnGsaQXdAccount地址5:5gMkZhETUgBMVRVxzdZarHSTLvFFCziCkSkKrSurWTWjAccount私钥5:4DiUbrs7vcFYMCyqe4dMehiNQBhx2iRbGKsW6nmBJLzyyPuRMRdorqcEq2yME1wM7skxTMRpcYcA9dCkSduQGmUfAccount地址6:5t1DS9h3tvCGCQfWSg4MP8bpZDPZp4Gavu2w5p7hymyzAccount私钥6:2hAst5LWJuBpeqE5C4H3MvTQb2BzC4mGCrfSi9QRHA7G322KgFmp4kVEcssry1wvLVMFv7WaUUDkFosuXeWnz8txAccount地址7:DLYHSMwPodh5Qms93JcHJL17vfFsqiqJ7SBEVShqdYR8Account私钥7:tpn1HxEWXoChunYWeixisxJ5DefhGzMhySu5M2VGUWCiaieYBUGPVJWSXfPqcxPyxqjbwEypHAktVsPbAB4tJ8JAccount地址8:DoBeV5gBojXEF9WjmwVAd2Ukd5PZrxFLL8taC4h4YynuAccount私钥8:PbkuETqeHWuCHcrYSWPVDHvmD57D25CLdSUfYe3d1FpXK3qDBZj6UWT9mcy6LWvHimHmY4ciVdR14dmk7EWPAJHAccount地址9:6V5TdtRzBMNFAbbfZUQ6y7cQzk7Eg1HPnWPJuENSmckuAccount私钥9:4D9sM3zcQyTjrTtnfruNYLpA4HDRtU9PBkxVmCzYBLVnmjjKBPutumS3Q4MQP2whBJGM4jLhMvp31MJEaVPWQEAhDisconnected from the target VM, address: '127.0.0.1:56354', transport: 'socket'Process finished with exit code 0
Phantom钱包对比
solana生态钱包中生成的地址。
参考资料:
https://github.com/portto/solana-web3.kotlin
相关内容
加密交易所Coinbase重大升级:允许用户将比特币发送到Taproot地址
3个地址今日被清算涉及222395枚WE
某休眠超11年地址半小时前转出25枚BTC
httpsxcomLayerZeroLa
0x335开头地址向Binance存入1
3位巨鲸在Binance售出203万枚U
一聪明钱地址从币安提取406亿枚PEPE
0xd2D开头地址从FalconX提取6
疑似RenderNetwork地址向Bi
Web3游戏开发商SeedsLabs完成
文章来源:
小袁
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 931614094@qq.com 举报,一经查实,本站将立刻删除。