Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Smart Contract開発のための新言語Vyperの環境構築・始め方

Vyperでスマートコントラクト開発をしてみましょう。
本記事はそのための環境構築をする方法について説明しています。

Install Python3.6

Vyperを使うには、Python3.6以上が必要。
pyenvを使ってPythonをインストールする。

Install pyenv

terminal
$ brew install pyenv

.zshrcにPATHを追加

.zshrc
export PATH="$HOME/.pyenv/shims:$PATH"

Python3.6.xをインストール

terminal
$ pyenv install 3.6.7

Python3.6.xを指定

terminal
$ pyenv global 3.6.7

確認

terminal
$ python -V
# => Python 3.6.7

Install libralies

必要なライブラリをインストールしておく

terminal
$ brew install gmp leveldb

Install virtualenv

Pythonの仮想環境を使うことを公式ドキュメントは推奨しているので、virtualenvをインストールしておく。
virtualenvを使えばプロジェクトごとにPythonのバージョンやパッケージを管理できるので、他の環境を汚さずに済む。

It is strongly recommended to install Vyper in a virtual Python environment, so that new packages installed and dependencies built are strictly contained in your Vyper project and will not alter or affect your other development environment set-up.
https://vyper.readthedocs.io/en/latest/installing-vyper.html

virtualenvをインストール

terminal
$ [sudo] pip install virtualenv

確認

terminal
$ virtualenv --version
# => 16.1.0

Vyper用の仮想環境を構築する

仮想環境を作成

terminal
$ virtualenv -p python3.6 --no-site-packages vyper-test

作成した仮想環境をactivate

terminal
$ source vyper-test/bin/activate

Vyperをクローンする

terminal
$ git clone https://github.com/ethereum/vyper.git
$ cd vyper
$ make
$ make test #実行完了まで結構時間がかかる...

これで環境構築とプロジェクトのセットアップは完了。
正しくセットアップができたかどうかは、Cloneしたディレクトリで以下を実行して確認。

terminal
$ vyper examples/crowdfund.vy

Vyperについて

  • Vyperの構文はPython3と同じ(ただし、Python3の全ての構文が使えるというわけではない)
  • VyperはFileで構成されている
  • Fileはオブジェクト指向言語におけるClassのようなもの
  • 各FileはState Variables, Functions, structure-structs-typesで構成される

Functions

  • コードを実行する1つの塊(他のプログラミング言語と同様に考えればOK)
  • 必ず@public@privateを指定する

Default function

  • __defalult__で宣言する
  • functionの実行時に該当のものが見つからない時などに実行される
  • Solidityのfallback functionのようなもの
  • 必ず@public内で宣言する
  • 引数や返り値は持たすことができない
  • @payableと組み合わせた場合、Etherを送った時には必ず実行される。これは送信したEtherとユーザーアドレスの間で差分が発生しないようにするため。
  • グローバル変数msgからは以下の3つが取得できる
    • msg.sender: 送り手のaddress
    • msg.value:送信されたETHの量
    • msg.gas: 提供されたgas代

Sample Function

Vyper公式ドキュメントにあるFunctionのサンプルコード。

  • bidされたETHが最高入札額より大きかったら、入札に成功し、元の最高入札者にETHが返されるコントラクト
simple_open_auction.vy
# Open Auction

# Auction params
# Beneficiary receives money from the highest bidder
beneficiary: public(address)
auctionStart: public(timestamp)
auctionEnd: public(timestamp)

# Current state of auction
highestBidder: public(address)
highestBid: public(wei_value)

# Set to true at the end, disallows any change
ended: public(bool)

# Create a simple auction with `_bidding_time`
# seconds bidding time on behalf of the
# beneficiary address `_beneficiary`.
@public
def __init__(_beneficiary: address, _bidding_time: timedelta):
    self.beneficiary = _beneficiary
    self.auctionStart = block.timestamp
    self.auctionEnd = self.auctionStart + _bidding_time

# Bid on the auction with the value sent
# together with this transaction.
# The value will only be refunded if the
# auction is not won.
@public
@payable
def bid():
    # Check if bidding period is over.
    assert block.timestamp < self.auctionEnd
    # Check if bid is high enough
    assert msg.value > self.highestBid
    if not self.highestBid == 0:
        # Sends money back to the previous highest bidder
        send(self.highestBidder, self.highestBid)
    self.highestBidder = msg.sender
    self.highestBid = msg.value


# End the auction and send the highest bid
# to the beneficiary.
@public
def endAuction():
    # It is a good guideline to structure functions that interact
    # with other contracts (i.e. they call functions or send Ether)
    # into three phases:
    # 1. checking conditions
    # 2. performing actions (potentially changing conditions)
    # 3. interacting with other contracts
    # If these phases are mixed up, the other contract could call
    # back into the current contract and modify the state or cause
    # effects (Ether payout) to be performed multiple times.
    # If functions called internally include interaction with external
    # contracts, they also have to be considered interaction with
    # external contracts.

    # 1. Conditions
    # Check if auction endtime has been reached
    assert block.timestamp >= self.auctionEnd
    # Check if this function has already been called
    assert not self.ended

    # 2. Effects
    self.ended = True

    # 3. Interaction
    send(self.beneficiary, self.highestBid)

Others

Viperはコードの上から イベントの定義 -> 変数の型定義 -> メソッドの記述という順番を守らないとコンパイル時にエラーになります
https://blockchain.gunosy.io/entry/compare-solidity-viper

まだまだ情報が少なく、Vyper自体もアルファ版ですが、今後に期待です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?