diff --git a/src/main/java/org/web3j/console/project/ProjectCreator.java b/src/main/java/org/web3j/console/project/ProjectCreator.java index c055d28..a036564 100644 --- a/src/main/java/org/web3j/console/project/ProjectCreator.java +++ b/src/main/java/org/web3j/console/project/ProjectCreator.java @@ -14,11 +14,16 @@ import java.io.File; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.web3j.console.project.utills.ProjectUtils; +import org.web3j.crypto.CipherException; +import org.web3j.crypto.WalletUtils; import picocli.CommandLine; import org.web3j.console.project.utils.InputVerifier; @@ -36,9 +41,14 @@ public class ProjectCreator { final TemplateProvider templateProvider; private final String projectName; ProjectCreator(final String root, final String packageName, final String projectName) - throws IOException { + throws IOException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException { this.projectName = projectName; this.projectStructure = new ProjectStructure(root, packageName, projectName); + projectStructure.createWalletDirectory(); + final String walletName = + WalletUtils.generateNewWalletFile( + walletPassword, new File(projectStructure.getWalletPath())); + this.templateProvider = new TemplateProvider.Builder() .loadGradlewBatScript("gradlew.bat.template") @@ -57,6 +67,7 @@ public class ProjectCreator { InputVerifier.capitalizeFirstLetter(projectName))) .withPrivateKeyReplacement( s -> s.replace("", walletPassword)) + .withWalletNameReplacement(s -> s.replace("", walletName)) .build(); } diff --git a/src/main/java/org/web3j/console/project/ProjectCreatorCLIRunner.java b/src/main/java/org/web3j/console/project/ProjectCreatorCLIRunner.java index 3f9cec7..3b5540d 100644 --- a/src/main/java/org/web3j/console/project/ProjectCreatorCLIRunner.java +++ b/src/main/java/org/web3j/console/project/ProjectCreatorCLIRunner.java @@ -16,7 +16,11 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import org.web3j.crypto.CipherException; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -68,7 +72,7 @@ public void run() { private void createProject() { try { new ProjectCreator(outputDir, packageName, projectName).generate(); - } catch (final IOException e) { + } catch (final IOException | NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | CipherException e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); exitError("Could not generate project reason:" + sw.toString()); diff --git a/src/main/java/org/web3j/console/project/ProjectImporter.java b/src/main/java/org/web3j/console/project/ProjectImporter.java index a467da8..e704c34 100644 --- a/src/main/java/org/web3j/console/project/ProjectImporter.java +++ b/src/main/java/org/web3j/console/project/ProjectImporter.java @@ -12,19 +12,19 @@ */ package org.web3j.console.project; +import org.web3j.crypto.CipherException; +import picocli.CommandLine; + import java.io.File; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import picocli.CommandLine; - -import static org.web3j.console.project.InteractiveOptions.getPackageName; -import static org.web3j.console.project.InteractiveOptions.getProjectDestination; -import static org.web3j.console.project.InteractiveOptions.getProjectName; -import static org.web3j.console.project.InteractiveOptions.getSolidityProjectPath; -import static org.web3j.console.project.InteractiveOptions.userWantsTests; +import static org.web3j.console.project.InteractiveOptions.*; import static org.web3j.utils.Collection.tail; public class ProjectImporter extends ProjectCreator { @@ -36,7 +36,8 @@ public ProjectImporter( final String packageName, final String projectName, final String solidityImportPath) - throws IOException { + throws IOException, CipherException, InvalidAlgorithmParameterException, + NoSuchAlgorithmException, NoSuchProviderException { super(root, packageName, projectName); this.solidityImportPath = solidityImportPath; } diff --git a/src/main/java/org/web3j/console/project/ProjectWriter.java b/src/main/java/org/web3j/console/project/ProjectWriter.java index bc0992e..4ad057c 100644 --- a/src/main/java/org/web3j/console/project/ProjectWriter.java +++ b/src/main/java/org/web3j/console/project/ProjectWriter.java @@ -17,8 +17,14 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.util.Objects; +import org.web3j.crypto.CipherException; +import org.web3j.crypto.WalletUtils; + class ProjectWriter { final void writeResourceFile( @@ -48,4 +54,10 @@ final void importSolidityProject(final File solidityImportPath, final String des new ProjectVisitor(solidityImportPath.getAbsolutePath(), destination)); } } + + final String createWallet(String walletPassword, String walletPath) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidAlgorithmParameterException, CipherException, IOException { + return WalletUtils.generateNewWalletFile(walletPassword, new File(walletPath)); + } } diff --git a/src/main/java/org/web3j/console/project/TemplateProvider.java b/src/main/java/org/web3j/console/project/TemplateProvider.java index c7402d0..8805dbe 100644 --- a/src/main/java/org/web3j/console/project/TemplateProvider.java +++ b/src/main/java/org/web3j/console/project/TemplateProvider.java @@ -91,7 +91,7 @@ public static class Builder { private Function packageNameReplacement = s -> s; private Function projectNameReplacement = s -> s; private Function privateKeyReplacement = s -> s; - + private Function walletNameReplacement = s -> s; public Builder loadMainJavaClass(final String name) throws IOException { this.mainJavaClass = readFile(name); @@ -157,17 +157,25 @@ public Builder withPrivateKeyReplacement( return this; } + public Builder withWalletNameReplacement( + final Function walletNameReplacement) { + this.walletNameReplacement = walletNameReplacement; + return this; + } + TemplateProvider build() { return new TemplateProvider( - projectNameReplacement.apply(packageNameReplacement.apply(privateKeyReplacement.apply(mainJavaClass))), + projectNameReplacement.apply( + packageNameReplacement.apply( + privateKeyReplacement.apply( + walletNameReplacement.apply(mainJavaClass)))), solidityProject, packageNameReplacement.apply(gradleBuild), projectNameReplacement.apply(gradleSettings), gradlewWrapperSettings, gradlewBatScript, gradlewScript, - gradlewWrapperJar - ); + gradlewWrapperJar); } private String readFile(final String name) throws IOException { diff --git a/src/main/resources/Template.java b/src/main/resources/Template.java index ad6a38d..49ca849 100644 --- a/src/main/resources/Template.java +++ b/src/main/resources/Template.java @@ -1,11 +1,67 @@ package ; +import .generated.contracts.HelloWorld; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.web3j.abi.datatypes.Address; +import org.web3j.crypto.CipherException; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.evm.Configuration; +import org.web3j.evm.EmbeddedWeb3jService; +import org.web3j.evm.PassthroughTracer; +import org.web3j.protocol.Web3j; +import org.web3j.tx.gas.ContractGasProvider; +import org.web3j.tx.gas.DefaultGasProvider; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; public class { - private static String walletPassword = ""; +private static final Logger log = LoggerFactory.getLogger(.class); + + +public static void main(String[]args) throws Exception { + Credentials credentials=loadCredentials("",""); + Configuration configuration=fundAccount(credentials); + Web3j web3j=createWeb3jService(configuration); + HelloWorld helloWorld = deployHelloWorld(web3j,credentials,new DefaultGasProvider()); + callGreetMethod(helloWorld); + } + +private static Credentials loadCredentials(String walletName,String walletPassword)throws CipherException,IOException,URISyntaxException{ + String root=System.getProperty("user.dir"); + String pathToWallet=String.join(File.separator,root,"src","test","resources","wallet",walletName); + File file=new File(pathToWallet); + + log.info("Loading wallet file: "+walletName+" from resources."); + log.info("Creating credentials from from wallet."); + return WalletUtils.loadCredentials(walletPassword,file); + } + +private static Configuration fundAccount(Credentials credentials){ + // Use the Web3j CLI fund command to obtain testnet Ether + // See + log.info("Funding address "+credentials.getAddress()+" with "+10+" ether."); + return new Configuration(new Address(credentials.getAddress()),10); + + } + +private static Web3j createWeb3jService(Configuration configuration){ + // To run against a real Ethereum node use HttpService instead of EmbeddedWeb3jService and pass in the URL of your node. + log.info("Creating a web3j service locally with EmbeddedWeb3jService."); + return Web3j.build(new EmbeddedWeb3jService(configuration,new PassthroughTracer())); + } - public static void main(String[]args){ +private static HelloWorld deployHelloWorld(Web3j web3j,Credentials credentials,ContractGasProvider contractGasProvider)throws Exception{ + return HelloWorld.deploy(web3j,credentials,contractGasProvider,"Hello Blockchain World!").send(); + } - } -} \ No newline at end of file +private static void callGreetMethod(HelloWorld helloWorld)throws Exception{ + log.info("Calling the greeting method of contract HelloWorld"); + String response = helloWorld.greeting().send(); + log.info("Contract returned: "+response); + } + } \ No newline at end of file diff --git a/src/test/java/org/web3j/console/project/ProjectTest.java b/src/test/java/org/web3j/console/project/ProjectTest.java index 93d6935..89277db 100644 --- a/src/test/java/org/web3j/console/project/ProjectTest.java +++ b/src/test/java/org/web3j/console/project/ProjectTest.java @@ -12,15 +12,16 @@ */ package org.web3j.console.project; -import java.io.File; -import java.nio.file.Path; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; - +import org.web3j.console.project.utills.ProjectUtils; import org.web3j.console.project.utils.InputVerifier; +import java.io.File; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class ProjectTest { @@ -50,6 +51,7 @@ public void setUpProject(@TempDir Path tempDirPath) throws Exception { Project.builder() .withTemplateProvider(templateProviderNew) .withProjectStructure(projectStructure) + .withWallet(ProjectUtils.generateWalletPassword()) .build(); } @@ -78,9 +80,9 @@ public void fileCreationTest() { .exists(); final boolean gradleWrapperSettings = new File( - projectStructure.getWrapperPath() - + File.separator - + "gradle-wrapper.properties") + projectStructure.getWrapperPath() + + File.separator + + "gradle-wrapper.properties") .exists(); final boolean gradleWrapperJar = new File(projectStructure.getWrapperPath() + File.separator + "gradle-wrapper.jar") @@ -90,7 +92,10 @@ public void fileCreationTest() { .exists(); final boolean gradlewScript = new File(projectStructure.getProjectRoot() + File.separator + "gradlew").exists(); - + final File[] filesInWalletDirectory = + new File(projectStructure.getWalletPath()).listFiles(); + assert filesInWalletDirectory != null; + assertEquals(2, filesInWalletDirectory.length); assertTrue( mainJavaClass && greeterContract