Ejemplo n.º 1
0
        static async Task Run(string[] args)
        {
            // Parse debugger program options.
            AppOptions opts = AppOptions.ParseProcessArgs(args);

            // Compile (or retrieve from cache) the solc data for the solidity sources provided in the app options.
            GeneratedSolcData generatedSolcData = GetSolcCompilationData(opts);

            // Identify the contract to deploy from either the provided app options, or heuristically if none provided.
            // TODO: if multiple candidates are found, prompt with list to GUI for user to pick.
            EntryPointContract entryContract = EntryPointContract.FindEntryPointContract(opts, generatedSolcData);

            // Get the solc output for the entry point contract.
            SolcBytecodeInfo contractBytecode = generatedSolcData.GetSolcBytecodeInfo(entryContract.ContractPath, entryContract.ContractName);

            // Ensure contract constructor has no input parameters, and that the contract is deployable (has all inherited abstract functions implemented).
            ValidateContractConstructor(entryContract, contractBytecode);

            // Find an entry point function to call after deployment (optionally specified).
            Abi entryFunction = GetContractEntryFunction(opts, entryContract);

            // Bootstrap a local test node and rpc client with debugging/tracing enabled.
            using (LocalTestNet localTestNet = await LocalTestNet.Setup())
            {
                await PerformContractTransactions(localTestNet, entryContract, contractBytecode, entryFunction);
            }
        }
Ejemplo n.º 2
0
        static GeneratedSolcData GetSolcCompilationData(AppOptions opts)
        {
            const string GENERATED_NAMESPACE = "Meadow.DebugSol.Generated";

            // Setup codegen/compilation options.
            var solCodeGenArgs = new CommandArgs
            {
                Generate                = GenerateOutputType.Source | GenerateOutputType.Assembly,
                Namespace               = GENERATED_NAMESPACE,
                OutputDirectory         = opts.SourceOutputDir,
                AssemblyOutputDirectory = opts.BuildOutputDir,
                SolSourceDirectory      = opts.SolCompilationSourcePath
            };

            // Perform sol compilation if out-of-date.
            var solCodeGenResults = CodebaseGenerator.Generate(solCodeGenArgs, logger: msg => { });

            // Load compiled assembly.
            var generatedAsm = AppDomain.CurrentDomain.Load(
                File.ReadAllBytes(solCodeGenResults.CompilationResults.AssemblyFilePath),
                File.ReadAllBytes(solCodeGenResults.CompilationResults.PdbFilePath));

            // Load solc data from assembly resources.
            return(GeneratedSolcData.Create(generatedAsm));
        }
Ejemplo n.º 3
0
        public void TestCompiledAssembly()
        {
            var solCodeGenArgs = new CommandArgs
            {
                OutputDirectory         = _outputDir,
                AssemblyOutputDirectory = _assemblyOutputDir,
                SolSourceDirectory      = _sourceDir,
                Generate  = GenerateOutputType.Source | GenerateOutputType.Assembly,
                Namespace = _namespace
            };

            var solCodeGenResults = CodebaseGenerator.Generate(solCodeGenArgs);

            Assembly loadedAssembly;
            var      assemblyBytes = File.ReadAllBytes(solCodeGenResults.CompilationResults.AssemblyFilePath);
            var      pdbBytes      = File.ReadAllBytes(solCodeGenResults.CompilationResults.PdbFilePath);

            loadedAssembly = Assembly.Load(assemblyBytes, pdbBytes);

            var solcDataParser = GeneratedSolcData.Create(loadedAssembly);
            var data           = solcDataParser.GetSolcData();
        }
