DEV Community

Cover image for How to compile, deploy and interact with smart contracts using Apeworx(ape) and VS Code.
Muwawu Moses
Muwawu Moses

Posted on

How to compile, deploy and interact with smart contracts using Apeworx(ape) and VS Code.

Today, we are going to write our smart contracts using Vyper and the Apeworx framework. We are going to connect to the ethereum network using Sepolia via Alchemy.

Prerequisites

  • python version later than 3.8
  • pip installed
  • metamask wallet already set up

Procedure

First, we are going to set up the development environment. Remember, when using windows, it's recommended to use WSL2 for development purposes. I am using Ubuntu for this tutorial.

  • Let's create a project folder named testing. mkdir testing
  • Then, navigate through the folder: cd testing
  • Create a virtual environment named .venv python3 -m venv .venvand then, run code . to open vs code. In the VS code terminal, activate the virtual environment by running source .venv/bin/activate

Next, we are going to install apeworx and all dependencies through a single command: pip install eth-ape'[recommended-plugins]'.

After a successful installation, we are now going to connect our project to the metamask wallet through creation of what is called an account.

  • Run ape accounts import meta_wallet In the above command, we have named our account 'meta_wallet'(you can name it anything you want). You'll then be prompted to enter private key and create a passphrase to encrypt your account.
Enter Private Key: 
Create Passphrase to encrypt account: 
Repeat for confirmation: 
Enter fullscreen mode Exit fullscreen mode

To enter private key, go to your metamask wallet and copy a private key and securely save it somewhere. Paste it into the terminal and please note that you won't be able to see it so, don't paste more than once.
For a passphrase, create something that you won't forget.
To confirm if your account has been imported, run ape accounts list.

One more last thing to do for a successful set up is adding the Alchemy-api-key to our settings.
Run code ~/.bashrc to open the bashrc file. In this file, add the following line of code("YOUR_ALCHEMY_API_KEY" with the actual api key from alchemy) to the bottom end of it: export WEB3_ALCHEMY_API_KEY="YOUR_ALCHEMY_API_KEY"

Note: If you are running your program on a testnet, please make sure that your alchemy ethereum app is a testnet not a mainnet.

Good that we are now done with the set up process, let's go for the actual business.
We shall start by initializing a project by running ape init.
This creates creates a project structure including; .build(for storage of artifacts), scripts folder, tests folder, contracts folder, and the ape.config-yaml file.

First, in the contracts folder, let's create a new file named hello.vy and add the following code which returns "Helloo, World!".

#pragma version ^0.3.10

# A simple Vyper contract
@external
def say_hello() -> String[14]:
    return "Helloo, World!"
Enter fullscreen mode Exit fullscreen mode

Next is to compile our code: ape compile.
Please note that after running the above command, a new file named hello.json is automatically created in the .build folder. This file contains the abi and bytcode of the contract.

Apart from abi, for our web3 library to be able interact with the deployed smart contract, it will need what we call a contract address and network. So, our next task is to create a another file named deploy_hello.py in the scripts folder for serving two purposes:

  1. Deploying script
  2. Saving or adding the contact address and network details to the already existing hello.json file.
import json
from ape import project, accounts

def main():
    # Load your account
    account = accounts.load('meta_wallet')

    # Deploy the contract
    contract = project.hello.deploy(sender=account)

    # Save the deployment details
    build_file = '.build/hello.json'
    with open(build_file, 'r') as file:
        contract_json = json.load(file)

    contract_json['networks'] = {
        'sepolia': {
            'address': contract.address
        }
    }

    with open(build_file, 'w') as file:
        json.dump(contract_json, file, indent=4)

    print(f"Contract deployed at address: {contract.address}")

if __name__ == "__main__":
    main()

Enter fullscreen mode Exit fullscreen mode

Run ape run deploy_hello --network ethereum:sepolia:alchemy .
Congratulations if your deployment was a successful one.

Lastly, we are going to interact with our deployed smart contract using web3.py library. Create a scripts/interact_hello.py file and add the following code:

import json
from web3 import Web3

# Define the path to the contract build file
contract_build_file = '.build/hello.json'

# Load the contract ABI and address from the build file
try:
    with open(contract_build_file, 'r') as file:
        contract_json = json.load(file)
        contract_abi = contract_json.get('abi')

        # Ensure the ABI is loaded
        if not contract_abi:
            raise ValueError("ABI not found in the contract build file.")

        # Check for the 'networks' key and retrieve the address
        networks = contract_json.get('networks')
        if not networks:
            raise KeyError("Networks key not found in the contract build file.")

        # Replace 'sepolia' with the actual network name used during deployment
        network_details = networks.get('sepolia')
        if not network_details:
            raise KeyError("Network details for 'sepolia' not found.")

        contract_address = network_details.get('address')
        if not contract_address:
            raise ValueError("Contract address not found in the network details.")


except (IOError, ValueError, KeyError) as e:
    print(f"Error loading contract build file: {e}")
    exit(1)

# Connect to the Ethereum network (e.g., Sepolia via Alchemy)
provider_url = 'Your_alchemy_url'
web3 = Web3(Web3.HTTPProvider(provider_url))

# Ensure the connection is successful
if not web3.is_connected():
    print("Failed to connect to the Ethereum network.")
    exit()

# Create a contract instance
contract = web3.eth.contract(address=contract_address, abi=contract_abi)

# Call the hello() function
def call_hello():
    try:
        message = contract.functions.say_hello().call()
        print(f"Contract message: {message}")
    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == "__main__":
    call_hello()

Enter fullscreen mode Exit fullscreen mode

Run python scripts/interact_hello.py
Output: Contract message: Helloo, World!

Wow! we have had our smart contract compiled, deployed and interacted with all in vs code. If you found this article helpful, don't hesitate to give me a like and please follow for more. Thank You!

Top comments (0)