forked from tronprotocol/java-tron
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move common functions from chainbase, framewrok to common module
- Loading branch information
1 parent
2f5c54f
commit 1096eb6
Showing
34 changed files
with
536 additions
and
324 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file was deleted.
Oops, something went wrong.
93 changes: 93 additions & 0 deletions
93
common/src/main/java/org/tron/common/utils/DecodeUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package org.tron.common.utils; | ||
|
||
import static org.tron.common.utils.Hash.sha3omit12; | ||
import static org.tron.core.Constant.ADD_PRE_FIX_BYTE_MAINNET; | ||
|
||
import java.util.Arrays; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang3.ArrayUtils; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.spongycastle.math.ec.ECPoint; | ||
|
||
@Slf4j(topic = "Commons") | ||
public class DecodeUtil { | ||
|
||
public static final int ADDRESS_SIZE = 42; | ||
public static final int ASSET_ISSUE_COUNT_LIMIT_MAX = 1000; | ||
public static byte addressPreFixByte = ADD_PRE_FIX_BYTE_MAINNET; | ||
|
||
public static byte[] clone(byte[] value) { | ||
byte[] clone = new byte[value.length]; | ||
System.arraycopy(value, 0, clone, 0, value.length); | ||
return clone; | ||
} | ||
|
||
private static byte[] decode58Check(String input) { | ||
byte[] decodeCheck = Base58.decode(input); | ||
if (decodeCheck.length <= 4) { | ||
return null; | ||
} | ||
byte[] decodeData = new byte[decodeCheck.length - 4]; | ||
System.arraycopy(decodeCheck, 0, decodeData, 0, decodeData.length); | ||
byte[] hash0 = Sha256Hash.hash(decodeData); | ||
byte[] hash1 = Sha256Hash.hash(hash0); | ||
if (hash1[0] == decodeCheck[decodeData.length] && | ||
hash1[1] == decodeCheck[decodeData.length + 1] && | ||
hash1[2] == decodeCheck[decodeData.length + 2] && | ||
hash1[3] == decodeCheck[decodeData.length + 3]) { | ||
return decodeData; | ||
} | ||
return null; | ||
} | ||
|
||
public static boolean addressValid(byte[] address) { | ||
if (ArrayUtils.isEmpty(address)) { | ||
logger.warn("Warning: Address is empty !!"); | ||
return false; | ||
} | ||
if (address.length != ADDRESS_SIZE / 2) { | ||
logger.warn( | ||
"Warning: Address length need " + ADDRESS_SIZE + " but " + address.length | ||
+ " !!"); | ||
return false; | ||
} | ||
|
||
if (address[0] != addressPreFixByte) { | ||
logger.warn("Warning: Address need prefix with " + addressPreFixByte + " but " | ||
+ address[0] + " !!"); | ||
return false; | ||
} | ||
//Other rule; | ||
return true; | ||
} | ||
|
||
public static byte[] decodeFromBase58Check(String addressBase58) { | ||
if (StringUtils.isEmpty(addressBase58)) { | ||
logger.warn("Warning: Address is empty !!"); | ||
return null; | ||
} | ||
byte[] address = decode58Check(addressBase58); | ||
if (address == null) { | ||
return null; | ||
} | ||
|
||
if (!addressValid(address)) { | ||
return null; | ||
} | ||
|
||
return address; | ||
} | ||
|
||
public static String createReadableString(byte[] bytes) { | ||
return ByteArray.toHexString(bytes); | ||
} | ||
|
||
public static byte[] computeAddress(ECPoint pubPoint) { | ||
return computeAddress(pubPoint.getEncoded(/* uncompressed */ false)); | ||
} | ||
|
||
public static byte[] computeAddress(byte[] pubBytes) { | ||
return sha3omit12( | ||
Arrays.copyOfRange(pubBytes, 1, pubBytes.length)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
/* | ||
* Copyright (c) [2016] [ <ether.camp> ] | ||
* This file is part of the ethereumJ library. | ||
* | ||
* The ethereumJ library is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* The ethereumJ library is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package org.tron.common.utils; | ||
|
||
import static java.util.Arrays.copyOfRange; | ||
import static org.tron.common.utils.ByteUtil.EMPTY_BYTE_ARRAY; | ||
import static org.tron.common.utils.ByteUtil.isNullOrZeroArray; | ||
import static org.tron.common.utils.ByteUtil.isSingleZero; | ||
|
||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.Provider; | ||
import java.security.Security; | ||
import java.util.Arrays; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.tron.common.crypto.jce.TronCastleProvider; | ||
|
||
@Slf4j(topic = "crypto") | ||
public class Hash { | ||
|
||
public static final byte[] EMPTY_TRIE_HASH; | ||
private static final Provider CRYPTO_PROVIDER; | ||
private static final String HASH_256_ALGORITHM_NAME; | ||
private static final String HASH_512_ALGORITHM_NAME; | ||
/** | ||
* [0x80] If a string is 0-55 bytes long, the RLP encoding consists of a single byte with value | ||
* 0x80 plus the length of the string followed by the string. The range of the first byte is thus | ||
* [0x80, 0xb7]. | ||
*/ | ||
private static final int OFFSET_SHORT_ITEM = 0x80; | ||
|
||
/** | ||
* [0xb7] If a string is more than 55 bytes long, the RLP encoding consists of a single byte with | ||
* value 0xb7 plus the length of the length of the string in binary form, followed by the length | ||
* of the string, followed by the string. For example, a length-1024 string would be encoded as | ||
* \xb9\x04\x00 followed by the string. The range of the first byte is thus [0xb8, 0xbf]. | ||
*/ | ||
private static final int OFFSET_LONG_ITEM = 0xb7; | ||
|
||
/** | ||
* Reason for threshold according to Vitalik Buterin: - 56 bytes maximizes the benefit of both | ||
* options - if we went with 60 then we would have only had 4 slots for long strings so RLP would | ||
* not have been able to store objects above 4gb - if we went with 48 then RLP would be fine for | ||
* 2^128 space, but that's way too much - so 56 and 2^64 space seems like the right place to put | ||
* the cutoff - also, that's where Bitcoin's varint does the cutof | ||
*/ | ||
private static final int SIZE_THRESHOLD = 56; | ||
|
||
static { | ||
Security.addProvider(TronCastleProvider.getInstance()); | ||
CRYPTO_PROVIDER = Security.getProvider("SC"); | ||
HASH_256_ALGORITHM_NAME = "TRON-KECCAK-256"; | ||
HASH_512_ALGORITHM_NAME = "TRON-KECCAK-512"; | ||
EMPTY_TRIE_HASH = sha3(encodeElement(EMPTY_BYTE_ARRAY)); | ||
} | ||
|
||
public static byte[] sha3(byte[] input) { | ||
MessageDigest digest; | ||
try { | ||
digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, | ||
CRYPTO_PROVIDER); | ||
digest.update(input); | ||
return digest.digest(); | ||
} catch (NoSuchAlgorithmException e) { | ||
logger.error("Can't find such algorithm", e); | ||
throw new RuntimeException(e); | ||
} | ||
|
||
} | ||
|
||
public static byte[] sha3(byte[] input1, byte[] input2) { | ||
MessageDigest digest; | ||
try { | ||
digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, | ||
CRYPTO_PROVIDER); | ||
digest.update(input1, 0, input1.length); | ||
digest.update(input2, 0, input2.length); | ||
return digest.digest(); | ||
} catch (NoSuchAlgorithmException e) { | ||
logger.error("Can't find such algorithm", e); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
/** | ||
* hashing chunk of the data | ||
* | ||
* @param input - data for hash | ||
* @param start - start of hashing chunk | ||
* @param length - length of hashing chunk | ||
* @return - keccak hash of the chunk | ||
*/ | ||
public static byte[] sha3(byte[] input, int start, int length) { | ||
MessageDigest digest; | ||
try { | ||
digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, | ||
CRYPTO_PROVIDER); | ||
digest.update(input, start, length); | ||
return digest.digest(); | ||
} catch (NoSuchAlgorithmException e) { | ||
logger.error("Can't find such algorithm", e); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public static byte[] sha512(byte[] input) { | ||
MessageDigest digest; | ||
try { | ||
digest = MessageDigest.getInstance(HASH_512_ALGORITHM_NAME, | ||
CRYPTO_PROVIDER); | ||
digest.update(input); | ||
return digest.digest(); | ||
} catch (NoSuchAlgorithmException e) { | ||
logger.error("Can't find such algorithm", e); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
/** | ||
* Calculates RIGTMOST160(SHA3(input)). This is used in address calculations. * | ||
* | ||
* @param input - data | ||
* @return - add_pre_fix + 20 right bytes of the hash keccak of the data | ||
*/ | ||
public static byte[] sha3omit12(byte[] input) { | ||
byte[] hash = sha3(input); | ||
byte[] address = copyOfRange(hash, 11, hash.length); | ||
address[0] = DecodeUtil.addressPreFixByte; | ||
return address; | ||
} | ||
|
||
public static byte[] encodeElement(byte[] srcData) { | ||
|
||
// [0x80] | ||
if (isNullOrZeroArray(srcData)) { | ||
return new byte[]{(byte) OFFSET_SHORT_ITEM}; | ||
|
||
// [0x00] | ||
} else if (isSingleZero(srcData)) { | ||
return srcData; | ||
|
||
// [0x01, 0x7f] - single byte, that byte is its own RLP encoding | ||
} else if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) { | ||
return srcData; | ||
|
||
// [0x80, 0xb7], 0 - 55 bytes | ||
} else if (srcData.length < SIZE_THRESHOLD) { | ||
// length = 8X | ||
byte length = (byte) (OFFSET_SHORT_ITEM + srcData.length); | ||
byte[] data = Arrays.copyOf(srcData, srcData.length + 1); | ||
System.arraycopy(data, 0, data, 1, srcData.length); | ||
data[0] = length; | ||
|
||
return data; | ||
// [0xb8, 0xbf], 56+ bytes | ||
} else { | ||
// length of length = BX | ||
// prefix = [BX, [length]] | ||
int tmpLength = srcData.length; | ||
byte lengthOfLength = 0; | ||
while (tmpLength != 0) { | ||
++lengthOfLength; | ||
tmpLength = tmpLength >> 8; | ||
} | ||
|
||
// set length Of length at first byte | ||
byte[] data = new byte[1 + lengthOfLength + srcData.length]; | ||
data[0] = (byte) (OFFSET_LONG_ITEM + lengthOfLength); | ||
|
||
// copy length after first byte | ||
tmpLength = srcData.length; | ||
for (int i = lengthOfLength; i > 0; --i) { | ||
data[i] = (byte) (tmpLength & 0xFF); | ||
tmpLength = tmpLength >> 8; | ||
} | ||
|
||
// at last copy the number bytes after its length | ||
System.arraycopy(srcData, 0, data, 1 + lengthOfLength, srcData.length); | ||
|
||
return data; | ||
} | ||
} | ||
} |
Oops, something went wrong.