In solving the levels of the CTF, we have seen the pitfalls of using a programming language like Solidity to develop smart contracts. To address this, one language that has been proposed is Vyper. In this lab, you will see how our initial smart contract MyContract can be written in Vyper and deployed on Ethereum. For more resources on Vyper go here. For an on-line Vyper interpreter, go here.

What you'll learn

What you'll need

We will be deploying a Vyper version of the prior Solidity contract MyContract. As before, MyContract takes in ETH (the cryptocurrency used for Ethereum transactions). Anyone can send ETH to this contract and anyone can destroy it. Upon destruction, all ETH from the contract is sent to its owner (the wallet that has deployed the contract).

# @version ^0.2.4
owner: public(address)

@external
def __init__():
    self.owner = msg.sender

@external
def v_cashOut():
    selfdestruct(self.owner)

@external
@view
def v_getBalance() -> uint256:
    return self.balance

@external
@payable
def __default__():
    pass
  1. Log into your Metamask account and ensure you are using Ropsten

  1. Visit the Remix IDE at https://remix.ethereum.org
  2. Activate the Vyper plug-in via the Plugin Manager.
  3. Click "Vyper" for your environment. The environment is similar to that of Solidity.

  1. Go back to the Remix file explorer and paste the code into a file in the IDE
  2. Click on the Vyper compiler icon to bring up the compiler. If you get a "404 Not Found" error, disable the plug-in, reload the site, then re-enable the plug-in. Continue to Option #2 if the issue persists.
  3. Click on "Remote Compiler" and compile the contract using the remote compiler.
  4. Note that for the remote compiler, the UI sends the contract code via an asynchronous HTTP request to https://vyper.live/compile . Errors are returned in JSON and can be found via the Developer Tools by clicking on the "compile" request.

  1. You may also use a local compiler to produce the EVM bytecode. To do so, perform the steps for installing the Python Vyper package in Option #2, then run vyper-serve.
  2. After compilation, click on the "Deploy & run transactions" tab
  3. Deploy the contract

Remix is one of several options for compiling Vyper contracts. Another option is via the Vyper package in Python. To try this method out. Bring up your Ubuntu 18.04 VM from prior labs. Then, create a virtual environment and install the Vyper package:

virtualenv -p python3 env
source env/bin/activate
pip install vyper==0.2.4

Then, create a file MyContract.vy that contains the MyContract code from before. Compile the contract to obtain the contract's bytecode.

vyper MyContract.vy

We will also need the contract's ABI. To generate this, perform the following:

vyper -f abi MyContract.vy

If you wish to use the "Local compiler" option of Remix, you can use the following command which will put up a web server that takes in compilation requests from the web browser running on the Remix site.

vyper-serve

Another alternative for compiling Vyper is the Vyper Online Compiler at https://etherscan.io/vyper. The site supports multiple versions of the compiler and contains links to several example Vyper contracts.

Enter your MyContract code in the "Source Code" window and then Compile it.

Scroll down to the Bytecode to show that the bytecode and ABI generated are the same as in the Python Vyper compilation. These will both be needed for subsequent steps.

Using the Bytecode and ABI from the compilation step, we will now deploy the contract via MyCrypto. Visit MyCrypto and under "Tools", navigate to "Deploy Contracts".

Ensure that you set the Network to Ropsten.

Copy the Bytecode from the previous step and "Deploy Contract" using your Metamask account

Perform the following:

Vyper builds in underflow and overflow checks on arithmetic operations when they are compiled to EVM bytecode. While this adds overhead, it can prevent disastrous errors that can lead to significant ETH being lost. To demonstrate this, consider the contract below:

# @version ^0.2.4
owner: public(address)
instructor: public(address)
commission: public(uint256)
funds: public(uint256)

@external
def __init__():
    self.owner = msg.sender
    self.instructor = 0xe9e7034AeD5CE7f5b0D281CFE347B8a5c2c53504 
    self.funds = 0
    self.commission = 1000

@external
@payable
def __default__():
    self.funds += msg.value

@external
def v_cashOut():
    send(self.instructor, self.commission)
    selfdestruct(self.owner)

@external
def v_reduceCommission():
    self.commission -= 500

@external
@view
def v_getBalance() -> uint256:
    return self.funds

Deploy the contract.

Then, call (fallback) to add funds to the contract. Use repeated calls to v_reduceCommission to show how Vyper differs from Solidity in how it handles arithmetic underflow

Congratulations!

You've created, deployed, and interacted with smart contracts written in Vyper. While the language is a safer one to use, it is not being used very prevalently yet. You can change this.