diff --git a/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java b/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java index d0d18206d..a282f0ee7 100644 --- a/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java +++ b/src/main/java/org/fisco/bcos/web3j/abi/EventEncoder.java @@ -5,6 +5,7 @@ import org.fisco.bcos.web3j.abi.datatypes.Event; import org.fisco.bcos.web3j.abi.datatypes.Type; import org.fisco.bcos.web3j.crypto.Hash; +import org.fisco.bcos.web3j.crypto.SmHash; import org.fisco.bcos.web3j.utils.Numeric; /** @@ -35,9 +36,16 @@ static String buildMethodSignature( return result.toString(); } - public static String buildEventSignature(String methodSignature) { + public static String buildEventSignature(String methodSignature, Boolean isSm) { byte[] input = methodSignature.getBytes(); - byte[] hash = Hash.sha3(input); - return Numeric.toHexString(hash); + if (Boolean.TRUE.equals(isSm)) { + // 国密 + byte[] hash = SmHash.sha3(input); + return Numeric.toHexString(hash); + } else { + // keccak256 + byte[] hash = Hash.sha3(input); + return Numeric.toHexString(hash); + } } } diff --git a/src/main/java/org/fisco/bcos/web3j/crypto/SmHash.java b/src/main/java/org/fisco/bcos/web3j/crypto/SmHash.java new file mode 100644 index 000000000..bfb402a13 --- /dev/null +++ b/src/main/java/org/fisco/bcos/web3j/crypto/SmHash.java @@ -0,0 +1,102 @@ +package org.fisco.bcos.web3j.crypto; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import org.bouncycastle.crypto.digests.RIPEMD160Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.params.KeyParameter; +import org.fisco.bcos.web3j.utils.Numeric; +import org.fisco.bcos.web3j.crypto.gm.sm3.SM3Digest; + +/** Crypto related functions. */ +public class SmHash { + private SmHash() {} + + private static HashInterface hashInterface = new SM3Digest(); + + public static HashInterface getHashInterface() { + return hashInterface; + } + + public static void setHashInterface(HashInterface hashInterface) { + SmHash.hashInterface = hashInterface; + } + + /** + * SM hash function. + * + * @param hexInput hex encoded input data with optional 0x prefix + * @return hash value as hex encoded string + */ + public static String sha3(String hexInput) { + return hashInterface.hash(hexInput); + } + + /** + * SM hash function. + * + * @param input binary encoded input data + * @param offset of start of data + * @param length of data + * @return hash value + */ + public static byte[] sha3(byte[] input, int offset, int length) { + return hashInterface.hash(input, offset, length); + } + + /** + * SM hash function. + * + * @param input binary encoded input data + * @return hash value + */ + public static byte[] sha3(byte[] input) { + return hashInterface.hash(input, 0, input.length); + } + + /** + * SM hash function that operates on a UTF-8 encoded String. + * + * @param utf8String UTF-8 encoded string + * @return hash value as hex encoded string + */ + public static String sha3String(String utf8String) { + return Numeric.toHexString(sha3(utf8String.getBytes(StandardCharsets.UTF_8))); + } + + /** + * Generates SHA-256 digest for the given {@code input}. + * + * @param input The input to digest + * @return The hash value for the given input + * @throws RuntimeException If we couldn't find any SHA-256 provider + */ + public static byte[] sha256(byte[] input) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + return digest.digest(input); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("Couldn't find a SHA-256 provider", e); + } + } + + public static byte[] hmacSha512(byte[] key, byte[] input) { + HMac hMac = new HMac(new SHA512Digest()); + hMac.init(new KeyParameter(key)); + hMac.update(input, 0, input.length); + byte[] out = new byte[64]; + hMac.doFinal(out, 0); + return out; + } + + public static byte[] sha256hash160(byte[] input) { + byte[] sha256 = sha256(input); + RIPEMD160Digest digest = new RIPEMD160Digest(); + digest.update(sha256, 0, sha256.length); + byte[] out = new byte[20]; + digest.doFinal(out, 0); + return out; + } +} diff --git a/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoder.java b/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoder.java index 1f804e17e..82fc2e638 100644 --- a/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoder.java +++ b/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoder.java @@ -31,20 +31,22 @@ public class TransactionDecoder { private String abi = ""; private String bin = ""; + private Boolean isSm = false; private Map methodIDMap; public TransactionDecoder(String abi) { - this(abi, ""); + this(abi, "", false); } - public TransactionDecoder(String abi, String bin) { + public TransactionDecoder(String abi, String bin, Boolean isSm) { this.abi = abi; this.bin = bin; + this.isSm = isSm; methodIDMap = new HashMap(); List funcAbiDefinitionList = ContractAbiUtil.getFuncAbiDefinition(abi); for (AbiDefinition abiDefinition : funcAbiDefinitionList) { String methodSign = decodeMethodSign(abiDefinition); - String methodID = FunctionEncoder.buildMethodId(methodSign); + String methodID = FunctionEncoder.buildMethodId(methodSign, isSm); methodIDMap.put(methodID, abiDefinition); } } diff --git a/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoderFactory.java b/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoderFactory.java index 8d3c041cb..8c28f192d 100644 --- a/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoderFactory.java +++ b/src/main/java/org/fisco/bcos/web3j/tx/txdecode/TransactionDecoderFactory.java @@ -19,10 +19,11 @@ public class TransactionDecoderFactory { /** * @param abi * @param bin + * @param isSm 是否国密;true:国密;false:非国密,ECDSA * @return TransactionDecoder */ - public static TransactionDecoder buildTransactionDecoder(String abi, String bin) { - return new TransactionDecoder(abi, bin); + public static TransactionDecoder buildTransactionDecoder(String abi, String bin, Boolean isSm) { + return new TransactionDecoder(abi, bin, isSm); } /**