Skip to content

Commit

Permalink
move common functions from chainbase, framewrok to common module
Browse files Browse the repository at this point in the history
  • Loading branch information
niuniublockchain committed Oct 31, 2019
1 parent 2f5c54f commit 1096eb6
Show file tree
Hide file tree
Showing 34 changed files with 536 additions and 324 deletions.
2 changes: 0 additions & 2 deletions chainbase/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ dependencies {
compile group: leveldbGroup, name: leveldbName, version: leveldbVersion
compile "org.fusesource.jansi:jansi:$jansiVersion"
compile group: 'org.rocksdb', name: 'rocksdbjni', version: '5.15.10'
compile "com.madgag.spongycastle:core:1.58.0.0"
compile "com.madgag.spongycastle:prov:1.58.0.0"
compile group: 'com.typesafe', name: 'config', version: '1.3.2'
compile 'com.github.tronprotocol:zksnark-java-sdk:master-SNAPSHOT'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.5'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
import org.tron.common.utils.Constant;
import org.tron.core.Constant;
import org.tron.protos.Protocol.Transaction;
import org.tron.protos.contract.SmartContractOuterClass.CreateSmartContract;
import org.tron.protos.contract.SmartContractOuterClass.SmartContract;
Expand Down
1 change: 1 addition & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ repositories {
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile "com.madgag.spongycastle:core:1.58.0.0"
compile "com.madgag.spongycastle:prov:1.58.0.0"
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.5'
compile project(":protocol")
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import static org.tron.common.utils.BIUtil.isLessThan;
import static org.tron.common.utils.ByteUtil.bigIntegerToBytes;
import static org.tron.common.utils.Commons.computeAddress;
import static org.tron.common.utils.DecodeUtil.computeAddress;

import java.io.IOException;
import java.io.Serializable;
Expand Down
26 changes: 0 additions & 26 deletions common/src/main/java/org/tron/common/utils/Constant.java

This file was deleted.

93 changes: 93 additions & 0 deletions common/src/main/java/org/tron/common/utils/DecodeUtil.java
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));
}
}
199 changes: 199 additions & 0 deletions common/src/main/java/org/tron/common/utils/Hash.java
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;
}
}
}
Loading

0 comments on commit 1096eb6

Please sign in to comment.