pythonsyntax-errorexecweb3pybrownie

python exec() raises SyntaxError exception when passing an object inside the string argument


So I am currently trying to deploy my smart contract using a brownie script as shown in the code below:

from brownie import accounts, network
import sys

sys.path.append("../")
import globalVars

def main():

    import_str = "from {0} import {1}".format("brownie", globalVars.contractName)
    exec(import_str)

    network.connect('development')
    accounts.add()
    account = accounts[0]
   
    transactDetails = {'from' : account}
    prompt = f"contract_instance = {globalVars.contractName}.deploy( 
                         *globalVars.constructorInputs , {transactDetails} )"
    exec(prompt)

    return contract_instance

Meanwhile, when python interprets exec(prompt), it raises this error:

File "<string>", line 1
    contract_instance = Voting.deploy( * globalVars.constructorInputs , {'from': <Account '0x66aB6D9362d4F35596279692F0251Db635165871'>} )
                                                                                 ^
SyntaxError: invalid syntax

I was expecting the smart contract to be deployed like in standard manner like in this code:

from brownie import accounts, network, Voting
import sys

sys.path.append("../")
import globalVars

def main():

    network.connect("development")
    accounts.add()
    account = accounts[0]
    print(globalVars.constructorInputs)
    contract_instance = Voting.deploy( * globalVars.constructorInputs ,  {'from' : account} )
    
    
    return contract_instance

I tried troubleshooting but could not find a solution, could someone please help!


Solution

  • Don't use exec at all. Use something like

    import brownie
    import globalVars
    
    def main():
    
        contract = getattr(brownie, globalVars.contractName)
    
        network.connect('development')
        accounts.add()
        account = accounts[0]
       
        transactDetails = {'from' : account}
        contract_instance = contract.deploy( 
                             *globalVars.constructorInputs , **transactDetails)
    
        return contract_instance