Mastering functions in Vyper(part2)
Tags: web3, ethereum, smartcontracts, vyper
Published: 2024-05-26 16:17:24

In our [previous tutorial](https://dev.to/mosesmuwawu/mastering-vyper-functionspart1--1144), we clearly saw the structure of functions, function decorators and how functions can be called.

In today's lesson, we are going to see how the `if--elif--else` control structures could be applied in our functions. Also, this example of smart contract is going to give us more confidence of how we can use `@internal` and `@external` decorators.
```python
@internal
def add_numbers(x: int128 = 3, y: int128 = 4 ) -> int128:
    return x + y

@internal
def multiply_numbers(x: int128 = 3, y: int128 = 4) -> int128:
    return x * y

@external
def my_choice(choice: int128) -> int128:
    if choice == 1:
        return self.add_numbers()
    elif choice == 2:
        return self.multiply_numbers()
    else:
        return 0
```
In the above example, we call three functions. The first two have got the `@internal` decorator and the last one has go the `@external` decorator. As we said earlier, internal functions can only be accessed by other functions within the same contract and are called using the self object. Therefore, we use the `self.add_numbers` to call an internal function by an external function of the same contract.

## Interacting with the contract

For the purpose of this tutorial, i will use web3.py to interact locally with the smart contract we just deployed.
```python
import sys
from web3 import Web3

# Connect to BSC node (Binance Smart Chain)
bsc_node_url = 'https://data-seed-prebsc-1-s1.binance.org:8545/'  # Replace with your BSC node URL
web3 = Web3(Web3.HTTPProvider(bsc_node_url))

# Set the private key directly (For demonstration purposes only, do not hardcode in production)
private_key = 'Your_private_key'  # Replace with your actual private key
account = web3.eth.account.from_key(private_key)

# Contract ABI
contract_abi = [Copy_and_paste_your_ABI_here]

# Contract address
contract_address = web3.to_checksum_address('Your_contract_address')  # Replace with your contract's address

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


# Function to set a choice
def call_my_choice(choice):
    nonce = web3.eth.get_transaction_count(account.address)
    tx = contract.functions.my_choice(choice).build_transaction({
        'chainId': 97,  # BSC testnet
        'gas': 3000000,
        'gasPrice': web3.to_wei('5', 'gwei'),
        'nonce': nonce,
    })
    signed_tx = web3.eth.account.sign_transaction(tx, private_key)
    tx_hash = web3.eth.send_raw_transaction(signed_tx.rawTransaction)
    receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
    result = contract.functions.my_choice(choice).call()
    return result

# Prompt user for input
def main():
    choice = int(input("Enter your choice (1 or 2): "))
    
    if choice in [1, 2]:
        result = call_my_choice(choice)
        print(f'Result of the calculation: {result}')
    else:
        print("Invalid choice. Please enter 1 or 2.")

if __name__ == "__main__":
    main()

```

## Result

![Vs code terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxd7zctjrz42fwpo0r92.png)
From the result image above, it's fully evident that our smart contract is giving the expected results. When we set the choice to `1`, the answer is `7`. This because the `add_numbers` function was called which added the default values of `x` and `y`. 

When we set the choice to `2`, the answer is `12`. This because the `multiply_numbers` function was called which multiplied the default values of `x` and `y`.

For more vyper content, please follow me and like my my posts.
I will be glad for any interactions in the comment section. I am here to learn and teach. [Next Tutorial](https://dev.to/mosesmuwawu/vyper-for-loops-and-arrays-26bd)

Thank you!