版权声明:本文为博主原创文章,未经博主允许不得转载。深圳夸克时代在线技术有限公司 官网:http://www.kksdapp.com https://blog.csdn.net/wahaha13168/article/details/82914311
1:生成钱包种子
public static String generateSeed() {
int numchars = 64;
SecureRandom random = SecureRandomUtil.secureRandom();
byte[] randomBytes = new byte[numchars / 2];
random.nextBytes(randomBytes);
StringBuilder sb = new StringBuilder(numchars);
for (byte b : randomBytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
2:根据钱包种子得到私钥
/**
* Convert a wallet seed to private key
*
* @param seed Wallet seed
* @return private key
*/
public static String seedToPrivate(String seed) {
Sodium sodium = NaCl.sodium();
byte[] state = new byte[Sodium.crypto_generichash_statebytes()];
byte[] key = new byte[Sodium.crypto_generichash_keybytes()];
byte[] seed_b = NanoUtil.hexToBytes(seed);
byte[] index_b = {0x00, 0x00, 0x00, 0x00};
byte[] output = new byte[32];
Sodium.crypto_generichash_blake2b_init(state, key, 0, 32);
Sodium.crypto_generichash_blake2b_update(state, seed_b, seed_b.length);
Sodium.crypto_generichash_blake2b_update(state, index_b, index_b.length);
Sodium.crypto_generichash_blake2b_final(state, output, output.length);
return bytesToHex(output);
}
3:由私钥得到公钥
/**
* Convert a private key to a public key
*
* @param private_key private key
* @return public key
*/
public static String privateToPublic(String private_key) {
Sodium sodium = NaCl.sodium();
byte[] public_key_b = new byte[Sodium.crypto_generichash_blake2b_bytes()];
byte[] private_key_b = hexToBytes(private_key);
Sodium.crypto_sign_ed25519_sk_to_pk(public_key_b, private_key_b);
return bytesToHex(public_key_b);
}
4:由公钥生成钱包地址
/**
* Convert a Public Key to an Address
*
* @param public_key Public Key
* @return xrb address
*/
public static String publicToAddress(String public_key) {
Sodium sodium = NaCl.sodium();
byte[] bytePublic = NanoUtil.hexStringToByteArray(public_key);
String encodedAddress = encode(public_key);
byte[] state = new byte[Sodium.crypto_generichash_statebytes()];
byte[] key = new byte[Sodium.crypto_generichash_keybytes()];
byte[] check_b = new byte[5];
Sodium.crypto_generichash_blake2b_init(state, key, 0, 5);
Sodium.crypto_generichash_blake2b_update(state, bytePublic, bytePublic.length);
Sodium.crypto_generichash_blake2b_final(state, check_b, check_b.length);
reverse(check_b);
StringBuilder resultAddress = new StringBuilder();
resultAddress.insert(0, "xrb_");
resultAddress.append(encodedAddress);
resultAddress.append(encode(NanoUtil.bytesToHex(check_b)));
return resultAddress.toString();
}
5:由地址去得到公钥
/**
* Convert an address to a public key
*
* @param encoded_address encoded Address
* @return Public Key
*/
public static String addressToPublic(String encoded_address) {
NaCl.sodium();
String data = encoded_address.split("_")[1].substring(0, 52);
byte[] data_b = NanoUtil.hexStringToByteArray(decodeAddressCharacters(data));
byte[] state = new byte[Sodium.crypto_generichash_statebytes()];
byte[] key = new byte[Sodium.crypto_generichash_keybytes()];
byte[] verify_b = new byte[5];
Sodium.crypto_generichash_blake2b_init(state, key, 0, 5);
Sodium.crypto_generichash_blake2b_update(state, data_b, data_b.length);
Sodium.crypto_generichash_blake2b_final(state, verify_b, verify_b.length);
reverse(verify_b);
// left pad byte array with zeros
StringBuilder pk = new StringBuilder(NanoUtil.bytesToHex(data_b));
while (pk.length() < 64) {
pk.insert(0, "0");
}
return pk.toString();
}
6:验证地址是否合法
public boolean isValidAddress() {
String[] parts = value.split("_");
if (parts.length != 2) {
return false;
}
if (!parts[0].equals("xrb") && !parts[0].equals("nano")) {
return false;
}
if (parts[1].length() != 60) {
return false;
}
checkCharacters:
for (int i = 0; i < parts[1].length(); i++) {
char letter = parts[1].toLowerCase().charAt(i);
for (int j = 0; j < NanoUtil.addressCodeCharArray.length; j++) {
if (NanoUtil.addressCodeCharArray[j] == letter) {
continue checkCharacters;
}
}
return false;
}
byte[] shortBytes = NanoUtil.hexToBytes(NanoUtil.decodeAddressCharacters(parts[1]));
byte[] bytes = new byte[37];
// Restore leading null bytes
System.arraycopy(shortBytes, 0, bytes, bytes.length - shortBytes.length, shortBytes.length);
byte[] checksum = new byte[5];
byte[] state = new byte[Sodium.crypto_generichash_statebytes()];
byte[] key = new byte[Sodium.crypto_generichash_keybytes()];
NaCl.sodium();
Sodium.crypto_generichash_blake2b_init(state, key, 0, 5);
Sodium.crypto_generichash_blake2b_update(state, bytes, 32);
Sodium.crypto_generichash_blake2b_final(state, checksum, checksum.length);
for (int i = 0; i < checksum.length; i++) {
if (checksum[i] != bytes[bytes.length - 1 - i]) {
return false;
}
}
return true;
}
7:验证钱包种子是否合法
public static boolean isValidSeed(String seed) {
if (seed.length() != 64) {
return false;
}
boolean isMatch = true;
for (int i = 0; i < seed.length() && isMatch; i++) {
char letter = seed.toLowerCase().charAt(i);
if (!VALID_SEED_CHARACTERS.contains(letter)) {
isMatch = false;
}
}
return isMatch;
}