我导入了web3j3.31的jar包,但是写依赖implementation 'org.web3j:core:3.3.1-android'运行就会出错,报More than one file was found with OS independent path 'solidity/build.sh'。不依赖可以运行,但运行到Keys.createEcKeyPair()就会崩溃,大神能帮帮忙吗。
2条回答 默认 最新
- Tony-老师 2019-02-12 23:34关注
// bitcoinj compile 'org.bitcoinj:bitcoinj-core:0.14.3' // 以太坊开发库 compile 'org.web3j:core:3.3.1-android' 你这边是创建钱包?我这边创建是这样处理的,没有问题:
package ai.ctxc.core.wallet; import ai.ctxc.core.CTXCErrorHandler; import ai.ctxc.core.CTXCException; import ai.ctxc.core.Requires; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; import java.util.List; import org.bitcoinj.crypto.ChildNumber; import org.bitcoinj.crypto.DeterministicKey; import org.bitcoinj.crypto.HDKeyDerivation; import org.bitcoinj.crypto.MnemonicCode; import org.bitcoinj.crypto.MnemonicException; import org.bitcoinj.wallet.DeterministicSeed; import org.web3j.crypto.CipherException; import org.web3j.crypto.Credentials; import org.web3j.crypto.ECKeyPair; import org.web3j.crypto.Keys; import org.web3j.crypto.Wallet; import org.web3j.crypto.WalletFile; import org.web3j.crypto.WalletUtils; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.utils.Numeric; import waterhole.commonlibs.utils.IOUtils; import waterhole.commonlibs.utils.StringUtils; /** * Wallet manager implements. * * @author kuang on 2018/09/28. */ final class WalletManager implements IWalletManager { private final DBInterface dbInterface = DBInterface.instance(); @Override public boolean insertWallet(CTXCWallet wallet) throws CTXCException { return dbInterface.insertWallet(wallet); } @Override public CTXCWallet getCurrentWallet() { return dbInterface.getCurrentWallet(); } @Override public List<CTXCWallet> getAllWallets() { return dbInterface.getAllWallets(); } @Override public CTXCWallet getWallet(String address) { return dbInterface.getWallet(address); } @Override public boolean setIsCurrent(String address) { return dbInterface.setIsCurrent(address); } @Override public boolean setIsBackup(String address) { return dbInterface.setIsBackup(address); } @Override public boolean setWalletName(String address, String name) { return dbInterface.setWalletName(address, name); } @Override public boolean setPwdReminder(String address, String pwdReminder) { return dbInterface.setPwdReminder(address, pwdReminder); } @Override public boolean setTokens(String address, String tokens) { return dbInterface.setTokens(address, tokens); } @Override public boolean deleteWallet(String address) { return dbInterface.deleteWallet(address); } private static String[] checkPath(@ETH_TYPE String path) throws CTXCException { if (Requires.isNull(path)) throw CTXCException.newNullInstance("path"); if ((!path.startsWith("m") && !path.startsWith("M"))) throw new CTXCException("path does not start with m or M, see WalletService.ETH_TYPE"); String[] array = StringUtils.fastSplit(path, '/'); if (array == null || array.length <= 1) throw new CTXCException("path format error, see WalletService.ETH_TYPE"); return array; } private static String generateNewWalletName() { char letter1 = (char) (int) (Math.random() * 26 + 97); char letter2 = (char) (int) (Math.random() * 26 + 97); return String.valueOf(letter1) + String.valueOf(letter2) + "_wallet"; } private void insertWallet(CTXCWallet wallet, String walletName, String passwordHint, boolean isBackup) throws CTXCException { if (!Requires.isNull(wallet)) { wallet.setName(walletName); wallet.setPwdReminder(passwordHint); wallet.setIsCurrent(true); wallet.setIsBackup(isBackup); insertWallet(wallet); } } @Override public CTXCWallet createWallet(String path, String walletName, String password, String passwordHint) throws CTXCException { String[] pathArray = checkPath(path); /* * Holds the seed bytes for the BIP32 deterministic wallet algorithm, inside a * {@link DeterministicKeyChain}. The purpose of this wrapper is to simplify the encryption * code. */ long time = System.currentTimeMillis() / 1000; SecureRandom random = SecureRandomUtils.secureRandom(); DeterministicSeed seed = new DeterministicSeed(random, 128, "", time); CTXCWallet wallet = createWallet(seed, pathArray, password); insertWallet(wallet, walletName, passwordHint, false); return wallet; } @Override public CTXCWallet importWalletByKeystore(String keystore, String password) throws CTXCException { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); ECKeyPair keyPair; try { WalletFile walletFile = objectMapper.readValue(keystore, WalletFile.class); keyPair = Wallet.decrypt(password, walletFile); } catch (IOException e) { throw new CTXCException(CTXCErrorHandler.INVALID_KEYSTORE); } catch (CipherException e) { throw new CTXCException(true, e); } String newWalletName = generateNewWalletName(); CTXCWallet wallet = createWallet(password, keyPair); insertWallet(wallet, newWalletName, "", true); return wallet; } @Override public CTXCWallet importWalletByMnemonicWords(String path, List<String> list, String password, String passwordHint) throws CTXCException { String[] pathArray = checkPath(path); try { MnemonicCode.INSTANCE.check(list); } catch (MnemonicException e) { throw new CTXCException(CTXCErrorHandler.INVALID_MNEMONIC); } long time = System.currentTimeMillis() / 1000; DeterministicSeed seed = new DeterministicSeed(list, null, "", time); String newWalletName = generateNewWalletName(); CTXCWallet wallet = createWallet(seed, pathArray, password); insertWallet(wallet, newWalletName, passwordHint, true); return wallet; } @Override public CTXCWallet importWalletByPrivateKey(String privateKey, String password, String passwordHint) throws CTXCException { if (!WalletUtils.isValidPrivateKey(privateKey)) throw new CTXCException(CTXCErrorHandler.INVALID_PRIVATE_KEY); privateKey = privateKey.toLowerCase(); ECKeyPair ecKeyPair; try { Credentials credentials = Credentials.create(privateKey); ecKeyPair = credentials.getEcKeyPair(); } catch (Exception e) { throw new CTXCException(true, e); } String newWalletName = generateNewWalletName(); CTXCWallet wallet = createWallet(password, ecKeyPair); insertWallet(wallet, newWalletName, passwordHint, true); return wallet; } @Override public String exportKeystore(String address) throws CTXCException { CTXCWallet wallet = getWallet(address); if (Requires.isNull(wallet)) throw new CTXCException("cannot find the wallet in db"); return wallet.getKeystore(); } @Override public String exportPrivateKey(String address, String password) throws CTXCException { ECKeyPair ecKeyPair = getEcKeyPair(address, password); if (!Requires.isNull(ecKeyPair)) return Numeric.toHexStringNoPrefixZeroPadded(ecKeyPair.getPrivateKey(), Keys.PRIVATE_KEY_LENGTH_IN_HEX); return null; } @Override public boolean verifyPassword(String address, String password) throws CTXCException { ECKeyPair ecKeyPair = getEcKeyPair(address, password); return ecKeyPair != null; } private ECKeyPair getEcKeyPair(String address, String password) throws CTXCException { CTXCWallet wallet = getWallet(address); if (Requires.isNull(wallet)) throw new CTXCException("cannot find the wallet in db"); ECKeyPair ecKeyPair; try { ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); WalletFile walletFile = objectMapper.readValue(wallet.getKeystore(), WalletFile.class); ecKeyPair = Wallet.decrypt(password, walletFile); } catch (CipherException | IOException e) { throw new CTXCException(true, e.getMessage()); } return ecKeyPair; } private static CTXCWallet createWallet(DeterministicSeed ds, String[] pathArray, String password) throws CTXCException { byte[] seedBytes = ds.getSeedBytes(); if (Requires.isNull(seedBytes)) throw CTXCException.newNullInstance("DeterministicSeed getSeedBytes"); List<String> mnemonic = ds.getMnemonicCode(); DeterministicKey dkKey = HDKeyDerivation.createMasterPrivateKey(seedBytes); for (int i = 1; i < pathArray.length; i++) { ChildNumber childNumber; if (pathArray[i].endsWith("'")) { int number = Integer.parseInt(pathArray[i].substring(0, pathArray[i].length() - 1)); childNumber = new ChildNumber(number, true); } else { int number = Integer.parseInt(pathArray[i]); childNumber = new ChildNumber(number, false); } dkKey = HDKeyDerivation.deriveChildKey(dkKey, childNumber); } ECKeyPair keyPair = ECKeyPair.create(dkKey.getPrivKeyBytes()); CTXCWallet wallet = new CTXCWallet(); try { WalletFile walletFile = Wallet.createLight(password, keyPair); String address = Keys.toChecksumAddress(walletFile.getAddress()); wallet.setAddress(address.toLowerCase()); ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); String keystore = objectMapper.writeValueAsString(walletFile); wallet.setKeystore(keystore); wallet.setMnemonics(wallet.getSaltPassword(password), mnemonic); } catch (CipherException | JsonProcessingException e) { throw new CTXCException(true, e.getMessage()); } return wallet; } private static CTXCWallet createWallet(String password, ECKeyPair ecKeyPair) throws CTXCException { try { WalletFile walletFile = Wallet.createLight(password, ecKeyPair); byte[] bytes; ByteArrayOutputStream baos = null; try { baos = new ByteArrayOutputStream(); ObjectMapperFactory.getObjectMapper().writeValue(baos, walletFile); bytes = baos.toByteArray(); baos.flush(); } finally { IOUtils.closeSafely(baos); } CTXCWallet wallet = new CTXCWallet(); String address = Keys.toChecksumAddress(walletFile.getAddress()); wallet.setAddress(address.toLowerCase()); wallet.setKeystore(new String(bytes)); return wallet; } catch (Exception e) { throw new CTXCException(true, e.getMessage()); } } }
解决 1无用