Example #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);
            }
        }
Example #2
0
        static void ValidateContractConstructor(EntryPointContract entryContract, SolcBytecodeInfo contractBytecode)
        {
            // Validate that there is a constructor.
            var constructor = entryContract.Abi.FirstOrDefault(f => f.Type == AbiType.Constructor);

            if (constructor == null)
            {
                throw new Exception($"The contract '{entryContract.ContractName}' does not have a constructor.");
            }

            // Validate that the constructor does not have any input parameteters.
            if (constructor.Inputs?.Length > 0)
            {
                throw new Exception($"The contract '{entryContract.ContractName}' constructor cannot have input parameters.");
            }

            // Validate that contract is not "abstract" (does not have unimplemented function).
            if (string.IsNullOrEmpty(contractBytecode.Bytecode))
            {
                throw new Exception($"The contract '{entryContract.ContractName}' does not implement all functions and cannot be deployed.");
            }
        }
Example #3
0
        static async Task PerformContractTransactions(LocalTestNet localTestNet, EntryPointContract entryContract, SolcBytecodeInfo contractBytecode, Abi entryFunction)
        {
            // Perform the contract deployment transaction
            var deployParams = new TransactionParams
            {
                From     = localTestNet.Accounts[0],
                Gas      = ArbitraryDefaults.DEFAULT_GAS_LIMIT,
                GasPrice = ArbitraryDefaults.DEFAULT_GAS_PRICE
            };
            var contractAddress = await ContractFactory.Deploy(localTestNet.RpcClient, HexUtil.HexToBytes(contractBytecode.Bytecode), deployParams);

            var contractInstance = new ContractInstance(
                entryContract.ContractPath, entryContract.ContractName,
                localTestNet.RpcClient, contractAddress, localTestNet.Accounts[0]);


            // If entry function is specified then send transasction to it.
            if (entryFunction != null)
            {
                var callData     = EncoderUtil.GetFunctionCallBytes($"{entryFunction.Name}()");
                var ethFunc      = EthFunc.Create(contractInstance, callData);
                var funcTxParams = new TransactionParams
                {
                    From     = localTestNet.Accounts[0],
                    Gas      = ArbitraryDefaults.DEFAULT_GAS_LIMIT,
                    GasPrice = ArbitraryDefaults.DEFAULT_GAS_PRICE
                };
                await ethFunc.SendTransaction(funcTxParams);
            }
        }