Ejemplo n.º 4
0
        public void FullEndToEnd()
        {
            // Find the solution directory (start at this assembly directory and move up).
            string solutionDir = Util.FindSolutionDirectory();

            string testAppDir    = Path.Combine(solutionDir, "Meadow.SolCodeGen.TestApp");
            string testProjPath  = Path.Combine(testAppDir, "Meadow.SolCodeGen.TestApp.csproj");
            string solCodeGenDir = Path.Combine(solutionDir, "Meadow.SolCodeGen");

            string outputDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()) + Path.DirectorySeparatorChar;

            // Build the Meadow.SolCodeGen project get its generated nupkg file for install.
            string packageDir;
            string packageVer = DateTime.UtcNow.ToString("yyMM.ddHH.mmss", CultureInfo.InvariantCulture);

            void BuildPackage()
            {
                var output = RunDotnet("build", solCodeGenDir, "-c", "Release", "--no-incremental", "/p:PackageVersion=" + packageVer, "-o", outputDir);
                // Successfully created package 'C:\Users\matt\Projects\Meadow.Core\Meadow.SolCodeGen\bin\Debug\Meadow.SolCodeGen.0.2.1.nupkg'.
                var pubLine = output.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Last(line => line.Contains(".nupkg", StringComparison.OrdinalIgnoreCase) && line.Contains("Meadow.SolCodeGen", StringComparison.OrdinalIgnoreCase) && line.Contains("created package", StringComparison.OrdinalIgnoreCase));

                packageDir = pubLine.Split("created package '")[1].Split("Meadow.SolCodeGen.")[0];
            }

            BuildPackage();

            // Delete any existing generated contracts.
            string generatedContractsDir = Path.Combine(testAppDir, "GeneratedContracts");

            if (Directory.Exists(generatedContractsDir))
            {
                Directory.Delete(generatedContractsDir, recursive: true);
            }

            // Install the Meadow.SolCodeGen nupkg into the test project.
            void InstallPackage()
            {
                RunDotnet("add", testProjPath, "package", "-s", outputDir, /*packageDir,*/ "-v", packageVer, "Meadow.SolCodeGen");
            }

            InstallPackage();

            // Build the test project (which triggers code generation).
            string compiledAssemblyPath;

            void CompileGeneratedCode()
            {
                // First build command trigger the code generation, but the generated source files do not
                // get added the assembly.
                var output = RunDotnet("build", testProjPath, "-c", "Release", "--no-incremental");

                var lines        = output.Split(new char[] { '\n', '\r' });
                var assemblyLine = lines.Last(p => p.Contains("Meadow.SolCodeGen.TestApp -> ", StringComparison.OrdinalIgnoreCase));

                compiledAssemblyPath = assemblyLine.Split("Meadow.SolCodeGen.TestApp -> ")[1];
            }

            CompileGeneratedCode();

            // Load the compiled assembly at runtime and use reflection to test the generated types.
            void LoadCompiledAssembly()
            {
                var compiledAsm = Assembly.LoadFrom(compiledAssemblyPath);

                var solcData = GeneratedSolcData.Create(compiledAsm).GetSolcData();

                Assert.True(solcData.SolcBytecodeInfo.Length > 0);
                Assert.True(solcData.SolcSourceInfo.Length > 0);

                // var compiledAsm = AssemblyLoadContext.Default.LoadFromAssemblyPath(compiledAssemblyPath);

                var exampleContractType = compiledAsm.GetType("Meadow.SolCodeGen.TestApp.ExampleContract", throwOnError: true);

                Type addressType       = GetTypeByName("Meadow.Core", "Meadow.Core.EthTypes.Address");
                Type jsonRpcClientType = GetTypeByName("Meadow.JsonRpc.Client", "Meadow.JsonRpc.Client.JsonRpcClient");
                Type baseContractType  = GetTypeByName("Meadow.Contract", "Meadow.Contract.BaseContract");

                object contractAddr = Activator.CreateInstance(addressType, "0x0");
                object fromAccount  = Activator.CreateInstance(addressType, "0x0");
                var    rpcClient    = JsonRpcClient.Create(new Uri("http://localhost"), ArbitraryDefaults.DEFAULT_GAS_LIMIT, ArbitraryDefaults.DEFAULT_GAS_PRICE);

                var     atMethod       = exampleContractType.GetMethod("At", BindingFlags.Static | BindingFlags.Public);
                dynamic contractAtTask = atMethod.Invoke(null, new object[] { rpcClient, contractAddr, fromAccount });

                object instance = contractAtTask.Result;

                Assert.True(baseContractType.IsAssignableFrom(instance.GetType()));
            }

            LoadCompiledAssembly();

            // Cleanup - remove nuget package
            void UninstallNugetPackage()
            {
                RunDotnet("remove", testProjPath, "package", "Meadow.SolCodeGen");
            }

            UninstallNugetPackage();

            // Cleanup - delete generated contact source files
            if (Directory.Exists(generatedContractsDir))
            {
                Directory.Delete(generatedContractsDir, recursive: true);
            }
        }