From 2fcb24f6e9aa4a573b00835157c64be735f9ff55 Mon Sep 17 00:00:00 2001 From: MaggieNgWu Date: Fri, 16 Apr 2021 22:13:14 +0800 Subject: [PATCH 01/11] support hsm (#300) * add hsm config methods and internal key support SDF SM2 keypair add 04 prefix in public key hex string use webank-blockchain-java-crypto instead of key-mini-toolkit * supply hsm config example --- .circleci/config.yml | 1 + build.gradle | 8 +- .../fisco/bcos/sdk/config/ConfigOption.java | 12 ++ .../bcos/sdk/config/model/AccountConfig.java | 33 ++++- .../bcos/sdk/config/model/ConfigProperty.java | 10 +- .../config/model/CryptoProviderConfig.java | 31 +++++ .../bcos/sdk/model/CryptoProviderType.java | 6 + .../org/fisco/bcos/sdk/model/CryptoType.java | 3 + .../src/test/resources/config-example.toml | 1 - sdk-crypto/build.gradle | 3 +- .../fisco/bcos/sdk/crypto/CryptoSuite.java | 69 +++++++--- .../fisco/bcos/sdk/crypto/hash/Keccak256.java | 2 +- .../bcos/sdk/crypto/hash/SDFSM3Hash.java | 34 +++++ .../fisco/bcos/sdk/crypto/hash/SM3Hash.java | 2 +- .../sdk/crypto/keypair/CryptoKeyPair.java | 2 +- .../bcos/sdk/crypto/keypair/ECDSAKeyPair.java | 4 +- .../sdk/crypto/keypair/SDFSM2KeyPair.java | 123 ++++++++++++++++++ .../bcos/sdk/crypto/keypair/SM2KeyPair.java | 4 +- .../sdk/crypto/signature/ECDSASignature.java | 4 +- .../sdk/crypto/signature/SDFSM2Signature.java | 107 +++++++++++++++ .../sdk/crypto/signature/SM2Signature.java | 6 +- .../bcos/sdk/crypto/vrf/Curve25519VRF.java | 23 ++-- .../bcos/sdk/crypto/Curve25519VRFTest.java | 1 + sdk-crypto/src/test/resources/config.toml | 2 +- src/test/resources/config-example.toml | 1 - src/test/resources/config-hsm-example.toml | 65 +++++++++ 26 files changed, 506 insertions(+), 51 deletions(-) create mode 100644 sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/CryptoProviderConfig.java create mode 100644 sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoProviderType.java create mode 100644 sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SDFSM3Hash.java create mode 100644 sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java create mode 100644 sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java create mode 100644 src/test/resources/config-hsm-example.toml diff --git a/.circleci/config.yml b/.circleci/config.yml index ac1da9083..788cfa1d3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,6 +16,7 @@ jobs: - run: name: Compile command: | + bash gradlew --version bash gradlew build -x test -x integrationTest - run: name: Integration Test diff --git a/build.gradle b/build.gradle index e3196c972..6a839e816 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,8 @@ ext { nettySMSSLContextVersion = "1.2.0" toml4jVersion = "0.7.2" bcprovJDK15onVersion = "1.60" - keyMiniToolkit = "1.0.3" + webankJavaCryptoVersion = "1.0.0-005-SNAPSHOT" + webankHsmCryptoVersion = "1.0.0-008-SNAPSHOT" slf4jVersion = "1.7.30" junitVersion = "4.12" @@ -66,6 +67,7 @@ allprojects { maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2"} maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven {url "https://plugins.gradle.org/m2/"} } dependencies { @@ -193,9 +195,9 @@ dependencies { compile ("commons-io:commons-io:${commonsIOVersion}") compile ("com.squareup:javapoet:${javapoetVersion}") compile ("info.picocli:picocli:${picocliVersion}") - compile ("com.webank:key-mini-toolkit:${keyMiniToolkit}") + compile ("com.webank:webank-blockchain-java-crypto:${webankJavaCryptoVersion}") compile ("com.moandjiezana.toml:toml4j:${toml4jVersion}") - + compile ("com.webank:webank-blockchain-hsm-crypto:${webankHsmCryptoVersion}") testCompile ("org.apache.commons:commons-collections4:${commonsCollections4Version}") testCompile ("com.google.guava:guava:${guavaVersion}") } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/ConfigOption.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/ConfigOption.java index 1d3123830..0869c0bf5 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/ConfigOption.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/ConfigOption.java @@ -21,6 +21,7 @@ import org.fisco.bcos.sdk.config.model.AmopConfig; import org.fisco.bcos.sdk.config.model.ConfigProperty; import org.fisco.bcos.sdk.config.model.CryptoMaterialConfig; +import org.fisco.bcos.sdk.config.model.CryptoProviderConfig; import org.fisco.bcos.sdk.config.model.NetworkConfig; import org.fisco.bcos.sdk.config.model.ThreadPoolConfig; import org.fisco.bcos.sdk.model.CryptoType; @@ -37,6 +38,7 @@ public class ConfigOption { private AmopConfig amopConfig; private NetworkConfig networkConfig; private ThreadPoolConfig threadPoolConfig; + private CryptoProviderConfig cryptoProviderConfig; private ConfigProperty configProperty; public ConfigOption(ConfigProperty configProperty) throws ConfigException { @@ -54,6 +56,8 @@ public ConfigOption(ConfigProperty configProperty, int cryptoType) throws Config networkConfig = new NetworkConfig(configProperty); // load threadPoolConfig threadPoolConfig = new ThreadPoolConfig(configProperty); + // load cryptoProviderConfig + cryptoProviderConfig = new CryptoProviderConfig(configProperty); // init configProperty this.configProperty = configProperty; } @@ -101,4 +105,12 @@ public ThreadPoolConfig getThreadPoolConfig() { public void setThreadPoolConfig(ThreadPoolConfig threadPoolConfig) { this.threadPoolConfig = threadPoolConfig; } + + public CryptoProviderConfig getCryptoProviderConfig() { + return cryptoProviderConfig; + } + + public void setCryptoProviderConfig(CryptoProviderConfig cryptoProviderConfig) { + this.cryptoProviderConfig = cryptoProviderConfig; + } } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/AccountConfig.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/AccountConfig.java index 257cb4f19..858b8b9d4 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/AccountConfig.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/AccountConfig.java @@ -15,6 +15,10 @@ package org.fisco.bcos.sdk.config.model; +import static org.fisco.bcos.sdk.model.CryptoProviderType.HSM; +import static org.fisco.bcos.sdk.model.CryptoProviderType.SSM; + +import java.util.Map; import java.util.Objects; import org.fisco.bcos.sdk.config.exceptions.ConfigException; @@ -25,6 +29,7 @@ public class AccountConfig { private String accountFileFormat; private String accountPassword; private String accountFilePath; + private String accountKeyIndex; public AccountConfig(ConfigProperty configProperty) throws ConfigException { this.keyStoreDir = @@ -38,13 +43,25 @@ public AccountConfig(ConfigProperty configProperty) throws ConfigException { this.accountPassword = ConfigProperty.getValue(configProperty.getAccount(), "password", ""); this.accountFilePath = ConfigProperty.getValue(configProperty.getAccount(), "accountFilePath", ""); + this.accountKeyIndex = + ConfigProperty.getValue(configProperty.getAccount(), "accountKeyIndex", ""); if (!this.accountFilePath.equals("")) { this.accountFilePath = ConfigProperty.getConfigFilePath(this.accountFilePath); } - checkAccountConfig(); - } - - private void checkAccountConfig() throws ConfigException { + checkAccountConfig(configProperty); + } + + private void checkAccountConfig(ConfigProperty configProperty) throws ConfigException { + Map cryptoProvider = configProperty.getCryptoProvider(); + if (cryptoProvider != null) { + String cryptoType = ConfigProperty.getValue(cryptoProvider, "type", SSM); + if (cryptoType != null && cryptoType.equals(HSM)) { + if (!this.accountKeyIndex.equals("") && this.accountPassword.equals("")) { + throw new ConfigException( + "cannot load hsm inner key, please config the password"); + } + } + } if (this.accountAddress.equals("")) { return; } @@ -97,6 +114,14 @@ public void setAccountPassword(String accountPassword) { this.accountPassword = accountPassword; } + public String getAccountKeyIndex() { + return accountKeyIndex; + } + + public void setAccountKeyIndex(String accountKeyIndex) { + this.accountKeyIndex = accountKeyIndex; + } + @Override public String toString() { return "AccountConfig{" diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java index c138dc705..e4b13051c 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java @@ -41,8 +41,8 @@ public class ConfigProperty { public Map network; public List amop; public Map account; - public Map threadPool; + public Map cryptoProvider; public Map getCryptoMaterial() { return cryptoMaterial; @@ -84,6 +84,14 @@ public void setThreadPool(Map threadPool) { this.threadPool = threadPool; } + public Map getCryptoProvider() { + return cryptoProvider; + } + + public void setCryptoProvider(Map cryptoProvider) { + this.cryptoProvider = cryptoProvider; + } + public static String getValue(Map config, String key, String defaultValue) { if (config == null || config.get(key) == null) { return defaultValue; diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/CryptoProviderConfig.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/CryptoProviderConfig.java new file mode 100644 index 000000000..896c1a082 --- /dev/null +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/CryptoProviderConfig.java @@ -0,0 +1,31 @@ +package org.fisco.bcos.sdk.config.model; + +import static org.fisco.bcos.sdk.model.CryptoProviderType.SSM; + +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CryptoProviderConfig { + private static Logger logger = LoggerFactory.getLogger(CryptoProviderConfig.class); + private String type; + + protected CryptoProviderConfig() {} + + public CryptoProviderConfig(ConfigProperty configProperty) { + Map cryptoProvider = configProperty.getCryptoProvider(); + if (cryptoProvider != null) { + this.type = ConfigProperty.getValue(cryptoProvider, "type", SSM); + } else { + type = SSM; + } + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoProviderType.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoProviderType.java new file mode 100644 index 000000000..a4bd31cc5 --- /dev/null +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoProviderType.java @@ -0,0 +1,6 @@ +package org.fisco.bcos.sdk.model; + +public class CryptoProviderType { + public static final String HSM = "hsm"; // Hardware secure module + public static final String SSM = "ssm"; // Software secure module +} diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoType.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoType.java index 73268ff29..f9a25369d 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoType.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoType.java @@ -22,4 +22,7 @@ public class CryptoType { // vrf related crypto type(1000-1999) public static final int ED25519_VRF_TYPE = 1000; + + // hardware secure module type (2000-2999) + public static final int SM_HSM_TYPE = 2001; } diff --git a/sdk-core/src/test/resources/config-example.toml b/sdk-core/src/test/resources/config-example.toml index 9eabf4f2f..8908eec18 100644 --- a/sdk-core/src/test/resources/config-example.toml +++ b/sdk-core/src/test/resources/config-example.toml @@ -1,5 +1,4 @@ [cryptoMaterial] - certPath = "conf" # The certification path # The following configurations take the certPath by default: diff --git a/sdk-crypto/build.gradle b/sdk-crypto/build.gradle index 959622886..574c22fd3 100644 --- a/sdk-crypto/build.gradle +++ b/sdk-crypto/build.gradle @@ -5,7 +5,8 @@ plugins { dependencies { compile project(':sdk-core') compile ("org.bouncycastle:bcprov-jdk15on:${bcprovJDK15onVersion}") - compile ("com.webank:key-mini-toolkit:${keyMiniToolkit}") + compile ("com.webank:webank-blockchain-java-crypto:${webankJavaCryptoVersion}") + compile ("com.webank:webank-blockchain-hsm-crypto:${webankHsmCryptoVersion}") } task sourcesJar(type: Jar) { diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/CryptoSuite.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/CryptoSuite.java index 6e356a566..60c552382 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/CryptoSuite.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/CryptoSuite.java @@ -13,21 +13,27 @@ */ package org.fisco.bcos.sdk.crypto; +import static org.fisco.bcos.sdk.model.CryptoProviderType.HSM; + import java.security.KeyPair; import org.fisco.bcos.sdk.config.ConfigOption; import org.fisco.bcos.sdk.config.model.AccountConfig; +import org.fisco.bcos.sdk.config.model.CryptoProviderConfig; import org.fisco.bcos.sdk.crypto.exceptions.LoadKeyStoreException; import org.fisco.bcos.sdk.crypto.exceptions.UnsupportedCryptoTypeException; import org.fisco.bcos.sdk.crypto.hash.Hash; import org.fisco.bcos.sdk.crypto.hash.Keccak256; +import org.fisco.bcos.sdk.crypto.hash.SDFSM3Hash; import org.fisco.bcos.sdk.crypto.hash.SM3Hash; import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair; import org.fisco.bcos.sdk.crypto.keypair.ECDSAKeyPair; +import org.fisco.bcos.sdk.crypto.keypair.SDFSM2KeyPair; import org.fisco.bcos.sdk.crypto.keypair.SM2KeyPair; import org.fisco.bcos.sdk.crypto.keystore.KeyTool; import org.fisco.bcos.sdk.crypto.keystore.P12KeyStore; import org.fisco.bcos.sdk.crypto.keystore.PEMKeyStore; import org.fisco.bcos.sdk.crypto.signature.ECDSASignature; +import org.fisco.bcos.sdk.crypto.signature.SDFSM2Signature; import org.fisco.bcos.sdk.crypto.signature.SM2Signature; import org.fisco.bcos.sdk.crypto.signature.Signature; import org.fisco.bcos.sdk.crypto.signature.SignatureResult; @@ -39,11 +45,10 @@ public class CryptoSuite { private static Logger logger = LoggerFactory.getLogger(CryptoSuite.class); - public final int cryptoTypeConfig; - - public final Signature signatureImpl; - public final Hash hashImpl; - private final CryptoKeyPair keyPairFactory; + public int cryptoTypeConfig; + public Signature signatureImpl; + public Hash hashImpl; + private CryptoKeyPair keyPairFactory; private CryptoKeyPair cryptoKeyPair; private ConfigOption config; @@ -63,11 +68,18 @@ public CryptoSuite(int cryptoTypeConfig, String hexedPrivateKey) { * @param configOption the configuration of account. */ public CryptoSuite(int cryptoTypeConfig, ConfigOption configOption) { - this(cryptoTypeConfig); - logger.info("init CryptoSuite, cryptoType: {}", cryptoTypeConfig); - setConfig(configOption); + this.config = configOption; + int cryptoType = cryptoTypeConfig; + if (cryptoTypeConfig == CryptoType.SM_TYPE) { + if (configOption != null + && configOption.getCryptoProviderConfig() != null + && configOption.getCryptoProviderConfig().getType().equals(HSM)) { + cryptoType = CryptoType.SM_HSM_TYPE; + } + } + initCryptoSuite(cryptoType); // doesn't set the account name, generate the keyPair randomly - if (!configOption.getAccountConfig().isAccountConfigured()) { + if (configOption == null || !configOption.getAccountConfig().isAccountConfigured()) { createKeyPair(); return; } @@ -80,29 +92,44 @@ public CryptoSuite(int cryptoTypeConfig, ConfigOption configOption) { * @param cryptoTypeConfig the crypto type config number */ public CryptoSuite(int cryptoTypeConfig) { - this.cryptoTypeConfig = cryptoTypeConfig; - if (this.cryptoTypeConfig == CryptoType.ECDSA_TYPE) { - this.signatureImpl = new ECDSASignature(); - this.hashImpl = new Keccak256(); - this.keyPairFactory = new ECDSAKeyPair(); + initCryptoSuite(cryptoTypeConfig); + } - } else if (this.cryptoTypeConfig == CryptoType.SM_TYPE) { + protected void initCryptoSuite(int cryptoTypeConfig) { + this.cryptoTypeConfig = cryptoTypeConfig; + if (cryptoTypeConfig == CryptoType.SM_TYPE) { this.signatureImpl = new SM2Signature(); this.hashImpl = new SM3Hash(); this.keyPairFactory = new SM2KeyPair(); - + } else if (cryptoTypeConfig == CryptoType.ECDSA_TYPE) { + this.signatureImpl = new ECDSASignature(); + this.hashImpl = new Keccak256(); + this.keyPairFactory = new ECDSAKeyPair(); + } else if (cryptoTypeConfig == CryptoType.SM_HSM_TYPE) { + this.signatureImpl = new SDFSM2Signature(); + this.hashImpl = new SDFSM3Hash(); + this.keyPairFactory = new SDFSM2KeyPair(); } else { throw new UnsupportedCryptoTypeException( "only support " + CryptoType.ECDSA_TYPE + "/" + CryptoType.SM_TYPE + + "/" + + CryptoType.SM_HSM_TYPE + " crypto type"); } // create keyPair randomly createKeyPair(); } + /** Load sdf internal account */ + public void loadSDFInternalAccount(String accountKeyIndex, String password) { + long index = Long.parseLong(accountKeyIndex); + SDFSM2KeyPair factory = (SDFSM2KeyPair) keyPairFactory; + SDFSM2KeyPair keyPair = factory.createKeyPair(index, password); + setCryptoKeyPair(keyPair); + } /** * Load account from file * @@ -133,6 +160,16 @@ public void loadAccount(String accountFileFormat, String accountFilePath, String */ private void loadAccount(ConfigOption configOption) { AccountConfig accountConfig = configOption.getAccountConfig(); + CryptoProviderConfig cryptoProviderConfig = config.getCryptoProviderConfig(); + String cryptoType = cryptoProviderConfig.getType(); + if (cryptoType != null && cryptoType.equals(HSM)) { + String accountKeyIndex = accountConfig.getAccountKeyIndex(); + if (accountKeyIndex != null && !accountKeyIndex.equals("")) { + loadSDFInternalAccount(accountKeyIndex, accountConfig.getAccountPassword()); + return; + } + } + String accountFilePath = accountConfig.getAccountFilePath(); if (accountFilePath == null || accountFilePath.equals("")) { if (accountConfig.getAccountFileFormat().compareToIgnoreCase("p12") == 0) { diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/Keccak256.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/Keccak256.java index 8456778da..dbb9daa33 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/Keccak256.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/Keccak256.java @@ -37,7 +37,7 @@ public String hashBytes(byte[] inputBytes) { public static String calculateHash(final byte[] inputBytes) { // Note: the exceptions should be handled by the caller - CryptoResult hashResult = NativeInterface.keccak256(Hex.toHexString(inputBytes)); + CryptoResult hashResult = NativeInterface.keccak256Hash(Hex.toHexString(inputBytes)); if (hashResult.wedprErrorMessage != null && !hashResult.wedprErrorMessage.isEmpty()) { throw new HashException( "Calculate hash with keccak256 failed! error message:" diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SDFSM3Hash.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SDFSM3Hash.java new file mode 100644 index 000000000..b12ec4723 --- /dev/null +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SDFSM3Hash.java @@ -0,0 +1,34 @@ +package org.fisco.bcos.sdk.crypto.hash; + +import com.webank.blockchain.hsm.crypto.sdf.AlgorithmType; +import com.webank.blockchain.hsm.crypto.sdf.SDF; +import com.webank.blockchain.hsm.crypto.sdf.SDFCryptoResult; +import org.fisco.bcos.sdk.crypto.exceptions.HashException; +import org.fisco.bcos.sdk.utils.Hex; + +public class SDFSM3Hash implements Hash { + @Override + public String hash(String inputData) { + return calculateHash(inputData.getBytes()); + } + + @Override + public String hashBytes(byte[] inputBytes) { + return calculateHash(inputBytes); + } + + @Override + public byte[] hash(byte[] inputBytes) { + return Hex.decode(calculateHash(inputBytes)); + } + + public static String calculateHash(final byte[] inputBytes) { + SDFCryptoResult hashResult = SDF.Hash(null, AlgorithmType.SM3, Hex.toHexString(inputBytes)); + if (hashResult.getSdfErrorMessage() != null && !hashResult.getSdfErrorMessage().isEmpty()) { + throw new HashException( + "calculate hash with sdf sm3 failed, error message:" + + hashResult.getSdfErrorMessage()); + } + return hashResult.getHash(); + } +} diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SM3Hash.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SM3Hash.java index 46b05aaeb..f9ca36325 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SM3Hash.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/hash/SM3Hash.java @@ -36,7 +36,7 @@ public byte[] hash(final byte[] inputBytes) { } public static String calculateHash(final byte[] inputBytes) { - CryptoResult hashResult = NativeInterface.sm3(Hex.toHexString(inputBytes)); + CryptoResult hashResult = NativeInterface.sm3Hash(Hex.toHexString(inputBytes)); // call sm3 failed if (hashResult.wedprErrorMessage != null && !hashResult.wedprErrorMessage.isEmpty()) { throw new HashException( diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java index 7e8e689f6..ad7ffb4c7 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java @@ -87,7 +87,7 @@ public CryptoKeyPair(KeyPair keyPair) { * @param nativeResult */ CryptoKeyPair(final CryptoResult nativeResult) { - this.hexPrivateKey = nativeResult.privteKey; + this.hexPrivateKey = nativeResult.privateKey; this.hexPublicKey = nativeResult.publicKey; } diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/ECDSAKeyPair.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/ECDSAKeyPair.java index d95a2d316..173425bc6 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/ECDSAKeyPair.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/ECDSAKeyPair.java @@ -53,7 +53,7 @@ private void initECDSAKeyPair() { } public static CryptoKeyPair createKeyPair() { - return new ECDSAKeyPair(NativeInterface.secp256k1keyPair()); + return new ECDSAKeyPair(NativeInterface.secp256k1GenKeyPair()); } /** @@ -63,7 +63,7 @@ public static CryptoKeyPair createKeyPair() { */ @Override public CryptoKeyPair generateKeyPair() { - return new ECDSAKeyPair(NativeInterface.secp256k1keyPair()); + return new ECDSAKeyPair(NativeInterface.secp256k1GenKeyPair()); } @Override diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java new file mode 100644 index 000000000..b31f0588d --- /dev/null +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java @@ -0,0 +1,123 @@ +package org.fisco.bcos.sdk.crypto.keypair; + +import com.webank.blockchain.hsm.crypto.sdf.AlgorithmType; +import com.webank.blockchain.hsm.crypto.sdf.SDF; +import com.webank.blockchain.hsm.crypto.sdf.SDFCryptoResult; +import com.webank.wedpr.crypto.CryptoResult; +import java.math.BigInteger; +import java.security.KeyPair; +import org.fisco.bcos.sdk.crypto.exceptions.KeyPairException; +import org.fisco.bcos.sdk.crypto.exceptions.SignatureException; +import org.fisco.bcos.sdk.crypto.hash.Hash; +import org.fisco.bcos.sdk.crypto.hash.SDFSM3Hash; +import org.fisco.bcos.sdk.crypto.keystore.KeyTool; +import org.fisco.bcos.sdk.utils.Hex; +import org.fisco.bcos.sdk.utils.Numeric; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SDFSM2KeyPair extends CryptoKeyPair { + protected static Logger logger = LoggerFactory.getLogger(SDFSM2KeyPair.class); + public static Hash DefaultHashAlgorithm = new SDFSM3Hash(); + public long keyIndex; + public String password; + public boolean isInternalKey = false; + + public SDFSM2KeyPair() { + initSM2KeyPairObject(); + CryptoKeyPair keyPair = this.generateKeyPair(); + this.hexPrivateKey = keyPair.getHexPrivateKey(); + this.hexPublicKey = keyPair.getHexPublicKey(); + this.keyPair = KeyTool.convertHexedStringToKeyPair(this.hexPrivateKey, curveName); + } + + public SDFSM2KeyPair(KeyPair javaKeyPair) { + super(javaKeyPair); + initSM2KeyPairObject(); + } + + protected SDFSM2KeyPair(CryptoResult result) { + super(result); + initSM2KeyPairObject(); + this.keyPair = KeyTool.convertHexedStringToKeyPair(this.hexPrivateKey, curveName); + } + + protected SDFSM2KeyPair(long keyIndex, String password) { + initSM2KeyPairObject(); + this.keyIndex = keyIndex; + this.password = password; + SDFCryptoResult pkResult = SDF.ExportInternalPublicKey(keyIndex, AlgorithmType.SM2); + if (pkResult.getSdfErrorMessage() != null && !pkResult.getSdfErrorMessage().equals("")) { + throw new KeyPairException( + "get sdf sm2 internal key public key failed:" + pkResult.getSdfErrorMessage()); + } + this.hexPublicKey = + Numeric.getHexKeyWithPrefix( + pkResult.getPublicKey(), + CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, + CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX); + this.isInternalKey = true; + } + + private void initSM2KeyPairObject() { + this.keyStoreSubDir = GM_ACCOUNT_SUBDIR; + this.hashImpl = new SDFSM3Hash(); + this.curveName = CryptoKeyPair.SM2_CURVE_NAME; + this.signatureAlgorithm = SM_SIGNATURE_ALGORITHM; + } + + @Override + public CryptoKeyPair generateKeyPair() { + SDFCryptoResult sdfResult = SDF.KeyGen(AlgorithmType.SM2); + checkSDFCryptoResult(sdfResult); + CryptoResult result = new CryptoResult(); + result.privateKey = sdfResult.getPrivateKey(); + result.publicKey = + Numeric.getHexKeyWithPrefix( + sdfResult.getPublicKey(), + CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, + CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX); + return new SDFSM2KeyPair(result); + } + + public static void checkSDFCryptoResult(SDFCryptoResult result) { + if (result.getSdfErrorMessage() != null && !result.getSdfErrorMessage().isEmpty()) { + throw new SignatureException("Sign with sdf sm2 failed:" + result.getSdfErrorMessage()); + } + } + + @Override + public CryptoKeyPair createKeyPair(KeyPair keyPair) { + return new SDFSM2KeyPair(keyPair); + } + + public SDFSM2KeyPair createKeyPair(long keyIndex, String password) { + return new SDFSM2KeyPair(keyIndex, password); + } + + public boolean isInternalKey() { + return isInternalKey; + } + + public long getKeyIndex() { + return keyIndex; + } + + public String getPassword() { + return password; + } + + public static String getAddressByPublicKey(String publicKey) { + return getAddress(publicKey, SDFSM2KeyPair.DefaultHashAlgorithm); + } + + public static byte[] getAddressByPublicKey(byte[] publicKey) { + return Hex.decode( + Numeric.cleanHexPrefix(getAddressByPublicKey(Hex.toHexString(publicKey)))); + } + + public static byte[] getAddressByPublicKey(BigInteger publicKey) { + byte[] publicKeyBytes = Numeric.toBytesPadded(publicKey, PUBLIC_KEY_SIZE); + return getAddressByPublicKey(publicKeyBytes); + } +} diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SM2KeyPair.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SM2KeyPair.java index 5a095a53d..3039e9764 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SM2KeyPair.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SM2KeyPair.java @@ -53,7 +53,7 @@ private void initSM2KeyPairObject() { } public static CryptoKeyPair createKeyPair() { - return new SM2KeyPair(NativeInterface.sm2keyPair()); + return new SM2KeyPair(NativeInterface.sm2GenKeyPair()); } /** @@ -63,7 +63,7 @@ public static CryptoKeyPair createKeyPair() { */ @Override public CryptoKeyPair generateKeyPair() { - return new SM2KeyPair(NativeInterface.sm2keyPair()); + return new SM2KeyPair(NativeInterface.sm2GenKeyPair()); } @Override diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/ECDSASignature.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/ECDSASignature.java index 9e77f52e5..7c4b16596 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/ECDSASignature.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/ECDSASignature.java @@ -80,12 +80,12 @@ public static boolean verifyMessage(String publicKey, String message, String sig CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX); CryptoResult verifyResult = - NativeInterface.secp256k1verify(hexPubKeyWithPrefix, inputMessage, signature); + NativeInterface.secp256k1Verify(hexPubKeyWithPrefix, inputMessage, signature); // call secp256k1verify failed if (verifyResult.wedprErrorMessage != null && !verifyResult.wedprErrorMessage.isEmpty()) { throw new SignatureException( "Verify with secp256k1 failed:" + verifyResult.wedprErrorMessage); } - return verifyResult.result; + return verifyResult.booleanResult; } } diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java new file mode 100644 index 000000000..95aab9c97 --- /dev/null +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java @@ -0,0 +1,107 @@ +package org.fisco.bcos.sdk.crypto.signature; + +import static org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX; +import static org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR; + +import com.webank.blockchain.hsm.crypto.sdf.AlgorithmType; +import com.webank.blockchain.hsm.crypto.sdf.SDF; +import com.webank.blockchain.hsm.crypto.sdf.SDFCryptoResult; +import com.webank.wedpr.crypto.CryptoResult; +import com.webank.wedpr.crypto.NativeInterface; +import org.fisco.bcos.sdk.crypto.exceptions.SignatureException; +import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.crypto.keypair.SDFSM2KeyPair; +import org.fisco.bcos.sdk.utils.Hex; +import org.fisco.bcos.sdk.utils.Numeric; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SDFSM2Signature implements Signature { + private static Logger logger = LoggerFactory.getLogger(SDFSM2Signature.class); + + @Override + public SignatureResult sign(final String message, final CryptoKeyPair keyPair) { + return new SM2SignatureResult( + keyPair.getHexPublicKey(), signWithStringSignature(message, keyPair)); + } + + @Override + public SignatureResult sign(final byte[] message, final CryptoKeyPair keyPair) { + return sign(Hex.toHexString(message), keyPair); + } + + @Override + public String signWithStringSignature(final String message, final CryptoKeyPair keyPair) { + return signMessage(message, keyPair); + } + + public String signMessage(String message, CryptoKeyPair keyPair) { + CryptoResult hashResult = + NativeInterface.sm2ComputeHashE( + Numeric.cleanHexPrefix(keyPair.getHexPublicKey()), + Numeric.cleanHexPrefix(message)); + checkCryptoResult(hashResult); + SDFCryptoResult signatureResult; + if (keyPair instanceof SDFSM2KeyPair) { + SDFSM2KeyPair sdfKeyPair = (SDFSM2KeyPair) keyPair; + if (sdfKeyPair.isInternalKey()) { + signatureResult = + SDF.SignWithInternalKey( + sdfKeyPair.getKeyIndex(), + sdfKeyPair.getPassword(), + AlgorithmType.SM2, + hashResult.hash); + checkSDFCryptoResult(signatureResult); + return signatureResult.getSignature(); + } + } + signatureResult = + SDF.Sign( + Numeric.cleanHexPrefix(keyPair.getHexPrivateKey()), + AlgorithmType.SM2, + hashResult.hash); + + checkSDFCryptoResult(signatureResult); + return signatureResult.getSignature(); + } + + public static void checkCryptoResult(CryptoResult result) { + if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) { + throw new SignatureException("Sign with sdf sm2 failed:" + result.wedprErrorMessage); + } + } + + public static void checkSDFCryptoResult(SDFCryptoResult result) { + if (result.getSdfErrorMessage() != null && !result.getSdfErrorMessage().isEmpty()) { + throw new SignatureException("Sign with sdf sm2 failed:" + result.getSdfErrorMessage()); + } + } + + @Override + public boolean verify(String publicKey, String message, String signature) { + return verifyMessage(publicKey, message, signature); + } + + @Override + public boolean verify(String publicKey, byte[] message, byte[] signature) { + return verify(publicKey, Hex.toHexString(message), Hex.toHexString(signature)); + } + + public static boolean verifyMessage(String publicKey, String message, String signature) { + CryptoResult hashResult = + NativeInterface.sm2ComputeHashE( + Numeric.cleanHexPrefix(publicKey), Numeric.cleanHexPrefix(message)); + checkCryptoResult(hashResult); + SDFCryptoResult verifyResult = + SDF.Verify( + Numeric.getKeyNoPrefix( + UNCOMPRESSED_PUBLICKEY_FLAG_STR, + publicKey, + PUBLIC_KEY_LENGTH_IN_HEX), + AlgorithmType.SM2, + hashResult.hash, + Numeric.cleanHexPrefix(signature)); + checkSDFCryptoResult(verifyResult); + return verifyResult.getResult(); + } +} diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java index 2016c9310..fcd6d93be 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java @@ -39,7 +39,7 @@ public String signWithStringSignature(final String message, final CryptoKeyPair public String signMessage(String message, CryptoKeyPair keyPair) { CryptoResult signatureResult = - NativeInterface.sm2SignWithPub( + NativeInterface.sm2SignFast( keyPair.getHexPrivateKey(), keyPair.getHexPublicKey(), Numeric.cleanHexPrefix(message)); @@ -68,12 +68,12 @@ public static boolean verifyMessage(String publicKey, String message, String sig CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX); CryptoResult verifyResult = - NativeInterface.sm2verify( + NativeInterface.sm2Verify( hexPubKeyWithPrefix, Numeric.cleanHexPrefix(message), signature); if (verifyResult.wedprErrorMessage != null && !verifyResult.wedprErrorMessage.isEmpty()) { throw new SignatureException( "Verify with sm2 failed:" + verifyResult.wedprErrorMessage); } - return verifyResult.result; + return verifyResult.booleanResult; } } diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/vrf/Curve25519VRF.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/vrf/Curve25519VRF.java index d209d9721..c4d80226c 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/vrf/Curve25519VRF.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/vrf/Curve25519VRF.java @@ -34,7 +34,7 @@ public VRFKeyPair createKeyPair() { @Override public String generateVRFProof(String privateKey, String vrfInput) { CryptoResult result = - NativeInterface.curve25519GenVRFProof( + NativeInterface.curve25519VrfProveUtf8( Numeric.getKeyNoPrefix( CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, privateKey, @@ -48,17 +48,18 @@ public String generateVRFProof(String privateKey, String vrfInput) { @Override public boolean verify(String publicKey, String vrfInput, String vrfProof) { - CryptoResult result = NativeInterface.curve25519VRFVerify(publicKey, vrfInput, vrfProof); + CryptoResult result = + NativeInterface.curve25519VrfVerifyUtf8(publicKey, vrfInput, vrfProof); if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) { - throw new VRFException("verify VRF Proof failed: " + result.wedprErrorMessage); + return false; } - return result.vrfVerifyResult; + return result.booleanResult; } @Override public String getPublicKeyFromPrivateKey(String privateKey) { CryptoResult result = - NativeInterface.curve25519VRFGetPubKeyFromPrivateKey( + NativeInterface.curve25519VrfDerivePublicKey( Numeric.getKeyNoPrefix( CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, privateKey, @@ -66,16 +67,16 @@ public String getPublicKeyFromPrivateKey(String privateKey) { if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) { throw new VRFException("get VRF Proof failed: " + result.wedprErrorMessage); } - return result.vrfPublicKey; + return result.publicKey; } @Override public String vrfProofToHash(String vrfProof) { - CryptoResult result = NativeInterface.curve25519VRFProofToHash(vrfProof); + CryptoResult result = NativeInterface.curve25519VrfProofToHash(vrfProof); if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) { throw new VRFException("convert VRF Proof to hash failed:" + result.wedprErrorMessage); } - return result.vrfHash; + return result.hash; } @Override @@ -85,10 +86,10 @@ public BigInteger vrfProofToRandomValue(String vrfProof) { @Override public boolean isValidVRFPublicKey(String vrfPublicKey) { - CryptoResult result = NativeInterface.curve25519IsValidVRFPubKey(vrfPublicKey); + CryptoResult result = NativeInterface.curve25519VrfIsValidPublicKey(vrfPublicKey); if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) { - throw new VRFException("invalid VRF public key:" + result.wedprErrorMessage); + return false; } - return result.isValidVRFPublicKey; + return result.booleanResult; } } diff --git a/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/Curve25519VRFTest.java b/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/Curve25519VRFTest.java index d19862c99..4738be070 100644 --- a/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/Curve25519VRFTest.java +++ b/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/Curve25519VRFTest.java @@ -57,6 +57,7 @@ public void testCurve25519VRFProve(VRFInterface vrfInterface, String privateKey, public void testCurve25519VRFProve(VRFInterface vrfInterface, String privateKey, String vrfInput, String fakePrivateKey) { // valid case + System.out.println(privateKey); String publicKey = vrfInterface.getPublicKeyFromPrivateKey(privateKey); Assert.assertTrue(vrfInterface.isValidVRFPublicKey(publicKey)); diff --git a/sdk-crypto/src/test/resources/config.toml b/sdk-crypto/src/test/resources/config.toml index 9eabf4f2f..46c7161d5 100644 --- a/sdk-crypto/src/test/resources/config.toml +++ b/sdk-crypto/src/test/resources/config.toml @@ -1,5 +1,5 @@ [cryptoMaterial] - +provider = "sw" certPath = "conf" # The certification path # The following configurations take the certPath by default: diff --git a/src/test/resources/config-example.toml b/src/test/resources/config-example.toml index dc38a0dee..59f069b45 100644 --- a/src/test/resources/config-example.toml +++ b/src/test/resources/config-example.toml @@ -1,5 +1,4 @@ [cryptoMaterial] - certPath = "conf" # The certification path # The following configurations take the certPath by default if commented diff --git a/src/test/resources/config-hsm-example.toml b/src/test/resources/config-hsm-example.toml new file mode 100644 index 000000000..f6fcb98a4 --- /dev/null +++ b/src/test/resources/config-hsm-example.toml @@ -0,0 +1,65 @@ +[cryptoMaterial] +certPath = "conf" # The certification path + +# The following configurations take the certPath by default if commented +# caCert = "conf/ca.crt" # CA cert file path +# If connect to the GM node, default CA cert path is ${certPath}/gm/gmca.crt + +# sslCert = "conf/sdk.crt" # SSL cert file path +# If connect to the GM node, the default SDK cert path is ${certPath}/gm/gmsdk.crt + +# sslKey = "conf/sdk.key" # SSL key file path +# If connect to the GM node, the default SDK privateKey path is ${certPath}/gm/gmsdk.key + +# enSslCert = "conf/gm/gmensdk.crt" # GM encryption cert file path +# default load the GM SSL encryption cert from ${certPath}/gm/gmensdk.crt + +# enSslKey = "conf/gm/gmensdk.key" # GM ssl cert file path +# default load the GM SSL encryption privateKey from ${certPath}/gm/gmensdk.key + +[cryptoProvider] +type = "hsm" # hsm: hard ware crypto device, by default sm algorithms use sdf standard, others use pkcs11 stantdard + # server: crypto server + +[network] +peers=["127.0.0.1:20200", "127.0.0.1:20201"] # The peer list to connect + +# AMOP configuration +# You can use following two methods to configure as a private topic message sender or subscriber. +# Usually, the public key and private key is generated by subscriber. +# Message sender receive public key from topic subscriber then make configuration. +# But, please do not config as both the message sender and the subscriber of one private topic, or you may send the message to yourself. + +# Configure a private topic as a topic message sender. +# [[amop]] +# topicName = "PrivateTopic" +# publicKeys = [ "conf/amop/consumer_public_key_1.pem" ] # Public keys of the nodes that you want to send AMOP message of this topic to. + +# Configure a private topic as a topic subscriber. +# [[amop]] +# topicName = "PrivateTopic" +# privateKey = "conf/amop/consumer_private_key.p12" # Your private key that used to subscriber verification. +# password = "123456" + +[account] +# keyStoreDir = "account" # The directory to load/store the account file, default is "account" +# accountFilePath = "" # The account file path (default load from the path specified by the keyStoreDir) +# accountFileFormat = "pem" # The storage format of account file (Default is "pem", "p12" as an option) + +# accountAddress = "" # The transactions sending account address +# Default is a randomly generated account +# The randomly generated account is stored in the path specified by the keyStoreDir + +# password = "" # The password used to load the account file +accountKeyIndex = "2" # If use hardware inner key, please config the key index and password +password = "123456" # If use hardware inner key, please config the key index and password + +[threadPool] +# channelProcessorThreadSize = "16" # The size of the thread pool to process channel callback +# Default is the number of cpu cores + +# receiptProcessorThreadSize = "16" # The size of the thread pool to process transaction receipt notification +# Default is the number of cpu cores + +maxBlockingQueueSize = "102400" # The max blocking queue size of the thread pool + From 874a00b776fdee86e0a224fafd9f9cc24bb219c0 Mon Sep 17 00:00:00 2001 From: cyjseagull <1547158861@qq.com> Date: Tue, 20 Apr 2021 10:11:47 +0800 Subject: [PATCH 02/11] fix serialize ABIDefinition with fallback failed && support (#302) fallback/receive functions --- .../bcos/sdk/abi/wrapper/ABIDefinition.java | 50 ++++++++++++--- .../sdk/abi/wrapper/ABIDefinitionFactory.java | 23 +++++-- .../abi/wrapper/ContractABIDefinition.java | 26 ++++++++ .../fisco/bcos/sdk/test/abi/ABICodecTest.java | 64 ++++++++++++++++++- .../fisco/bcos/sdk/network/NetworkImp.java | 8 ++- .../bcos/sdk/crypto/keystore/KeyTool.java | 2 +- 6 files changed, 155 insertions(+), 18 deletions(-) diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinition.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinition.java index 4809822ac..1b6abfd3f 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinition.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinition.java @@ -1,5 +1,7 @@ package org.fisco.bcos.sdk.abi.wrapper; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -26,16 +28,38 @@ * blockchain state), view (specified to not modify the blockchain state), nonpayable (function does * not accept Ether - the default) and payable (function accepts Ether).
*/ +@JsonIgnoreProperties(ignoreUnknown = true) public class ABIDefinition { + public static final String CONSTRUCTOR_TYPE = "constructor"; + public static final String FUNCTION_TYPE = "function"; + public static final String EVENT_TYPE = "event"; + public static final String FALLBACK_TYPE = "fallback"; + public static final String RECEIVE_TYPE = "receive"; + + @JsonProperty("name") private String name; + + @JsonProperty("type") private String type; + + @JsonProperty("constant") private boolean constant; + + @JsonProperty("payable") private boolean payable; + + @JsonProperty("anonymous") private boolean anonymous; + + @JsonProperty("stateMutability") private String stateMutability; + @JsonProperty("inputs") private List inputs; + + @JsonProperty("outputs") private List outputs; + public static List CONSTANT_KEY = Arrays.asList("view"); public ABIDefinition() {} @@ -94,14 +118,19 @@ public static ABIDefinition createDefaultConstructorABIDefinition() { */ public String getMethodSignatureAsString() { StringBuilder result = new StringBuilder(); - result.append(name); + // Fix: the name field of the fallback is empty + if (name != null) { + result.append(name); + } result.append("("); - String params = - getInputs() - .stream() - .map(abi -> abi.getTypeAsString()) - .collect(Collectors.joining(",")); - result.append(params); + if (getInputs() != null) { + String params = + getInputs() + .stream() + .map(abi -> abi.getTypeAsString()) + .collect(Collectors.joining(",")); + result.append(params); + } result.append(")"); return result.toString(); } @@ -113,8 +142,11 @@ public String getMethodSignatureAsString() { * @return the method id */ public String getMethodId(CryptoSuite cryptoSuite) { - FunctionEncoder encoder = new FunctionEncoder(cryptoSuite); - return encoder.buildMethodId(getMethodSignatureAsString()); + if (getType().equals(ABIDefinition.FUNCTION_TYPE)) { + FunctionEncoder encoder = new FunctionEncoder(cryptoSuite); + return encoder.buildMethodId(getMethodSignatureAsString()); + } + return ""; } public boolean isConstant() { diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinitionFactory.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinitionFactory.java index f5738ac0f..9072b530e 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinitionFactory.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ABIDefinitionFactory.java @@ -1,12 +1,12 @@ package org.fisco.bcos.sdk.abi.wrapper; +import org.fisco.bcos.sdk.abi.ABICodecException; import org.fisco.bcos.sdk.crypto.CryptoSuite; import org.fisco.bcos.sdk.utils.ObjectMapperFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ABIDefinitionFactory { - private static final Logger logger = LoggerFactory.getLogger(ABIDefinitionFactory.class); private CryptoSuite cryptoSuite; @@ -28,12 +28,27 @@ public ContractABIDefinition loadABI(String abi) { ContractABIDefinition contractABIDefinition = new ContractABIDefinition(cryptoSuite); for (ABIDefinition abiDefinition : abiDefinitions) { - if (abiDefinition.getType().equals("constructor")) { + if (abiDefinition.getType().equals(ABIDefinition.CONSTRUCTOR_TYPE)) { contractABIDefinition.setConstructor(abiDefinition); - } else if (abiDefinition.getType().equals("function")) { + } else if (abiDefinition.getType().equals(ABIDefinition.FUNCTION_TYPE)) { contractABIDefinition.addFunction(abiDefinition.getName(), abiDefinition); - } else if (abiDefinition.getType().equals("event")) { + } else if (abiDefinition.getType().equals(ABIDefinition.EVENT_TYPE)) { contractABIDefinition.addEvent(abiDefinition.getName(), abiDefinition); + } else if (abiDefinition.getType().equals(ABIDefinition.FALLBACK_TYPE)) { + if (contractABIDefinition.hasFallbackFunction()) { + throw new ABICodecException("only single fallback is allowed"); + } + contractABIDefinition.setFallbackFunction(abiDefinition); + } else if (abiDefinition.getType().equals(ABIDefinition.RECEIVE_TYPE)) { + if (contractABIDefinition.hasReceiveFunction()) { + throw new ABICodecException("only single receive is allowed"); + } + if (abiDefinition.getStateMutability().equals("payable") == false + && abiDefinition.isPayable() == false) { + throw new ABICodecException( + "the statemutability of receive can only be payable"); + } + contractABIDefinition.setReceiveFunction(abiDefinition); } else { // skip and do nothing } diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java index a8b9fc9cb..e5244c78d 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/wrapper/ContractABIDefinition.java @@ -18,6 +18,8 @@ public class ContractABIDefinition { private Map> events = new HashMap<>(); // method id => function private Map methodIDToFunctions = new HashMap<>(); + private ABIDefinition fallbackFunction; + private ABIDefinition receiveFunction; // event topic => topic private Map eventTopicToEvents = new HashMap<>(); private CryptoSuite cryptoSuite; @@ -107,4 +109,28 @@ public ABIDefinition getABIDefinitionByMethodId(String methodId) { public ABIDefinition getABIDefinitionByEventTopic(String topic) { return eventTopicToEvents.get(Numeric.prependHexPrefix(topic)); } + + public ABIDefinition getFallbackFunction() { + return fallbackFunction; + } + + public void setFallbackFunction(ABIDefinition fallbackFunction) { + this.fallbackFunction = fallbackFunction; + } + + public boolean hasFallbackFunction() { + return this.fallbackFunction != null; + } + + public boolean hasReceiveFunction() { + return this.receiveFunction != null; + } + + public ABIDefinition getReceiveFunction() { + return receiveFunction; + } + + public void setReceiveFunction(ABIDefinition receiveFunction) { + this.receiveFunction = receiveFunction; + } } diff --git a/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java b/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java index 3fb9a37b0..a02fd1ba8 100644 --- a/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java +++ b/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java @@ -1,15 +1,24 @@ package org.fisco.bcos.sdk.test.abi; +import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.fisco.bcos.sdk.abi.ABICodec; import org.fisco.bcos.sdk.abi.ABICodecException; import org.fisco.bcos.sdk.abi.wrapper.ABICodecObject; import org.fisco.bcos.sdk.abi.wrapper.ABIDefinition; +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinitionFactory; import org.fisco.bcos.sdk.abi.wrapper.ABIObject; import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; +import org.fisco.bcos.sdk.crypto.CryptoSuite; +import org.fisco.bcos.sdk.model.CryptoType; +import org.fisco.bcos.sdk.utils.ObjectMapperFactory; import org.junit.Assert; import org.junit.Test; @@ -227,9 +236,13 @@ public class ABICodecTest { + " \"payable\": false,\n" + " \"stateMutability\": \"nonpayable\",\n" + " \"type\": \"fallback\"\n" + + " },\n" + + " {\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"payable\",\n" + + " \"type\": \"receive\"\n" + " }\n" + "]"; - // int a, Info[] memory b, string memory c /* * { @@ -291,7 +304,40 @@ function test(int a, Info[] memory b, string memory c) public returns(int) { private String encodedWithMethodId = "0x00a3c75d" + encoded; @Test - public void testEncodeFromString() { + public void testEncodeFromString() throws IOException { + CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE); + ABIDefinitionFactory abiDefinitionFactory = new ABIDefinitionFactory(cryptoSuite); + ContractABIDefinition abiDefinition = abiDefinitionFactory.loadABI(abiDesc); + // check the fallback function + Assert.assertTrue(abiDefinition.getFallbackFunction() != null); + // check the content of the fallback function + Assert.assertTrue(abiDefinition.getFallbackFunction().getStateMutability().equals( "nonpayable")); + Assert.assertTrue(abiDefinition.getFallbackFunction().isPayable() == false); + Assert.assertTrue(abiDefinition.getFallbackFunction().getType().equals("fallback")); + + // check receive functions + Assert.assertTrue(abiDefinition.getReceiveFunction() != null); + Assert.assertTrue(abiDefinition.getReceiveFunction().getType().equals("receive")); + + // check serialization and deserialization + ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + byte[] encodedABIDefinitions = objectMapper.writeValueAsBytes(abiDefinition.getFallbackFunction()); + // decode + ABIDefinition decodedABIDefinition = objectMapper.readValue(encodedABIDefinitions, ABIDefinition.class); + Assert.assertTrue(decodedABIDefinition.getStateMutability().equals( "nonpayable")); + Assert.assertTrue(decodedABIDefinition.isPayable() == false); + Assert.assertTrue(decodedABIDefinition.getType().equals("fallback")); + // test encode/decode for all the functions + for(String key : abiDefinition.getFunctions().keySet()) + { + List abiDefinitions = abiDefinition.getFunctions().get(key); + for(int i = 0; i < abiDefinitions.size(); i++) { + ABIDefinition functionAbiDefinition = abiDefinitions.get(i); + encodedABIDefinitions = objectMapper.writeValueAsBytes(functionAbiDefinition); + decodedABIDefinition = objectMapper.readValue(encodedABIDefinitions, ABIDefinition.class); + } + } + List args = new ArrayList(); args.add("100"); // [{"name": "Hello world!", "count": 100, "items": [{"a": 1, "b": 2, "c": 3}]}, {"name": @@ -401,9 +447,21 @@ public void testEncodeByInterface() { argsObjects.add(a); try { String s1 = abiCodec.encodeMethodByInterface("call(uint256[2],uint256[],bytes,address)", argsObjects); - String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"u1\",\"type\":\"uint256[2]\"},{\"name\":\"u2\",\"type\":\"uint256[]\"},{\"name\":\"b\",\"type\":\"bytes\"},{\"name\":\"a\",\"type\":\"address\"}],\"name\":\"call\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"u\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"},{\"name\":\"s\",\"type\":\"string\"}],\"name\":\"add\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"s\",\"type\":\"string\"}],\"name\":\"LogAdd3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd4\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd5\",\"type\":\"event\"}]"; + String abi = "[{\"inputs\":[{\"name\":\"u1\",\"type\":\"uint256[2]\"},{\"name\":\"u2\",\"type\":\"uint256[]\"},{\"name\":\"b\",\"type\":\"bytes\"},{\"name\":\"a\",\"type\":\"address\"}],\"name\":\"call\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"u\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"},{\"name\":\"s\",\"type\":\"string\"}],\"name\":\"add\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"s\",\"type\":\"string\"}],\"name\":\"LogAdd3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd4\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd5\",\"type\":\"event\"}]"; String s2 = abiCodec.encodeMethod(abi, "call", argsObjects); Assert.assertEquals(s1, s2); + // test ABIDefinition + // check constant + CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE); + ABIDefinitionFactory abiDefinitionFactory = new ABIDefinitionFactory(cryptoSuite); + ContractABIDefinition abiDefinition = abiDefinitionFactory.loadABI(abi); + Map> functions = abiDefinition.getFunctions(); + Assert.assertTrue(functions.containsKey("call")); + List callABIDefinition = functions.get("call"); + Assert.assertEquals(1, callABIDefinition.size()); + Assert.assertTrue(callABIDefinition.get(0).isConstant()); + // check without + } catch (ABICodecException e) { Assert.fail(e.getMessage()); } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java index 5f71488ae..28d14a829 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java @@ -154,6 +154,7 @@ public void start() throws NetworkException { boolean tryEcdsaConnect = false; CheckCertExistenceResult result = null; String ecdsaCryptoInfo = configOption.getCryptoMaterialConfig().toString(); + String ecdsaErrorMessage = ""; try { try { result = checkCertExistence(false); @@ -186,6 +187,7 @@ public void start() throws NetworkException { } // means that all the ECDSA certificates exist tryEcdsaConnect = true; + ecdsaErrorMessage += e.getMessage(); connManager.stopNetty(); logger.debug( "start connManager with the ECDSA sslContext failed, try to use SM sslContext, error info: {}", @@ -197,7 +199,11 @@ public void start() throws NetworkException { if (!result.isCheckPassed()) { if (tryEcdsaConnect) { String errorMessage = - "\n* Try init the sslContext failed.\n\n* If your blockchain channel config is NON-SM, please provide the NON-SM certificates: " + "\n* Try init the NON-SM sslContext failed and the SM certificates are incomplete . error info: \n" + + ecdsaErrorMessage; + + errorMessage += + "\n* If your blockchain channel config is NON-SM, please provide the NON-SM certificates: " + ecdsaCryptoInfo + ".\n"; errorMessage += diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java index 6420d5716..aad967a97 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java @@ -306,7 +306,7 @@ private static Method getMethod( try { return ec5UtilClass.getDeclaredMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { - logger.warn("get method for EC5Util failed, method name: {}", methodName); + logger.debug("try to get method for EC5Util failed, method name: {}", methodName); return null; } } From 8d04737f4effcb7176955b2646b4d2af87ce9689 Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Fri, 8 Oct 2021 16:05:38 +0800 Subject: [PATCH 03/11] fix ci_check --- .ci/ci_check.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/ci_check.sh b/.ci/ci_check.sh index 0f3c2d2e4..9706112c6 100755 --- a/.ci/ci_check.sh +++ b/.ci/ci_check.sh @@ -1,6 +1,7 @@ #!/bin/bash set -e +tag="v2.8.0" LOG_INFO() { local content=${1} echo -e "\033[32m ${content}\033[0m" @@ -28,7 +29,6 @@ download_tassl() download_build_chain() { - tag=$(curl -sS "https://gitee.com/api/v5/repos/FISCO-BCOS/FISCO-BCOS/tags" | grep -oe "\"name\":\"v[2-9]*\.[0-9]*\.[0-9]*\"" | cut -d \" -f 4 | sort -V | tail -n 1) LOG_INFO "--- current tag: $tag" curl -LO "https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/${tag}/build_chain.sh" && chmod u+x build_chain.sh } From 54757b96ed42178347c60fc3b95eb6809f50c911 Mon Sep 17 00:00:00 2001 From: cyjseagull <1547158861@qq.com> Date: Fri, 8 Oct 2021 20:38:58 +0800 Subject: [PATCH 04/11] add decodeTransactionInput to ABICodec (#360) --- .ci/ci_check.sh | 2 +- build.gradle | 2 +- .../java/org/fisco/bcos/sdk/abi/ABICodec.java | 56 +++++++++++++++++-- .../decode/TransactionDecoderService.java | 9 +++ .../model/dto/TransactionResponse.java | 28 ++++++++++ 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/.ci/ci_check.sh b/.ci/ci_check.sh index 9706112c6..733889e36 100755 --- a/.ci/ci_check.sh +++ b/.ci/ci_check.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -tag="v2.8.0" +tag="v2.7.2" LOG_INFO() { local content=${1} echo -e "\033[32m ${content}\033[0m" diff --git a/build.gradle b/build.gradle index 93c297809..d34fc02de 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ ext { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.java-sdk' - version = '2.8.0-GMT0018' + version = '2.8.1-SNAPSHOT' apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: 'idea' diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java index 060f3a7d7..af3677c2d 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java @@ -303,9 +303,28 @@ public List decodeMethod(String ABI, String methodName, String output) throws ABICodecException { return decodeMethodAndGetOutputObject(ABI, methodName, output).getLeft(); } + /** + * decode the input string into json + * + * @param input the transaction input + * @return the decoded json string of the input + */ + public List decodeTransactionInputToString(String ABI, String input) + throws ABICodecException { + String inputWithPrefix = addHexPrefixToString(input); + String methodId = inputWithPrefix.substring(0, 10); + return decodeMethodByIdToString(ABI, methodId, input.substring(10), false); + } - public List decodeMethodById(String ABI, String methodId, String output) + public Pair, List> decodeTransactionInput(String ABI, String input) throws ABICodecException { + String inputWithPrefix = addHexPrefixToString(input); + String methodId = inputWithPrefix.substring(0, 10); + return decodeDataByMethodId(ABI, methodId, input.substring(10), false); + } + + public Pair, List> decodeDataByMethodId( + String ABI, String methodId, String data, boolean isOutput) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); ABIDefinition abiDefinition = contractABIDefinition.getABIDefinitionByMethodId(methodId); if (abiDefinition == null) { @@ -313,10 +332,15 @@ public List decodeMethodById(String ABI, String methodId, String output) logger.error(errorMsg); throw new ABICodecException(errorMsg); } - ABIObject outputABIObject = abiObjectFactory.createOutputObject(abiDefinition); + ABIObject outputABIObject = null; + if (isOutput) { + outputABIObject = abiObjectFactory.createOutputObject(abiDefinition); + } else { + outputABIObject = abiObjectFactory.createInputObject(abiDefinition); + } ABICodecObject abiCodecObject = new ABICodecObject(); try { - return abiCodecObject.decodeJavaObject(outputABIObject, output); + return abiCodecObject.decodeJavaObjectAndOutputObject(outputABIObject, data); } catch (Exception e) { logger.error(" exception in decodeMethodByIdToObject : {}", e.getMessage()); } @@ -326,6 +350,11 @@ public List decodeMethodById(String ABI, String methodId, String output) throw new ABICodecException(errorMsg); } + public List decodeMethodById(String ABI, String methodId, String output) + throws ABICodecException { + return decodeDataByMethodId(ABI, methodId, output, true).getLeft(); + } + public List decodeMethodByInterface(String ABI, String methodInterface, String output) throws ABICodecException { FunctionEncoder functionEncoder = new FunctionEncoder(cryptoSuite); @@ -361,6 +390,11 @@ public List decodeMethodToString(String ABI, String methodName, String o public List decodeMethodByIdToString(String ABI, String methodId, String output) throws ABICodecException { + return decodeMethodByIdToString(ABI, methodId, output, true); + } + + public List decodeMethodByIdToString( + String ABI, String methodId, String data, boolean isOutput) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); ABIDefinition abiDefinition = contractABIDefinition.getABIDefinitionByMethodId(methodId); if (abiDefinition == null) { @@ -368,10 +402,15 @@ public List decodeMethodByIdToString(String ABI, String methodId, String logger.error(errorMsg); throw new ABICodecException(errorMsg); } - ABIObject outputABIObject = abiObjectFactory.createOutputObject(abiDefinition); + ABIObject outputABIObject = null; + if (isOutput) { + outputABIObject = abiObjectFactory.createOutputObject(abiDefinition); + } else { + outputABIObject = abiObjectFactory.createInputObject(abiDefinition); + } ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); try { - return abiCodecJsonWrapper.decode(outputABIObject, output); + return abiCodecJsonWrapper.decode(outputABIObject, data); } catch (UnsupportedOperationException e) { logger.error(" exception in decodeMethodByIdToString : {}", e.getMessage()); } @@ -513,6 +552,13 @@ public List decodeEventByInterfaceToString( return decodeEventByTopicToString(ABI, methodId, log); } + private String addHexPrefixToString(String s) { + if (!s.startsWith("0x")) { + return "0x" + s; + } + return s; + } + private List mergeEventParamsAndTopics( ABIDefinition abiDefinition, List params, List topics) { List ret = new ArrayList<>(); diff --git a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java index 2f3d9f368..88c4f1cda 100644 --- a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java +++ b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java @@ -72,6 +72,15 @@ public TransactionResponse decodeReceiptWithValues( String abi, String functionName, TransactionReceipt transactionReceipt) throws IOException, ABICodecException, TransactionException { TransactionResponse response = decodeReceiptWithoutValues(abi, transactionReceipt); + // parse the input + if (transactionReceipt.getInput() != null) { + Pair, List> inputObject = + abiCodec.decodeTransactionInput(abi, transactionReceipt.getInput()); + String inputValues = JsonUtils.toJson(inputObject.getLeft()); + response.setInputData(inputValues); + response.setInputObject(inputObject.getLeft()); + response.setInputABIObject(inputObject.getRight()); + } // only successful tx has return values. if (transactionReceipt.getStatus().equals("0x0")) { Pair, List> returnObject = diff --git a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/model/dto/TransactionResponse.java b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/model/dto/TransactionResponse.java index cd6c6e0ff..fbaba1dfb 100644 --- a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/model/dto/TransactionResponse.java +++ b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/model/dto/TransactionResponse.java @@ -37,6 +37,10 @@ public class TransactionResponse extends CommonResponse { private List returnObject; private List returnABIObject; + private String inputData; + private List inputObject; + private List inputABIObject; + public TransactionResponse() { super(); } @@ -134,4 +138,28 @@ public List getReturnABIObject() { public void setReturnABIObject(List returnABIObject) { this.returnABIObject = returnABIObject; } + + public List getInputObject() { + return inputObject; + } + + public void setInputObject(List inputObject) { + this.inputObject = inputObject; + } + + public List getInputABIObject() { + return inputABIObject; + } + + public void setInputABIObject(List inputABIObject) { + this.inputABIObject = inputABIObject; + } + + public String getInputData() { + return inputData; + } + + public void setInputData(String inputData) { + this.inputData = inputData; + } } From 3343bd742f5522307c043289d1c718e161ee0213 Mon Sep 17 00:00:00 2001 From: dalaocu Date: Mon, 11 Oct 2021 15:16:41 +0800 Subject: [PATCH 05/11] Constructor input parser & add test cases of input parse (#361) * add test of input parser * add test * fix ci problems --- .../java/org/fisco/bcos/sdk/abi/ABICodec.java | 31 ++++++++++++++++ .../decode/TransactionDecoderInterface.java | 12 +++++++ .../decode/TransactionDecoderService.java | 18 ++++++++++ .../manager/AssembleTransactionProcessor.java | 3 +- .../TransactionDecoderServiceTest.java | 2 ++ .../AssembleTransactionProcessorTest.java | 35 +++++++++++++++++-- ...ransactionWithRemoteSignProcessorTest.java | 2 +- .../mock/RemoteSignCallbackMock.java | 4 +-- 8 files changed, 100 insertions(+), 7 deletions(-) diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java index af3677c2d..97e490ae4 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.fisco.bcos.sdk.abi.wrapper.ABICodecJsonWrapper; import org.fisco.bcos.sdk.abi.wrapper.ABICodecObject; @@ -323,6 +324,36 @@ public Pair, List> decodeTransactionInput(String ABI, St return decodeDataByMethodId(ABI, methodId, input.substring(10), false); } + public Pair, List> decodeMethodInput( + String ABI, String input, String methodName, String code) throws ABICodecException { + ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); + List methods; + ABICodecObject abiCodecObject = new ABICodecObject(); + ABIObjectFactory abiObjectFactory = new ABIObjectFactory(); + if (StringUtils.equals(methodName, "constructor")) { + String lastCode = StringUtils.substring(code, code.length() - 32, code.length()); + String paramsInput = StringUtils.substringAfter(input, lastCode); + // remove methodId of input + return abiCodecObject.decodeJavaObjectAndOutputObject( + abiObjectFactory.createInputObject(contractABIDefinition.getConstructor()), + paramsInput); + } else { + methods = contractABIDefinition.getFunctions().get(methodName); + } + for (ABIDefinition abiDefinition : methods) { + ABIObject outputABIObject = abiObjectFactory.createInputObject(abiDefinition); + try { + return abiCodecObject.decodeJavaObjectAndOutputObject( + outputABIObject, input.substring(10)); + } catch (Exception e) { + logger.warn(" exception in decodeMethodInput : {}", e.getMessage()); + } + } + String errorMsg = " cannot decode in decodeMethodInput with appropriate interface ABI"; + logger.error(errorMsg); + throw new ABICodecException(errorMsg); + } + public Pair, List> decodeDataByMethodId( String ABI, String methodId, String data, boolean isOutput) throws ABICodecException { ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI); diff --git a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderInterface.java b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderInterface.java index 8551763d1..927cf86cb 100644 --- a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderInterface.java +++ b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderInterface.java @@ -69,6 +69,18 @@ public TransactionResponse decodeReceiptWithoutValues( String abi, TransactionReceipt transactionReceipt) throws TransactionException, IOException, ABICodecException; + /** + * parse the transaction information from receipt without return values, but with input values + * + * @param abi contract abi + * @param transactionReceipt transaction receipt + * @param constructorCode decode for constructor + * @return the resolved status and other transaction detail + */ + public TransactionResponse decodeReceiptWithoutOutputValues( + String abi, TransactionReceipt transactionReceipt, String constructorCode) + throws TransactionException, IOException, ABICodecException; + /** * parse the transaction events from receipt logs * diff --git a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java index 88c4f1cda..111b277f7 100644 --- a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java +++ b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/codec/decode/TransactionDecoderService.java @@ -110,6 +110,24 @@ public TransactionResponse decodeReceiptWithoutValues( return response; } + @Override + public TransactionResponse decodeReceiptWithoutOutputValues( + String abi, TransactionReceipt transactionReceipt, String constructorCode) + throws TransactionException, IOException, ABICodecException { + TransactionResponse response = decodeReceiptWithoutValues(abi, transactionReceipt); + // parse the input + if (transactionReceipt.getInput() != null && transactionReceipt.isStatusOK()) { + Pair, List> inputObject = + abiCodec.decodeMethodInput( + abi, transactionReceipt.getInput(), "constructor", constructorCode); + String inputValues = JsonUtils.toJson(inputObject.getLeft()); + response.setInputData(inputValues); + response.setInputObject(inputObject.getLeft()); + response.setInputABIObject(inputObject.getRight()); + } + return response; + } + @Override public TransactionResponse decodeReceiptStatus(TransactionReceipt receipt) { TransactionResponse response = new TransactionResponse(); diff --git a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessor.java b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessor.java index 72b5c2972..a0fee8de3 100644 --- a/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessor.java +++ b/sdk-transaction/src/main/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessor.java @@ -103,8 +103,9 @@ public TransactionReceipt deployAndGetReceipt(String data) { @Override public TransactionResponse deployAndGetResponse(String abi, String signedData) { TransactionReceipt receipt = transactionPusher.push(signedData); + String code = client.getCode(receipt.getContractAddress()).getCode(); try { - return transactionDecoder.decodeReceiptWithoutValues(abi, receipt); + return transactionDecoder.decodeReceiptWithoutOutputValues(abi, receipt, code); } catch (TransactionException | IOException | ABICodecException e) { log.error("deploy exception: {}", e.getMessage()); return new TransactionResponse( diff --git a/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/TransactionDecoderServiceTest.java b/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/TransactionDecoderServiceTest.java index fb9a359b5..6f53dcdc0 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/TransactionDecoderServiceTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/transaction/decoder/TransactionDecoderServiceTest.java @@ -65,6 +65,8 @@ public void testDecode() throws Exception { return; } String contractAddress = response.getContractAddress(); + Assert.assertEquals(2, response.getInputObject().size()); + // System.out.println(JsonUtils.toJson(response)); // increment TransactionReceipt transactionReceipt = diff --git a/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessorTest.java b/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessorTest.java index c16b15757..e15365d7f 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessorTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionProcessorTest.java @@ -101,6 +101,8 @@ public void test1HelloWorld() throws Exception { transactionProcessor.sendTransactionAndGetResponseByContractLoader( "HelloWorld", helloWorldAddrss, "set", params); Assert.assertEquals("0x0", res.getTransactionReceipt().getStatus()); + Assert.assertEquals("test", res.getInputObject().get(0)); + // System.out.println(JsonUtils.toJson(res)); // test call by contract loader CallResponse callResponse2 = @@ -293,7 +295,6 @@ public void onResponse(TransactionReceipt receipt) { abi, "getUint256", Lists.newArrayList()); - // System.out.println(JsonUtils.toJson(callResponse3)); Assert.assertEquals("Success", callResponse3.getReturnMessage()); } catch (TransactionBaseException | ABICodecException e) { System.out.println(e.getMessage()); @@ -313,6 +314,7 @@ public void test6ComplexSetValues() throws Exception { params.add("test2"); TransactionResponse response = transactionProcessor.deployByContractLoader("ComplexSol", params); + // System.out.println(JsonUtils.toJson(response)); if (!response.getTransactionReceipt().getStatus().equals("0x0")) { return; } @@ -322,14 +324,14 @@ public void test6ComplexSetValues() throws Exception { String[] o = {"0x1", "0x2", "0x3"}; List a = Arrays.asList(o); paramsSetValues.add(a); - paramsSetValues.add("set values 字符串"); + paramsSetValues.add("set values 字符"); TransactionResponse transactionResponse = transactionProcessor.sendTransactionAndGetResponse( contractAddress, abi, "setValues", paramsSetValues); // System.out.println(JsonUtils.toJson(transactionResponse)); Map>> eventsMap = transactionResponse.getEventResultMap(); Assert.assertEquals(1, eventsMap.size()); - Assert.assertEquals("set values 字符串", eventsMap.get("LogSetValues").get(0).get(2)); + Assert.assertEquals("set values 字符", eventsMap.get("LogSetValues").get(0).get(2)); } @Test @@ -401,4 +403,31 @@ public void test8ComplexSetBytesFuture() throws Exception { Assert.assertEquals("0x0", response.getTransactionReceipt().getStatus()); }); } + + @Test + public void test9ComplexIncrementInputParser() throws Exception { + AssembleTransactionProcessor transactionProcessor = + TransactionProcessorFactory.createAssembleTransactionProcessor( + client, cryptoKeyPair, abiFile, binFile); + // deploy + List params = Lists.newArrayList(); + params.add(1); + params.add("test2"); + TransactionResponse response = + transactionProcessor.deployByContractLoader("ComplexSol", params); + if (!response.getTransactionReceipt().getStatus().equals("0x0")) { + return; + } + Assert.assertEquals(2, response.getInputABIObject().size()); + Assert.assertEquals("test2", response.getInputObject().get(1)); + String contractAddress = response.getContractAddress(); + // increment v + TransactionResponse transactionResponse = + transactionProcessor.sendTransactionAndGetResponse( + contractAddress, + abi, + "incrementUint256", + Lists.newArrayList(BigInteger.valueOf(10))); + Assert.assertEquals(BigInteger.valueOf(10), transactionResponse.getInputObject().get(0)); + } } diff --git a/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java b/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java index 0f4233637..e435d0a98 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java @@ -48,7 +48,7 @@ public class AssembleTransactionWithRemoteSignProcessorTest { private static final String abiFile = "src/integration-test/resources/abi/"; private static final String binFile = "src/integration-test/resources/bin/"; private List params = Lists.newArrayList("test"); - // prepare sdk, read from the config file + // prepare sdk, read from the config file private BcosSDK sdk = BcosSDK.build(configFile); // set the group number 1 private Client client = sdk.getClient(Integer.valueOf(1)); diff --git a/src/integration-test/java/org/fisco/bcos/sdk/transaction/mock/RemoteSignCallbackMock.java b/src/integration-test/java/org/fisco/bcos/sdk/transaction/mock/RemoteSignCallbackMock.java index 355209640..fd6fd5000 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/transaction/mock/RemoteSignCallbackMock.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/transaction/mock/RemoteSignCallbackMock.java @@ -21,7 +21,7 @@ public RemoteSignCallbackMock( } /** - * 签名结果回调的实现 + * callback of sign transaction * * @param signatureStr 签名服务回调返回的签名结果串 * @return * @@ -29,7 +29,7 @@ public RemoteSignCallbackMock( @Override public int handleSignedTransaction(SignatureResult signatureStr) { System.out.println(System.currentTimeMillis() + " SignatureResult: " + signatureStr); - // 完成了交易签名后,将其发送出去 + // after sign, send it TransactionReceipt tr = assembleTransactionWithRemoteSignProcessor.signAndPush( rawTransaction, signatureStr.convertToString()); From 42ed33a3a3682ab711fe94df7d54ba5cf94dc31c Mon Sep 17 00:00:00 2001 From: kyonRay Date: Wed, 19 Jan 2022 18:32:02 +0800 Subject: [PATCH 06/11] (build): update grgit version. --- .ci/ci_check.sh | 7 ++++--- .github/workflows/workflow.yml | 2 +- build.gradle | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.ci/ci_check.sh b/.ci/ci_check.sh index 0f3c2d2e4..963a54b40 100755 --- a/.ci/ci_check.sh +++ b/.ci/ci_check.sh @@ -30,7 +30,8 @@ download_build_chain() { tag=$(curl -sS "https://gitee.com/api/v5/repos/FISCO-BCOS/FISCO-BCOS/tags" | grep -oe "\"name\":\"v[2-9]*\.[0-9]*\.[0-9]*\"" | cut -d \" -f 4 | sort -V | tail -n 1) LOG_INFO "--- current tag: $tag" - curl -LO "https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/${tag}/build_chain.sh" && chmod u+x build_chain.sh +# curl -LO "https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/${tag}/build_chain.sh" && chmod u+x build_chain.sh + curl -LO "https://raw.githubusercontent.com/FISCO-BCOS/FISCO-BCOS/master-2.0/tools/build_chain.sh" && chmod u+x build_chain.sh } get_sed_cmd() @@ -75,11 +76,11 @@ build_node() { local node_type="${1}" if [ "${node_type}" == "sm" ];then - ./build_chain.sh -l 127.0.0.1:4 -g + bash -x build_chain.sh -l 127.0.0.1:4 -g sed_cmd=$(get_sed_cmd) $sed_cmd 's/sm_crypto_channel=false/sm_crypto_channel=true/g' nodes/127.0.0.1/node*/config.ini else - ./build_chain.sh -l 127.0.0.1:4 + bash -x build_chain.sh -l 127.0.0.1:4 fi ./nodes/127.0.0.1/fisco-bcos -v ./nodes/127.0.0.1/start_all.sh diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 7c601955a..b1507c8a6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-16.04, macos-latest] + os: [ubuntu-18.04, ubuntu-20.04, macos-latest] steps: - uses: actions/checkout@v2 with: diff --git a/build.gradle b/build.gradle index 93c297809..48764a66d 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'com.github.sherter.google-java-format' version '0.8' id 'maven-publish' - id 'org.ajoberstar.grgit' version '4.1.0' + id 'org.ajoberstar.grgit' version '4.1.1' } println("Notice: current gradle version is " + gradle.gradleVersion) // Additional attribute definition From de13087ceb34699a4769b697a69e8a833124f1d7 Mon Sep 17 00:00:00 2001 From: kyonRay Date: Fri, 21 Jan 2022 16:14:50 +0800 Subject: [PATCH 07/11] (sdk-crypto): fix sdk sm2 get pubKey with prefix bug. --- .../sdk/crypto/keypair/CryptoKeyPair.java | 6 +- .../sdk/crypto/keypair/SDFSM2KeyPair.java | 6 +- .../bcos/sdk/crypto/keystore/KeyTool.java | 2 +- .../sdk/crypto/signature/SDFSM2Signature.java | 5 +- .../sdk/crypto/signature/SM2Signature.java | 5 +- .../crypto/signature/SM2SignatureResult.java | 4 +- .../fisco/bcos/sdk/crypto/KeyToolTest.java | 9 +-- .../fisco/bcos/sdk/crypto/SignatureTest.java | 74 +++++++++---------- 8 files changed, 55 insertions(+), 56 deletions(-) diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java index ad7ffb4c7..e8b5467d4 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/CryptoKeyPair.java @@ -88,7 +88,7 @@ public CryptoKeyPair(KeyPair keyPair) { */ CryptoKeyPair(final CryptoResult nativeResult) { this.hexPrivateKey = nativeResult.privateKey; - this.hexPublicKey = nativeResult.publicKey; + this.hexPublicKey = getPublicKeyNoPrefix(nativeResult.publicKey); } /** @@ -164,7 +164,7 @@ public CryptoKeyPair createKeyPair(String hexPrivateKey) { return createKeyPair(keyPair); } - protected static String getPublicKeyNoPrefix(String publicKeyStr) { + public static String getPublicKeyNoPrefix(String publicKeyStr) { String publicKeyNoPrefix = Numeric.cleanHexPrefix(publicKeyStr); if (publicKeyNoPrefix.startsWith(UNCOMPRESSED_PUBLICKEY_FLAG_STR) && publicKeyNoPrefix.length() @@ -188,7 +188,7 @@ protected static String getPublicKeyNoPrefix(String publicKeyStr) { public String getAddress() { // Note: The generated publicKey is prefixed with 04, When calculate the address, need to // remove 04 - return getAddress(this.getHexPublicKey().substring(2)); + return getAddress(getPublicKeyNoPrefix(this.hexPublicKey)); } public String getAddress(String publicKey) { diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java index 55134f1fa..26c17b9d4 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keypair/SDFSM2KeyPair.java @@ -52,11 +52,7 @@ protected SDFSM2KeyPair(long keyIndex, String password) { throw new KeyPairException( "get sdf sm2 internal key public key failed:" + pkResult.getSdfErrorMessage()); } - this.hexPublicKey = - Numeric.getHexKeyWithPrefix( - pkResult.getPublicKey(), - CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, - CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX); + this.hexPublicKey = getPublicKeyNoPrefix(pkResult.getPublicKey()); this.isInternalKey = true; } diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java index 6420d5716..7924dec5a 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/keystore/KeyTool.java @@ -138,7 +138,7 @@ public static String getHexedPublicKey(PublicKey publicKey) { byte[] publicKeyBytes = ((BCECPublicKey) publicKey).getQ().getEncoded(false); BigInteger publicKeyValue = new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length)); - return ("04" + Numeric.toHexStringNoPrefixZeroPadded(publicKeyValue, 128)); + return Numeric.toHexStringNoPrefixZeroPadded(publicKeyValue, 128); } /** diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java index dcf1dd582..162893abc 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SDFSM2Signature.java @@ -38,7 +38,10 @@ public String signWithStringSignature(final String message, final CryptoKeyPair public String signMessage(String message, CryptoKeyPair keyPair) { CryptoResult hashResult = NativeInterface.sm2ComputeHashE( - Numeric.cleanHexPrefix(keyPair.getHexPublicKey()), + Numeric.getHexKeyWithPrefix( + keyPair.getHexPublicKey(), + UNCOMPRESSED_PUBLICKEY_FLAG_STR, + PUBLIC_KEY_LENGTH_IN_HEX), Numeric.cleanHexPrefix(message)); checkCryptoResult(hashResult); SDFCryptoResult signatureResult; diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java index fcd6d93be..cc45cfebb 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2Signature.java @@ -41,7 +41,10 @@ public String signMessage(String message, CryptoKeyPair keyPair) { CryptoResult signatureResult = NativeInterface.sm2SignFast( keyPair.getHexPrivateKey(), - keyPair.getHexPublicKey(), + Numeric.getHexKeyWithPrefix( + keyPair.getHexPublicKey(), + CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR, + CryptoKeyPair.PUBLIC_KEY_LENGTH_IN_HEX), Numeric.cleanHexPrefix(message)); if (signatureResult.wedprErrorMessage != null && !signatureResult.wedprErrorMessage.isEmpty()) { diff --git a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2SignatureResult.java b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2SignatureResult.java index 8447f8e4b..510e069ee 100644 --- a/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2SignatureResult.java +++ b/sdk-crypto/src/main/java/org/fisco/bcos/sdk/crypto/signature/SM2SignatureResult.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.List; +import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair; import org.fisco.bcos.sdk.rlp.RlpString; import org.fisco.bcos.sdk.rlp.RlpType; import org.fisco.bcos.sdk.utils.Hex; @@ -24,7 +25,8 @@ public class SM2SignatureResult extends SignatureResult { public SM2SignatureResult(final String hexPublicKey, final String signatureString) { super(signatureString); - this.pub = Hex.decode(hexPublicKey.substring(2)); + // clean 04 prefix + this.pub = Hex.decode(CryptoKeyPair.getPublicKeyNoPrefix(hexPublicKey)); } public SM2SignatureResult(byte[] pub, byte[] r, byte[] s) { diff --git a/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/KeyToolTest.java b/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/KeyToolTest.java index 404fe67b5..617f53d62 100644 --- a/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/KeyToolTest.java +++ b/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/KeyToolTest.java @@ -34,9 +34,8 @@ public void testECDSALoadPEMFile() { CryptoType.ECDSA_TYPE, "0x0fc3c4bb89bd90299db4c62be0174c4966286c00"); // check the public key and the privateKey - // Note the 04 prefix Assert.assertEquals( - "04dbbfee4f76f5a3bc3dbc2e6127c4a1f50b7614bff4138a44a79aed3d42f67f9c7aa70570205f9b60a5888c6415b6a830012677b4415a79ccd1533fe5637861df", + "dbbfee4f76f5a3bc3dbc2e6127c4a1f50b7614bff4138a44a79aed3d42f67f9c7aa70570205f9b60a5888c6415b6a830012677b4415a79ccd1533fe5637861df", cryptoKeyPair.getHexPublicKey()); Assert.assertEquals( "bc516b2600eec3a216f457dc14cf83a01ed22d0fc2149fc911dc2ec486fe57a3", @@ -52,7 +51,7 @@ public void testSMLoadPEMFile() { CryptoType.SM_TYPE, "0x40b3558746e8f9a47a474774e8c4a9e67d4e3174"); Assert.assertEquals( - "043b72cd28244c856d3d89b67d1c5ff22e1f26835bafcd63e9a4ad3424a2a57f2b759149f46c696df08b9d9473686675fc6dade744d0c82bdc5598d759e015fd96", + "3b72cd28244c856d3d89b67d1c5ff22e1f26835bafcd63e9a4ad3424a2a57f2b759149f46c696df08b9d9473686675fc6dade744d0c82bdc5598d759e015fd96", cryptoKeyPair.getHexPublicKey()); Assert.assertEquals( "901744c34e2adffc9fd7fb12e8cba2d88a79aaf54be9b4e11660153287489f13", @@ -83,7 +82,7 @@ public void testLoadECDSAP12File() { "123456", "0x45e14c53197adbcb719d915fb93342c25600faaf"); Assert.assertEquals( - "04d7b9e00f56d3f79305359fa2d7db166021e73086bdcd2e7a28d6ed27345e1f2ddecf85db7438e8457fd474ef9c4ceb89abb7d5fa60a22f2902ec26dca52ad5e5", + "d7b9e00f56d3f79305359fa2d7db166021e73086bdcd2e7a28d6ed27345e1f2ddecf85db7438e8457fd474ef9c4ceb89abb7d5fa60a22f2902ec26dca52ad5e5", cryptoKeyPair.getHexPublicKey()); Assert.assertEquals( "c0c8b4d96aa4aefaeeafa157789d528b6010f65059dee796d8757e1171bbcd2c", @@ -100,7 +99,7 @@ public void testLoadSMP12File() { "abcd123", "0x6f68461309925093236df82b51df630a55d32377"); Assert.assertEquals( - "04a809a0176dc24432490697b6ed74995a6716a122a0fa5c73429a259cd73f14995934522288f226a049bbbb803d78f296289bee8fb4f5d7821514e731a57c9f2f", + "a809a0176dc24432490697b6ed74995a6716a122a0fa5c73429a259cd73f14995934522288f226a049bbbb803d78f296289bee8fb4f5d7821514e731a57c9f2f", cryptoKeyPair.getHexPublicKey()); Assert.assertEquals( "d0cbcdfea24e206688ce6c1a63171a24d9e1e0cf5331151ed5406e07fdb38256", diff --git a/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/SignatureTest.java b/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/SignatureTest.java index f062f0c75..fa722ea2a 100644 --- a/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/SignatureTest.java +++ b/sdk-crypto/src/test/java/org/fisco/bcos/sdk/crypto/SignatureTest.java @@ -54,12 +54,16 @@ public void testCryptoSuiteForECDSA() { // generate keyPair CryptoKeyPair keyPair = cryptoSuite.createKeyPair(); CryptoSuite cryptoSuite2 = new CryptoSuite(CryptoType.ECDSA_TYPE, keyPair); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPublicKey().equals(cryptoSuite.getCryptoKeyPair().getHexPublicKey())); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey().equals(cryptoSuite.getCryptoKeyPair().getHexPrivateKey())); + System.out.println("cryptoSuite2.getCryptoKeyPair().getHexPublicKey(): " + cryptoSuite2.getCryptoKeyPair().getHexPublicKey()); + System.out.println("cryptoSuite.getCryptoKeyPair().getHexPublicKey(): " + cryptoSuite.getCryptoKeyPair().getHexPublicKey()); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPublicKey(), cryptoSuite.getCryptoKeyPair().getHexPublicKey()); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey(), cryptoSuite.getCryptoKeyPair().getHexPrivateKey()); cryptoSuite2 = new CryptoSuite(CryptoType.ECDSA_TYPE, cryptoSuite.getCryptoKeyPair().getHexPrivateKey()); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPublicKey().equals(cryptoSuite.getCryptoKeyPair().getHexPublicKey())); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey().equals(cryptoSuite.getCryptoKeyPair().getHexPrivateKey())); + System.out.println("cryptoSuite2.getCryptoKeyPair().getHexPublicKey(): " + cryptoSuite2.getCryptoKeyPair().getHexPublicKey()); + System.out.println("cryptoSuite.getCryptoKeyPair().getHexPublicKey(): " + cryptoSuite.getCryptoKeyPair().getHexPublicKey()); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPublicKey(), cryptoSuite.getCryptoKeyPair().getHexPublicKey()); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey(), cryptoSuite.getCryptoKeyPair().getHexPrivateKey()); // test signature testSignature(cryptoSuite, keyPair); @@ -76,7 +80,7 @@ public void testCryptoSuiteForECDSA() { System.out.println("hexedPublicKey: " + hexedPublicKey); System.out.println("keyPair.getHexPublicKey(): " + keyPair.getHexPublicKey()); System.out.println("keyPair.getHexPrivate(): " + keyPair.getHexPrivateKey()); - Assert.assertEquals(hexedPublicKey, keyPair.getHexPublicKey().substring(2)); + Assert.assertEquals(hexedPublicKey, keyPair.getHexPublicKey()); testSignature(cryptoSuite, keyPair); String hexedPrivateKeyStr = "bcec428d5205abe0f0cc8a734083908d9eb8563e31f943d760786edf42ad67dd"; @@ -91,12 +95,12 @@ public void testCryptoSuiteForSM2() { CryptoKeyPair keyPair = cryptoSuite.createKeyPair(); CryptoSuite cryptoSuite2 = new CryptoSuite(CryptoType.SM_TYPE, keyPair); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPublicKey().equals(cryptoSuite.getCryptoKeyPair().getHexPublicKey())); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey().equals(cryptoSuite.getCryptoKeyPair().getHexPrivateKey())); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPublicKey(), cryptoSuite.getCryptoKeyPair().getHexPublicKey()); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey(), cryptoSuite.getCryptoKeyPair().getHexPrivateKey()); cryptoSuite2 = new CryptoSuite(CryptoType.SM_TYPE, cryptoSuite.getCryptoKeyPair().getHexPrivateKey()); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPublicKey().equals(cryptoSuite.getCryptoKeyPair().getHexPublicKey())); - Assert.assertTrue(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey().equals(cryptoSuite.getCryptoKeyPair().getHexPrivateKey())); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPublicKey(), cryptoSuite.getCryptoKeyPair().getHexPublicKey()); + Assert.assertEquals(cryptoSuite2.getCryptoKeyPair().getHexPrivateKey(), cryptoSuite.getCryptoKeyPair().getHexPrivateKey()); // test signature testSignature(cryptoSuite, keyPair); } @@ -202,8 +206,7 @@ private void testKeyPair(CryptoKeyPair keyPair, String publicKey, String expecte Assert.assertEquals(expectedAddress, keyPair.getAddress(publicKey)); String uncompressedPublicKey = publicKey; boolean contain0x = false; - if(publicKey.startsWith("0x")) - { + if (publicKey.startsWith("0x")) { contain0x = true; uncompressedPublicKey = publicKey.substring(2); } @@ -214,32 +217,28 @@ private void testKeyPair(CryptoKeyPair keyPair, String publicKey, String expecte + uncompressedPublicKey; } String prefix = "04"; - if(contain0x) - { + if (contain0x) { prefix = "0x04"; } Assert.assertEquals(expectedAddress, keyPair.getAddress(prefix + uncompressedPublicKey)); // convert the publicKey into BigInteger - BigInteger uncompressedPublicKeyValue = new BigInteger(uncompressedPublicKey, 16); + BigInteger uncompressedPublicKeyValue = new BigInteger(uncompressedPublicKey, 16); Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(keyPair.getAddress(uncompressedPublicKeyValue))); // convert the publicKey into bytes byte[] uncompressedPublicKeyBytes = Hex.decode(Numeric.cleanHexPrefix(uncompressedPublicKey)); Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(keyPair.getAddress(uncompressedPublicKeyBytes))); - if(smCrypto) - { - Assert.assertEquals(expectedAddress, SM2KeyPair.getAddressByPublicKey(publicKey)); - Assert.assertEquals(expectedAddress, SM2KeyPair.getAddressByPublicKey(uncompressedPublicKey)); - Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(SM2KeyPair.getAddressByPublicKey(uncompressedPublicKeyValue))); - Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(SM2KeyPair.getAddressByPublicKey(uncompressedPublicKeyBytes))); - - } - else - { - Assert.assertEquals(expectedAddress, ECDSAKeyPair.getAddressByPublicKey(publicKey)); - Assert.assertEquals(expectedAddress, ECDSAKeyPair.getAddressByPublicKey(uncompressedPublicKey)); - Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(ECDSAKeyPair.getAddressByPublicKey(uncompressedPublicKeyValue))); - Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(ECDSAKeyPair.getAddressByPublicKey(uncompressedPublicKeyBytes))); + if (smCrypto) { + Assert.assertEquals(expectedAddress, SM2KeyPair.getAddressByPublicKey(publicKey)); + Assert.assertEquals(expectedAddress, SM2KeyPair.getAddressByPublicKey(uncompressedPublicKey)); + Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(SM2KeyPair.getAddressByPublicKey(uncompressedPublicKeyValue))); + Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(SM2KeyPair.getAddressByPublicKey(uncompressedPublicKeyBytes))); + + } else { + Assert.assertEquals(expectedAddress, ECDSAKeyPair.getAddressByPublicKey(publicKey)); + Assert.assertEquals(expectedAddress, ECDSAKeyPair.getAddressByPublicKey(uncompressedPublicKey)); + Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(ECDSAKeyPair.getAddressByPublicKey(uncompressedPublicKeyValue))); + Assert.assertEquals(expectedAddress, "0x" + Hex.toHexString(ECDSAKeyPair.getAddressByPublicKey(uncompressedPublicKeyBytes))); } } @@ -304,7 +303,7 @@ public void testSignature(Hash hasher, Signature signature, CryptoKeyPair keyPai signature.verify( keyPair.getHexPublicKey(), hexMessageWithPrefix, signResult.convertToString())); //verify - String hexPublicKeyWithoutPrefix = keyPair.getHexPublicKey().substring(2); + String hexPublicKeyWithoutPrefix = keyPair.getHexPublicKey(); Assert.assertTrue( signature.verify( hexPublicKeyWithoutPrefix, message, signResult.convertToString())); @@ -343,20 +342,17 @@ public void testSignature(Hash hasher, Signature signature, CryptoKeyPair keyPai try { String invalidMessage = "0xb3b9ce5a0725c1457b8c7872d05accb3887ecc09a50dc7619b53837e4d9f"; SignatureResult signResult = signature.sign(invalidMessage, keyPair); - }catch(SignatureException e) - { + } catch (SignatureException e) { System.out.println("Sign failed for " + e.getMessage()); } try { String invalidMessage = ""; - for(int i = 0; i < 64; i++) - { + for (int i = 0; i < 64; i++) { invalidMessage += "r"; } SignatureResult signResult = signature.sign(invalidMessage, keyPair); - }catch(SignatureException e) - { + } catch (SignatureException e) { System.out.println("Sign failed for " + e.getMessage()); } } @@ -510,10 +506,10 @@ public void testLoadAndStoreKeyPairWithP12(int cryptoType) throws ConfigExceptio System.out.println("P12 orgKeyPair pri: " + orgKeyPair.getHexPrivateKey()); System.out.println("P12 decodedKeyPair pr: " + decodedCryptoKeyPair.getHexPrivateKey()); - Assert.assertTrue( - orgKeyPair.getHexPrivateKey().equals(decodedCryptoKeyPair.getHexPrivateKey())); - Assert.assertTrue( - orgKeyPair.getHexPublicKey().equals(decodedCryptoKeyPair.getHexPublicKey())); + Assert.assertEquals( + orgKeyPair.getHexPrivateKey(), decodedCryptoKeyPair.getHexPrivateKey()); + Assert.assertEquals( + orgKeyPair.getHexPublicKey(), decodedCryptoKeyPair.getHexPublicKey()); // test sign and verify message with String publicP12Path = p12FilePath + ".pub"; From f4f75e7bf777321474960d17cf17179bb98366a6 Mon Sep 17 00:00:00 2001 From: cyjseagull Date: Wed, 13 Apr 2022 17:00:13 +0800 Subject: [PATCH 08/11] optimize java-sdk connection error message (#538) --- .../fisco/bcos/sdk/channel/ChannelImp.java | 14 +- .../bcos/sdk/config/model/ConfigProperty.java | 8 +- .../bcos/sdk/network/ChannelHandler.java | 5 +- .../bcos/sdk/network/ConnectionManager.java | 88 +++++++--- .../fisco/bcos/sdk/network/NetworkImp.java | 156 ++++++++++-------- .../bcos/sdk/utils/SystemInformation.java | 64 +++---- 6 files changed, 188 insertions(+), 147 deletions(-) diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelImp.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelImp.java index 580165c25..60f032513 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelImp.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/channel/ChannelImp.java @@ -89,11 +89,11 @@ public void start() { network.start(); checkConnectionsToStartPeriodTask(); running = true; - logger.debug("Start the channel success"); + logger.debug("====> Start the channel success"); } catch (NetworkException e) { network.stop(); - logger.error("init channel network error, {} ", e.getMessage()); - throw new ChannelException("init channel network error: " + e.getMessage(), e); + logger.error("====> init channel network error, {} ", e.getMessage()); + throw new ChannelException("init channel network error!\n" + e.getMessage(), e); } } @@ -115,13 +115,7 @@ private void checkConnectionsToStartPeriodTask() { connectionInfoStr += peer + ", "; } - String baseMessage = - " nodes: " - + connectionInfoStr - + "java version: " - + System.getProperty("java.version") - + " ,java vendor: " - + System.getProperty("java.vm.vendor"); + String baseMessage = " nodes: " + connectionInfoStr; if (getAvailablePeer().size() == 0) { String errorMessage = " Failed to connect to " + baseMessage; diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java index e4b13051c..53f33f778 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/config/model/ConfigProperty.java @@ -110,10 +110,6 @@ public static InputStream getConfigInputStream(String configFilePath) throws Con return inputStream; } } catch (IOException e) { - logger.warn( - "Load config from {} failed, trying to load from the classpath, e: {}", - configFilePath, - e); if (inputStream != null) { try { inputStream.close(); @@ -124,6 +120,10 @@ public static InputStream getConfigInputStream(String configFilePath) throws Con } // try to load from the class path ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + logger.info( + "Load config from {} failed, trying to load from the resourcePath {}", + configFilePath, + classLoader.getResource("").getPath()); inputStream = classLoader.getResourceAsStream(configFilePath); return inputStream; } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ChannelHandler.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ChannelHandler.java index 35842fea0..2577cc679 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ChannelHandler.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ChannelHandler.java @@ -91,12 +91,11 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc } } else { logger.error( - " handshake failed, host: {}, port: {}, message: {}, cause: {} ", + " handshake failed, host: {}, port: {}, reason: {}, error stack: {} ", host, port, - e.cause().getMessage(), + e.cause().getLocalizedMessage(), e.cause()); - ctx.disconnect(); ctx.close(); } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java index beb46d78f..af7f28404 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/ConnectionManager.java @@ -36,6 +36,7 @@ import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.Future; import java.io.IOException; +import java.nio.channels.ClosedChannelException; import java.security.Security; import java.util.ArrayList; import java.util.List; @@ -47,9 +48,11 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLHandshakeException; import org.fisco.bcos.sdk.config.ConfigOption; import org.fisco.bcos.sdk.model.CryptoType; import org.fisco.bcos.sdk.model.RetCode; +import org.fisco.bcos.sdk.utils.SystemInformation; import org.fisco.bcos.sdk.utils.ThreadPoolService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,6 +72,7 @@ public class ConnectionManager { private Bootstrap bootstrap = new Bootstrap(); private List connChannelFuture = new ArrayList(); private ScheduledExecutorService reconnSchedule = new ScheduledThreadPoolExecutor(1); + private int cryptoType; public ConnectionManager(ConfigOption configOption, MsgHandler msgHandler) { this(configOption.getNetworkConfig().getPeers(), msgHandler); @@ -115,7 +119,7 @@ public void startConnect(ConfigOption configOption) throws NetworkException { for (int i = 0; i < connectionInfoList.size(); i++) { ConnectionInfo connInfo = connectionInfoList.get(i); ChannelFuture connectFuture = connChannelFuture.get(i); - if (checkConnectionResult(connInfo, connectFuture, errorMessageList)) { + if (checkConnectionResult(cryptoType, connInfo, connectFuture, errorMessageList)) { atLeastOneConnectSuccess = true; } } @@ -125,20 +129,20 @@ public void startConnect(ConfigOption configOption) throws NetworkException { logger.error(" all connections have failed, {} ", errorMessageList); String errorMessageString = ""; for (RetCode errorRetCode : errorMessageList) { - errorMessageString += errorRetCode.getMessage() + "\n"; + errorMessageString += "* " + errorRetCode.getMessage() + "\n"; } for (RetCode errorRetCode : errorMessageList) { if (errorRetCode.getCode() == NetworkException.SSL_HANDSHAKE_FAILED) { throw new NetworkException( - " Failed to connect to all the nodes! errorMessage: \n" - + errorMessageString, + "Failed to connect to all the nodes!\n" + errorMessageString, NetworkException.SSL_HANDSHAKE_FAILED); } } throw new NetworkException( - " Failed to connect to all the nodes! errorMessage: \n" + errorMessageString, + "Failed to connect to all the nodes!\n" + errorMessageString, NetworkException.CONNECT_FAILED); } + cryptoType = configOption.getCryptoMaterialConfig().getSslCryptoType(); logger.debug(" start connect end. "); } @@ -192,7 +196,8 @@ private void reconnect() { ChannelFuture connectFuture = bootstrap.connect(connectionInfo.getIp(), connectionInfo.getPort()); List errorMessageList = new ArrayList<>(); - if (checkConnectionResult(connectionInfo, connectFuture, errorMessageList)) { + if (checkConnectionResult( + cryptoType, connectionInfo, connectFuture, errorMessageList)) { logger.info( " reconnect to {}:{} success", connectionInfo.getIp(), @@ -350,27 +355,26 @@ protected void initChannel(SocketChannel ch) throws Exception { } private boolean checkConnectionResult( - ConnectionInfo connInfo, ChannelFuture connectFuture, List errorMessageList) { + int cryptoType, + ConnectionInfo connInfo, + ChannelFuture connectFuture, + List errorMessageList) { connectFuture.awaitUninterruptibly(); if (!connectFuture.isSuccess()) { + String errorMessage = + "connect to " + + connInfo.getIp() + + ":" + + connInfo.getPort() + + " failed! Please make sure the nodes have been started, and the network between the SDK and the nodes are connected normally."; /** connect failed. */ if (Objects.isNull(connectFuture.cause())) { - logger.error("connect to {}:{} failed. ", connInfo.getIp(), connInfo.getPort()); + logger.error("{}", errorMessage); } else { - logger.error( - "connect to {}:{} failed. {}", - connInfo.getIp(), - connInfo.getPort(), - connectFuture.cause().getMessage()); + errorMessage += "reason: " + connectFuture.cause().getLocalizedMessage() + "\n"; + logger.error("{}, cause: {}", errorMessage, connectFuture.cause().getMessage()); } - errorMessageList.add( - new RetCode( - NetworkException.CONNECT_FAILED, - "connect to " - + connInfo.getIp() - + ":" - + connInfo.getPort() - + " failed")); + errorMessageList.add(new RetCode(NetworkException.CONNECT_FAILED, errorMessage)); return false; } else { /** connect success, check ssl handshake result. */ @@ -379,7 +383,7 @@ private boolean checkConnectionResult( "! Please make sure the certificate is correctly configured and copied, ensure that the SDK and the node are in the same agency!"; if (Objects.isNull(sslhandler)) { String sslHandshakeFailedMessage = - " ssl handshake failed:/" + "ssl handshake failed:/" + connInfo.getIp() + ":" + connInfo.getPort() @@ -391,18 +395,48 @@ private boolean checkConnectionResult( return false; } - Future sshHandshakeFuture = + Future sslHandshakeFuture = sslhandler.handshakeFuture().awaitUninterruptibly(); - if (sshHandshakeFuture.isSuccess()) { - logger.trace(" ssl handshake success {}:{}", connInfo.getIp(), connInfo.getPort()); + if (sslHandshakeFuture.isSuccess()) { + logger.info(" ssl handshake success {}:{}", connInfo.getIp(), connInfo.getPort()); return true; } else { String sslHandshakeFailedMessage = - " ssl handshake failed:/" + "ssl handshake failed:/" + connInfo.getIp() + ":" + connInfo.getPort() - + checkerMessage; + + "\n"; + if (sslHandshakeFuture.cause() instanceof SSLHandshakeException) { + if (cryptoType == CryptoType.ECDSA_TYPE + && !SystemInformation.supportSecp256K1) { + sslHandshakeFailedMessage += + " reason: secp256k1 algorithm is disabled by the current jdk. Please enable secp256k1 or replace to jdk that supports secp256k1."; + } else { + SSLHandshakeException e = + (SSLHandshakeException) sslHandshakeFuture.cause(); + sslHandshakeFailedMessage += + " reason: " + + e.getLocalizedMessage() + + ". Please make sure the certificate are correctly configured and copied."; + } + } else if (sslHandshakeFuture.cause() instanceof ClosedChannelException) { + ClosedChannelException e = (ClosedChannelException) sslHandshakeFuture.cause(); + if (cryptoType == CryptoType.ECDSA_TYPE) { + sslHandshakeFailedMessage += + " reason: The node closes the connection. Maybe connect to the sm node with ecdsa context or the node and the SDK are not belong to the same agency."; + } else { + sslHandshakeFailedMessage += + " reason: The node closes the connection. Maybe connect to the ecdsa node with sm context or the node and the SDK are not belong to the same agency."; + } + } else { + sslHandshakeFailedMessage += + " reason: " + + sslHandshakeFuture.cause().getLocalizedMessage() + + " Please check if there is a netty conflict, the netty version currently supported by the sdk is:" + + SystemInformation.nettyVersion; + } + logger.error(sslHandshakeFailedMessage); errorMessageList.add( new RetCode( diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java index 37a99a5f2..cd94c0d24 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/network/NetworkImp.java @@ -110,17 +110,16 @@ private CheckCertExistenceResult checkCertExistence(boolean isSM) throws Network CheckCertExistenceResult result = new CheckCertExistenceResult(); result.setCheckPassed(true); - String errorMessage = ""; - errorMessage = errorMessage + "Please make sure "; + String errorMessage = "["; if (configOption.getCryptoMaterialConfig().getCaInputStream() == null) { result.setCheckPassed(false); errorMessage = - errorMessage + configOption.getCryptoMaterialConfig().getCaCertPath() + " "; + errorMessage + configOption.getCryptoMaterialConfig().getCaCertPath() + ","; } if (configOption.getCryptoMaterialConfig().getSdkCertInputStream() == null) { result.setCheckPassed(false); errorMessage = - errorMessage + configOption.getCryptoMaterialConfig().getSdkCertPath() + " "; + errorMessage + configOption.getCryptoMaterialConfig().getSdkCertPath() + ","; } if (configOption.getCryptoMaterialConfig().getSdkPrivateKeyInputStream() == null) { @@ -128,11 +127,11 @@ private CheckCertExistenceResult checkCertExistence(boolean isSM) throws Network errorMessage = errorMessage + configOption.getCryptoMaterialConfig().getSdkPrivateKeyPath() - + " "; + + ","; } if (!isSM) { - errorMessage = errorMessage + "exists!"; + errorMessage = errorMessage + "]"; result.setErrorMessage(errorMessage); return result; } @@ -141,119 +140,132 @@ private CheckCertExistenceResult checkCertExistence(boolean isSM) throws Network errorMessage = errorMessage + configOption.getCryptoMaterialConfig().getEnSSLPrivateKeyPath() - + " "; + + ","; result.setCheckPassed(false); } if (configOption.getCryptoMaterialConfig().getEnSSLCertInputStream() == null) { errorMessage = errorMessage + configOption.getCryptoMaterialConfig().getEnSSLCertPath() - + " "; + + ","; result.setCheckPassed(false); } } - errorMessage = errorMessage + "exist!"; + errorMessage = errorMessage + "]"; result.setErrorMessage(errorMessage); return result; } @Override public void start() throws NetworkException { - boolean tryEcdsaConnect = false; CheckCertExistenceResult result = null; String ecdsaCryptoInfo = configOption.getCryptoMaterialConfig().toString(); - String ecdsaErrorMessage = ""; + String tipsInformation = "\n* TRACE INFORMATION:\n----------------------------\n"; try { try { + tipsInformation += "====> STEP1: try to connect nodes with ecdsa context...\n"; + logger.info("{}", tipsInformation); result = checkCertExistence(false); if (result.isCheckPassed()) { - logger.debug("start connManager with ECDSA sslContext"); + String message = + "<==== STEP1-1: Load certificates for ecdsa context success..."; + tipsInformation += message + "\n"; + logger.info("====> {}, start connManager with ECDSA sslContext", message); connManager.startConnect(configOption); connManager.startReconnectSchedule(); return; } else { - logger.warn( - "Try to connect node with ECDSA sslContext failed, the tried NON-SM certPath: " - + ecdsaCryptoInfo - + ", currentPath: " - + new File("").getAbsolutePath()); + String errorMessage = + "<==== STEP1 Result: try to connect nodes with ecdsa context failed for cert missing\n* Missed certificates: " + + result.getErrorMessage() + + "\n"; + errorMessage += "currentPath: " + new File("").getAbsolutePath() + "\n"; + tipsInformation += errorMessage + "\n"; + logger.warn(errorMessage); } } catch (NetworkException e) { - configOption.reloadConfig(CryptoType.SM_TYPE); if (e.getErrorCode() == NetworkException.CONNECT_FAILED) { - String errorMessage = e.getMessage(); - errorMessage += - "\n* If your blockchain is NON-SM,please provide the NON-SM certificates: " - + ecdsaCryptoInfo - + ".\n"; - errorMessage += - "\n* If your blockchain is SM, please provide the SM certificates: " - + configOption.getCryptoMaterialConfig().toString() - + "\n"; - throw new NetworkException( - errorMessage + "\n" + SystemInformation.getSystemInformation()); + String errorMessage = "<==== connect nodes failed, reason:\n" + e.getMessage(); + tipsInformation += errorMessage + "\n"; + logger.warn("{}", errorMessage); + throw new NetworkException(tipsInformation); } // means that all the ECDSA certificates exist - tryEcdsaConnect = true; - ecdsaErrorMessage += e.getMessage(); + String errorMessage = + "<==== STEP1 Result: try to connect nodes with ecdsa context failed. reason:\n" + + e.getMessage(); + tipsInformation += errorMessage + "\n"; + logger.info("{}", errorMessage); + configOption.reloadConfig(CryptoType.SM_TYPE); connManager.stopNetty(); - logger.debug( - "start connManager with the ECDSA sslContext failed, try to use SM sslContext, error info: {}", - e.getMessage()); } - logger.debug("start connManager with SM sslContext"); + String message = "----------------------------\n"; + message += + "====> STEP2: connect nodes with ecdsa context failed, try to connect nodes with sm-context..."; + tipsInformation += message + "\n"; + logger.info("{}", message); configOption.reloadConfig(CryptoType.SM_TYPE); result = checkCertExistence(true); if (!result.isCheckPassed()) { - if (tryEcdsaConnect) { - String errorMessage = - "\n* Try init the NON-SM sslContext failed and the SM certificates are incomplete . error info: \n" - + ecdsaErrorMessage; + message = + "<==== STEP2 Result: connect with sm context failed for cert missing.\n* Missed certificates: \n" + + result.getErrorMessage() + + "\n"; + message += "currentPath: " + new File("").getAbsolutePath() + "\n"; + message += "----------------------------\n"; + message += + "<====> Error: try to connect nodes with both ecdsa and sm context failed <====>\n"; + message += + "<====>\033[1;31m Please refer to github issue: " + + SystemInformation.connectionFaqIssueUrl + + " \033[0m\n"; + message += + "<====>\033[1;31m Please refer to fisco-docs: " + + SystemInformation.connectionFaqDocUrl + + " \033[0m\n"; + message += "----------------------------\n"; - errorMessage += - "\n* If your blockchain channel config is NON-SM, please provide the NON-SM certificates: " - + ecdsaCryptoInfo - + ".\n"; - errorMessage += - "\n* If your blockchain channel config is SM, please provide the missing certificates: " - + result.getErrorMessage() - + "\n"; - throw new NetworkException(errorMessage); - } else { - String errorMessage = - "\n# Not providing all the certificates to connect to the node! Please provide the certificates to connect with the block-chain.\n"; - errorMessage += - "\n* If your blockchain is NON-SM, please provide the NON-SM certificates: " - + ecdsaCryptoInfo - + ". \n"; - errorMessage += - "\n* If your blockchain is SM, please provide the SM certificates: " - + configOption.getCryptoMaterialConfig().toString() - + "\n"; - throw new NetworkException(errorMessage); - } + message += SystemInformation.getSystemInformation(); + tipsInformation += message + "\n"; + logger.warn("{}", message); + throw new NetworkException(tipsInformation); } try { + message = "<==== STEP2-1: Load certificates for sm context success..."; + tipsInformation += message + "\n"; + logger.info("{}", message); // create a new connectionManager to connect the node with the SM sslContext connManager = new ConnectionManager(configOption, handler); connManager.startConnect(configOption); connManager.startReconnectSchedule(); - } catch (NetworkException e) { - String errorMessage = e.getMessage(); - errorMessage += - "\n* If your blockchain channel config is NON-SM, please provide the NON-SM certificates: " - + ecdsaCryptoInfo - + ".\n"; - errorMessage += - "\n* If your blockchain channel config is SM, please provide the SM certificates: " - + configOption.getCryptoMaterialConfig().toString() + } catch (Exception e) { + message = + "<==== STEP2 Result: connect nodes with sm context failed for " + + e.getMessage() + "\n"; - throw new NetworkException( - errorMessage + "\n" + SystemInformation.getSystemInformation()); + message += "----------------------------\n"; + message += + "<====> Error: try to connect nodes with both ecdsa and sm context failed <====>\n"; + message += + "<====>\033[1;31m Please refer to github issue: " + + SystemInformation.connectionFaqIssueUrl + + " \033[0m\n"; + message += + "<====>\033[1;31m Please refer to fisco-docs: " + + SystemInformation.connectionFaqDocUrl + + " \033[0m\n"; + message += "----------------------------\n"; + + message += SystemInformation.getSystemInformation(); + tipsInformation += message; + logger.warn("{}, e: ", message, e); + throw new NetworkException(tipsInformation); } } catch (ConfigException e) { throw new NetworkException(e); + } catch (Exception e) { + throw new NetworkException(e); } } diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java index bd7295870..32757af54 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java @@ -19,6 +19,14 @@ import java.util.List; public class SystemInformation { + // Note: must update the version if publish new-version + private static final String sdkVersion = "2.8.1"; + public static final String connectionFaqIssueUrl = + "https://github.com/FISCO-BCOS/java-sdk/issues/536"; + public static final String connectionFaqDocUrl = + "https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/faq/connect.html"; + public static final String nettyVersion = "4.1.53.Final"; + public static class InformationProperty { private String key; private String value; @@ -47,59 +55,53 @@ public void setValue(String value) { public static final InformationProperty JAVA_VERSION = new InformationProperty("Java Version", System.getProperty("java.version")); + public static final InformationProperty JDK_DISABLED_NAMED_CURVES = + new InformationProperty( + "JDK Disabled NamedCurves", System.getProperty("jdk.disabled.namedCurves")); + public static final InformationProperty JDK_DISABLE_NATIVE_OPTION = + new InformationProperty( + "JDK DisableNative Option", System.getProperty("jdk.sunec.disableNative")); public static final InformationProperty OS_NAME = new InformationProperty("OS Name", System.getProperty("os.name")); public static final InformationProperty OS_ARCH = new InformationProperty("OS Arch", System.getProperty("os.arch")); public static final InformationProperty OS_VERSION = new InformationProperty("OS Version", System.getProperty("os.version")); - public static final InformationProperty VENDOR_NAME = - new InformationProperty("Vendor Name", System.getProperty("java.vendor")); - public static final InformationProperty VENDOR_URL = - new InformationProperty("Vendor URL", System.getProperty("java.vendor.url")); public static final InformationProperty JVM_VERSION = new InformationProperty("JVM Version", System.getProperty("java.vm.version")); - public static final InformationProperty JVM_NAME = - new InformationProperty("JVM Name", System.getProperty("java.vm.name")); - public static final InformationProperty JVM_VENDOR = - new InformationProperty("JVM Vendor", System.getProperty("java.vm.vendor")); - public static final InformationProperty JAVA_LIB_PATH = - new InformationProperty("JAVA Library Path", System.getProperty("java.library.path")); - public static final InformationProperty JDK_DISABLED_NAMED_CURVES = - new InformationProperty( - "JDK Disabled NamedCurves", System.getProperty("jdk.disabled.namedCurves")); - public static final InformationProperty JDK_DISABLE_NATIVE_OPTION = - new InformationProperty( - "JDK DisableNative Option", System.getProperty("jdk.sunec.disableNative")); - private static String systemInformation; - public static List EXPECTED_CURVES = Arrays.asList("secp256k1", "secp256r1"); + public static List EXPECTED_CURVES = Arrays.asList("secp256k1"); + public static boolean supportSecp256K1 = false; static { - systemInformation = "[System Information]:\n"; + systemInformation += "--------- System Information --------- \n"; + systemInformation = "* FISCO BCOS Java SDK Version: " + sdkVersion + "\n"; + String supportedCurves = + Security.getProviders("AlgorithmParameters.EC")[0] + .getService("AlgorithmParameters", "EC") + .getAttribute("SupportedCurves"); + if (supportedCurves.contains("secp256k1")) { + supportSecp256K1 = true; + } + for (String curve : EXPECTED_CURVES) { + if (supportedCurves.contains(curve)) { + systemInformation += "* Support " + curve + " : true\n"; + } else { + systemInformation += "* Support " + curve + " : false\n"; + } + } Field[] fields = SystemInformation.class.getDeclaredFields(); for (Field field : fields) { if (field.getType().equals(InformationProperty.class)) { try { InformationProperty property = (InformationProperty) field.get(null); systemInformation += - "[" + property.getKey() + "] : " + property.getValue() + "\n"; + "* " + property.getKey() + " : " + property.getValue() + "\n"; } catch (IllegalAccessException e) { continue; } } } - String supportedCurves = - Security.getProviders("AlgorithmParameters.EC")[0] - .getService("AlgorithmParameters", "EC") - .getAttribute("SupportedCurves"); - for (String curve : EXPECTED_CURVES) { - if (supportedCurves.contains(curve)) { - systemInformation += "[Support " + curve + "] : true\n"; - } else { - systemInformation += "[Support " + curve + "] : false\n"; - } - } } public static String getSystemInformation() { From 808868dc50b03a5e784a15e307b33e0377c97c01 Mon Sep 17 00:00:00 2001 From: ywy2090 <912554887@qq.com> Date: Fri, 29 Apr 2022 10:25:57 +0800 Subject: [PATCH 09/11] add java vendor info (#550) --- .../main/java/org/fisco/bcos/sdk/utils/SystemInformation.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java b/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java index 32757af54..b44b0bfcf 100644 --- a/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java +++ b/sdk-core/src/main/java/org/fisco/bcos/sdk/utils/SystemInformation.java @@ -69,6 +69,10 @@ public void setValue(String value) { new InformationProperty("OS Version", System.getProperty("os.version")); public static final InformationProperty JVM_VERSION = new InformationProperty("JVM Version", System.getProperty("java.vm.version")); + public static final InformationProperty JAVA_VENDOR = + new InformationProperty("JVM Vendor", System.getProperty("java.vendor")); + public static final InformationProperty JAVA_VENDOR_URL = + new InformationProperty("JVM Vendor URL", System.getProperty("java.vendor.url")); private static String systemInformation; public static List EXPECTED_CURVES = Arrays.asList("secp256k1"); public static boolean supportSecp256K1 = false; From c68f1127fc464b151620d850ccecc64917658b1b Mon Sep 17 00:00:00 2001 From: octopus <912554887@qq.com> Date: Fri, 29 Apr 2022 12:31:10 +0800 Subject: [PATCH 10/11] update java-sdk --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f05df6227..ac0cdf394 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ ext { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.java-sdk' - version = '2.8.1-SNAPSHOT' + version = '2.8.1' apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: 'idea' From 245f66be52e534cf4967673702f6e8e53baa5193 Mon Sep 17 00:00:00 2001 From: octopus <912554887@qq.com> Date: Fri, 29 Apr 2022 12:51:04 +0800 Subject: [PATCH 11/11] update ChangeLog --- Changelog.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Changelog.md b/Changelog.md index 73f130721..5f89f7dcb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,24 @@ +## v2.8.1 +(2022-04-29) +Added: +* add decodeTransactionInput to ABICodec (FISCO-BCOS#360) + +Update: +* optimize java-sdk connection error message (java-sdk#536) + +Fix: +* fix serialize ABIDefinition with fallback failed (java-sdk#302) + +---- +添加: +* ABICodec支持decodeTransactionInput + +更新: +* 优化java-sdk初始化失败错误提示 + +修复: +* 修复ABI fallback接口序列化失败的问题 + ## v2.8.0 (2021-07-27) Added: