Ethereum <超初心者の方向け>Mistを用いたコントラクト開発入門
この記事は Ethereum Advent Calendar 2017 の12日目の記事です。
初めましての方は初めまして
お久しぶりですの方は非常にお久しぶりです。
どーも、おっさんSEのぴんくです。
しばらくブログは書いておりませんでしたが、Ethereum Advent Calendarに参加するため、一時的に復活しました。
今日は、Ethereum 超初心者の方向けにMistを用いたコントラクト開発の手順の一部をご紹介します。
私自身も経験期間約1ヶ月と少しの超初心者ですので、有識者の方から見て拙い部分等有りましたら是非ご指摘下さい。
はじめに
多くのEthereumのコントラクト開発に関するサイトや書籍では、
- ブロックチェーンやEthereumに関する説明
- Ethereumクライアント「Geth(正式名称はgo-ethereum)」の導入
- Gethの操作
- マイニングの方法
等の内容を経由して、ようやくsolidity言語を用いたコントラクト開発の内容が始まります。
ブロックチェーンやEthereumに関する知識もGethの操作もEthereumへの理解を深めるためには非常に重要ですが、この時点で挫折してしまう方も数多くいらっしゃるのではないでしょうか?
(かく言う私も挫折しかけた一人ですw)
なので今回の手順はそういった手順をすっ飛ばして、プライベートネット上でコントラクトを動かしてみようといったある種の体験版的な内容です。
※他のプログラム入門の開発環境のセットアップ、コンパイル、プログラム実行くらいの水準と考えて頂けるとなんとなくイメージが沸くかと思います。
Ethereum初心者の方々がEthereum、Mist、コントラクト等の挙動に触れてみて、その楽しさに気付いて頂ければ幸いです。
※注1、Ethereum上級者の方々には少々退屈な内容になると思います。
※注2、Ethereum初心者の方々は興味が芽生えたらちゃんと基本も勉強しましょう♪
体験手順
当手順は以下の内容で進めていきます。
※私はwindowsOSを使用してますのでwindowsOSベースでの説明になりますが、Mistダウンロード後の手順はMistのGUI上のみの挙動なのでその他のOSでもそんなに変わりは無いと思います。
Mistのダウンロード
以下のサイトからダウンロード可能です。
https://github.com/ethereum/mist/releases
上記リンクから以下のダウンロードページに遷移しますので、ページをググっと下へスクロールして、自分の環境に対応するMistのzipファイルをダウンロードして下さい。
※上記の例はWindowsOS64bit用zipのダウンロードです。
※本格的に利用するのであればEthereum Walletもあった方が良いかもしれませんが、今回はスルーします。
Ethereum Walletをインストールすると当手順と異なる動きになる部分が有りますのでご注意下さい。
Mistのセットアップ
ダウンロードしたzipファイルを解凍し、任意のフォルダに配置して下さい。
配置後、フォルダにあるMist.exeを起動して下さい。
起動するとしばらく(長い時は5~10分)以下のような状態になりますので少々お待ち下さい。
しばらく待つと以下の画面が表示されます。
「メインネット使う?」「テストネット使う?」といった事が表示されていますが、今回はプライベートネットしか使わないのでどちらでも構いません。
画像は「メインネット使う?」の方を選択しています。
次の画面はスキップで構いません。
※Ethereumのプレセール参加者用の入力らしいです。
次にアカウント用のパスワードを入力してSKIP(パスワード入力後はNEXT)をクリックして下さい。
※メインネットやテストネットを使用する場合は非常に重要なパスワードですので、保存をお勧めしますが、今回は使用しません。
この後、以下の確認メッセージが表示されますが、「キーストアフォルダのバックアップをしっかりね!」といった内容なのでOKで進んで問題ありません。
先ほど入力したパスワードから生成されたアカウントアドレスが表示されます。
※メインネット(先頭画面でテストネットを選択していた場合はテストネット)に作成された正式なアドレスのため、保存をお勧めしますが、今回は使用しません。
NEXTをクリックして下さい。
以下の画面が表示されますので、「LAUNCH APPLICATION!」をクリックして下さい。
以下の画面が表示されれば、セットアップは完了です。
※画面下部に警告が出ますが「Ethereum Walletがセットアップされていない」といったメッセージのため、今回は関係ありません。邪魔な場合は「Close this messege」ボタンで消して下さい。
プライベートネットへの接続
セットアップが完了したらプライベートネット(自分のPC上に作成されるネットワーク)へ接続します。
Develop>ネットワーク>Solo NetWorkを選択して下さい。
アカウントの作成
ウォレットの画面で「アカウントを追加」をクリックして下さい。
「Create New Account」をクリックして下さい。
パスワードの入力を求められるため、パスワードを入力しまて「OK」をクリックして下さい。
※当手順は2回繰り返し。2度目は確認用です。
メッセージが表示されますが、「キーストアフォルダのバックアップをしっかりね!」といった内容なのでOKで進んで問題ありません。
生成されたアドレスが表示されますので、画面を閉じて下さい。
メイン画面に生成されたアカウントが表示されれば完了です。
マイニング
まず「マイニングとは」という説明をここでするべきですが、説明を始めると非常に長く(それだけで一記事分以上に)なるため、ここでは割愛します。
気になる方は「イーサリアム マイニングとは」とGoogle先生に聞いてみて下さい。
本来であればマイニングを行うためには前述の「geth」のようなイーサリアムクライアントが必要となりますが、Mistではプライベートネットワーク上に限り、ボタン一つでマイニングを行う事が出来ます。
Mist上部のツールバーから「Develop」>「マイニングを始める」を選択して下さい。
これだけでマイニングが始まります。
先ほど作成したプライベートネット用のアカウントのEther残高がどんどん増えていきます。
どんどん増えていきます。
これがメインネットのEtherであれば、あっという間に億万長者になれますが、これはプライベートネット用のEtherであり、メインネットのEtherとしては利用できません。
※放っておくとどんどんEtherが増えていき、疑似的にテストETH長者になれるので楽しいのですが、コントラクトをデブロイ、または操作する際以外には不要なため、普段はマイニングを止めておくことをお勧めします。
コントラクトのデプロイ
本来であれば、デプロイの前にsolidity言語を用いてコントラクトのコーディング、コントラクトのコンパイル等の手順が必要ですが、今回は気軽な体験版という事でショートカットを行います。
Mist画面のコントラクトという部分をクリックして下さい。
以下の画面が表示されますので、ページを軽く下へスクロールして下さい。
カスタムトークンの説明文章内の「カスタムトークンコントラクトの例トークン」という青地の部分をクリックして下さい。
すると以下のような画面が展開し、ソースコードが表示されます。
これはsolidity言語を用いて記述されたトークンコントラクトのサンプルコードです。
このコードはERC20という規格に沿って組まれており、トークンコントラクトの挙動を知る上では非常に参考になります。
細かく話し出すと一記事どころかシリーズ記事レベルの内容になりますのでまたまた割愛します。
興味のある人は「ERC20 solidity」等をGoogle先生に聞いてみて下さい。
少々脱線しましたが、表示されたサンプルコードを最初から最後までコピーして下さい。
コピー後、左側のサイドバーの緑色のボタンをクリックし、元の画面に戻りましょう。
元の画面の「新しいコントラクトを配置」をクリックして下さい。
以下のような画面に遷移するので、FROMの部分に先ほど作成したアカウントとアカウントの保有Etherが表示されていることを確認して下さい。
※Etherを保有していない場合、デプロイ時にエラーとなりますので、0Etherの場合は前述のマイニングの手順を見直して下さい。
またまた軽く下にスクロールすると以下のような部分が有りますので赤枠で囲んでいる部分に先ほどコピーしたサンプルコードを貼り付けて下さい。
コピー後、画面右側のリストから「Token ERC 20」を選択して下さい。
※ここで選択可能となる名称はスペースで区切られていますが、貼り付けたコード内のコントラクトの名称(「contract TokenERC20 {」の部分)です。自分で独自にコーディングする際はご留意下さい。
コントラクトを選択するとコントラクトのコンストラクタの引数を入力する項目が表示されます。
以下の例では、
initial Supply:初期供給量(トークンの初期発行数)
token Name :トークンの名称
token Symbol:トークンのシンボル(単位表記。以下の例の場合、保有時に1000 OTと表示されます)
コンストラクタの引数を入力後、再び画面を下にスクロールし、「配置」をクリックして下さい。
パスワードの入力を求められるため、アカウント作成時に登録したパスワードを入力し、「SEND TRANSACTION」をクリックしてください。
ウォレット画面の下部に送信したトランザクションが表示されます。
プライイベートネット上のため、1分程度でトランザクションは承認され、デプロイが完了します。(メインネット、テストネットではもっと時間が掛かります)
※マイニング実行中でない場合、いつまで待っても進みません。その場合は前述の手順でマイニングを開始して下さい。
完了すると以下のような表示となります。
完了後、メインアカウントの画面を表示すると以下のようにデプロイしたトークンの初期発行量がメインアカウントに付与されています。
※コントラクトのコンストラクタ(初期化処理のようなもの)内で、呼び出したアカウントに引数で指定した初期保有量をメインアカウントが初期供給量(トークンの初期発行数)分のトークンを保有させるという処理があるため、このような結果となります。コードの内容によって結果は異なりますので、その点ご留意ください。
コントラクトの処理呼び出し
デプロイが完了したら、コントラクトを動かしてみましょう。
最初に動作確認用にアカウントをもう一つ追加して下さい
。手順はメインアカウント作成と同様ですので、省略します。
動作確認用にアカウント追加後、メインアカウントと作成したアカウントのアドレスをコピーして下さい。
アドレスは各アカウントの画面にてアカウント名の下に表示される「0X」から始まる文字列です。
左の赤枠部分→アカウントアドレス
右の赤枠部分→アドレスのコピーボタン
次にコントラクト画面にて前述の手順で追加されたコントラクトを選択します。
以下のような画面へ遷移するので、少し下へスクロールして下さい。
すると以下のように「コントラクトから読む」「コントラクトを書く」といった2種類の表示があります。
「コントラクトから読む」には外部から参照可能な変数、参照処理限定の関数が列挙され、コントラクト内の情報を参照する事が出来ます。
「コントラクトを書く」は外部から実行可能な処理を選択し、実行する事が出来ます。
まずは「コントラクトから読む」内の「Balance of」を試してみます。
「Balance of」はERC20の規格においてアドレスの保有するトークンの残高を確認する事が可能な関数です。
アドレスを指定する部分に先ほど取得した2つのアカウントのアドレスを入力してみます。
コントラクトをデプロイしたアカウント(以下、メインアカウントと記述)にはコントラクト作成時にアカウント画面で確認した結果と同様に1000000000000000000000(1000 OT)が設定されています。
※0がやたらと多いのは、小数部(Decimals)を18桁で設定しているためです。
動作確認用に作成したアカウント(以下、サブアカウントと記述)は何も処理を行っていないため、0と表示されます。
このままでは動きが無くつまらないので、次はトークンのメイン機能とも言えるトークンの送信処理を実行してみます。
「コントラクトを書く」のドロップダウンから「Transfer」という処理を選択して下さい。
するとデプロイ時と似たような感じで「Transfer」の入力パラメータが表示されます。
パラメータの内容はそれぞれ以下の通りです。
to:送信先アドレス
value:送信トークンの量
「Execute from」は「Transfer」の入力パラメータではなく「Transfer」をどのアカウントが実行するかの設定です。
サブアカウントは保有残高0ですので、toにサブアカウントのアドレス、valueに400000000000000000000(400 OT)、Execute fromにメインアカウントのアドレスを指定して実行ボタンをクリックして下さい。
※メインアカウントからサブアカウントに400 OT送信する処理を実行する事になります。
トランザクションを送信するため、デプロイ時と同様にパスワードの入力を求められますので、メインアカウントのパスワードを入力し、「SEND TRANSACTION」をクリックし下さい。
コントラクトのデプロイ時と同様にウォレット画面の下部に送信したトランザクションが表示されます。
プライイベートネット上のため、1分程度で承認されます。
※マイニング実行中でない場合、いつまで待っても進みません。その場合は前述の手順でマイニングを開始して下さい。
処理が完了したら、「コントラクトから読む」内の「Balance of」でメインアカウントとサブアカウントの残高を再度確認してください。
メインアカウントは400 OT減り、
サブアカウントは400 OT増えた結果が確認できるはずです。
オマケ
以上で今回の本編は終了です。
内容が薄い!!とご指摘を受ける恐れが有りますので、蛇足的なオマケです。
Mistはあくまで実行環境であり、コーディングやデバッグを行う開発環境としては不足が有ります。
そこで良く用いられるのがBrowser-solidity(Remix IDE)という開発環境なのですが、実環境(メインネット、テストネット、プライベートネット)にて動作させるためにはgethとの連動が必要になります。
結局gethから勉強しなきゃいけないのか...という話になるとそもそも今回の記事は本末転倒になってしまいますのでその点を解決するMistの機能の一部をご紹介します。
実はMistにはMist内部のgethと連動したBrowser-solidity(Remix IDE)が同梱されています。
Mist上部のツールバーから「Develop」>「Open Remix IDE」を選択して下さい。
これだけでBrowser-solidity(Remix IDE)が即利用可能です。
起動元のMistが接続しているネットワークに接続されるため、gethを個別に準備する必要もありません。
※細かい使用方法やsolidity言語の記述方法等はいろんな方が紹介されていますのでGoogle先生にお問い合わせ下さい。
さいごに
以上でMistを用いたコントラクト入門は終了となります。
今回は省略しましたが「Ethereum Wallet」をダウンロードしてメインネットやテストネットに接続すれば出来る事の幅は更に広がりますので、興味のある方は是非ダウンロードしてみて下さい。(※注、すごく時間が掛かります)
コミュニティ紹介
数か月前に仮想通貨に興味を持ってから、仮想通貨関連のコミュニティに参加しております。
興味のある方は是非ご参加ください。
Ethereum 開発者向けコミュニティ「Hi-Ether」
Ethereum 開発者の方、Ethereum 開発者になりたい方、Ethereum 開発に興味のある方向けコミュニティです。
Ethereum 開発者向けコミュニティへの参加方法はEthereum Advent Calendar 2017 1日目をご覧下さい。TenX Community JAPAN
私のホームグラウンドで、コミュニティ用のトークンコントラクトの開発担当などをさせて頂いてます。
みんなでTenXを盛り上げていこう!!が主目的のコミュニティですので、興味のある方はどうぞお越し下さい♪
※特に暗号通貨関連でいろいろ開発してみたい方は是非♪♪
www.tenx-matome.com
ちょっとした仕事の報告(苦し紛れのネタ)
お久しぶりです、おっさんSEぴんくです。
最近とんと更新ご無沙汰しておりますが、ネタが無くって。。。
数少ない読者の方々申し訳ない。。。
そんな中お友達のマーンさんの依頼でちょっとだけ頑張ったのでご報告。
マーンさんのブログの記事内にちょこっとだけ入ってる計算フォームが
今回の成果物です♪
前回、マーンさんからご依頼のお仕事の際に使用した部品を
イーサリアム用にちょちょいと変更して
入力フォームをちょちょいと作成しただけなので、
マーンさんは褒めてくれるけど心苦しい限りですw
マーンさんの記事はいつも非常に分かりやすいので、
私のように仮想通貨始めたばかりの人や今から始める人は是非是非ご一読下さい♪
ゲスとの戦い(windows版導入編)
こんばんわ、最近肩が痛くて困っているおっさんSEのぴんくです。
ゲス...強敵でした。
まあ、ゲスとは言ってもここ数年芸能ニュースを騒がせてるゲスな方達と戦ったわけではなく、「Go Ethereum」通称「geth」のゲスと戦ってました。
※ここからはちゃんとgethと書きます。
gethとはEthereumのP2Pネットワークに参加するためのEthereumクライアント
らしいです!!
EthereumのP2Pネットワークに参加することで、採掘をはじめ、送金やスマートコントラクトの作成ができる
らしいです!!
詳しくはグーグル先生に聞いてくださいw
そーいう前置き的なものは得意では有りません。
以前、仮想通貨の話題で取り上げた独自の仮想通貨を作成することに挑戦するにあたり
開発環境の一部としてgethが必要らしく今回戦ってみた次第です。
以下、戦いの記録(備忘録的なもの)です。
誰か同じようなことにチャレンジしている方の参考になれば幸いです。
gethを導入するにあたり、恒例のグーグル先生に質問をしてみましたが...
「geth インストール」で質問した結果、こちらのサイトを発見。
ふむふむ...ふむふむ...
「Ubuntu、Debian、Mac OS X へのGethのインストール」
・・・あれ?windows無い。
いやいや、出張生活ばっかりの私にwindowsPC以外のPCも持ち歩けと?
ムリでしょうが!
windowsはないのか~と読み進めてみると
「Windows へのGethのインストール」
!!あった!!
・・・けど・・・面倒くさいからこっち見てと以下のサイトへのリンクが...
しくしくしく・・・ガッツリ英語で書かれていました。
英語力ほぼ0ですが、プログラミングやコマンドと似たような単語なので
手順は何となく分かりました。
書いてある内容はこんな感じ(※注、以下の手順はまだ実行しちゃダメ!!)
- https://geth.ethereum.org/downloads/からgethのzipファイルをダウンロードする
- zipを解凍する
- コマンドプロンプトを開く
- chdir(※ディレクトリを変更する。gethの解凍先にって意味だと思う)
- gethを起動する
書いてある通りにやってみました。
結論!!多分情報が古い!!そして内容端折りすぎ!!
私が手順に従って進め、いろいろと苦戦した結果、正しくは以下のような手順でした。
1.https://geth.ethereum.org/downloads/を開き、「Geth 〇〇〇 for Windows」を
クリックして、「geth-windows-amd64-〇〇〇.exe」をダウンロード
する。
「geth-windows-amd64-〇〇〇.exe」はインストーラです。
バージョンが進めば、ファイル名は変更になるかもしれないのでバージョン
およびその近辺は〇〇〇としておきます。(当手順実施時はver1.7.0)
64bit版しか見当たりませんでした。
32bitのPCでやりたい人は手順があるか不明ですが、自力でがんばりましょう。
zipじゃありませんでしたが、危ないファイルではないので大丈夫です。
※サイトを開いた際に「Retrieving packages from release server...」というメッセージの後に
「Failed to load releases!」というメッセージが出て固まることが有りましたが、
その場合は別のブラウザで開くか、再度開きなおせば進めました。
2.ダウンロードした「geth-windows-amd64-〇〇〇.exe」を実行する。
全部英語ですが、右下のボタンを押し続ければインストールが始まります。
3.コマンドプロンプトを開く。
ここだけは記述通りでした。
4.chdirは不要です。
インストーラがパスを通してくれるため、どのフォルダ上でも実行可能です。
無理な時はデフォルトで「C:\Program Files\Geth」にインストールされるため、
「cd C:\Program Files\Geth」を実行してください。
※インストーラで別フォルダを指定した場合は自分でなんとかして下さい。
独自のフォルダを作った方が良いというサイトも有りましたので、そこは個人の判断で・・・
5.gethを起動するはストップです。
gethコマンドをオプション無しで実行するとライブネットと呼ばれるEthereumの
本番環境へ接続が実行されるらしいです。実害は無いようですが、同期処理に
2、3日必要らしいので、たぶん時間と電気代の無駄です。
開発段階では不要みたいなので、開発目的であれば実行しない方が懸命です。
間違えて実行しちゃった人は「ctl⁺c」で強制終了しましょう。
インストールの確認は「geth help」とコマンドを入力して実行します。
ヘルプが表示されればインストール出来てます。
※マイニング(採掘)目的であればライブネットへの接続が必要なようですが、
現在では通常のPCでのマイニングは全然儲からないらしいですよ・・・
ガッツリやってる方はGPUを鬼積みした専用マシンとかでみんなやってるようです。
あとEthereumはもうしばらくしたらマイニングが不要な仕様になるらしいって友人のマーンさんが
言ってました。詳しくはよく分からないけど今から始めても・・・と私は思います。
とまあ、ここまでがここ数日で得たgethとの戦いの戦果です。
だれかの参考になれば幸いですが、たぶん必要とする人は少ないだろうなぁw
でも独自の仮想通貨を作成することには挑み続けてますので、
気が向けばまた続編を書いてみます。
以上、夢広がるゲス(geth)との戦いの話でした。
修行を続けていけば、いずれ必要になるかもなので、心優しい方よろしければ
Ethereum恵んでくださいw
売ったりしません。大切に温めますwww
ETH:0xd827270996f4d3ce56a11c028290a9ff9b8fe17b
VSジェイソン
おひさしぶりです、おっさんSEぴんくです。
タイトルについては後ほど説明するとして、近況報告です。
ここしばらく友人のマーンさんの依頼で前回作成したサイトの
仕様追加を行っていました。
決して出張先で飲み歩きして、ブログ更新をサボっていたわけではないのです。
ちゃんとお仕事してました!!
今回はなんとサイト表示時にリアルタイムの仮想通貨の金額が表示される!!
という斬新な仕様変更です。
まあ、正直なところ私が凄いんじゃなくリアルタイムの情報を提供してくれる方々が
素晴らしいのですが...
まずはこちらが成果物です。
でタイトルのジェイソンの話ですが、
あの有名なホラー映画のジェイソン(懐かしいなぁ...)ではありません。
自分非力なんであんなチェーンソーを人に向けて振り回すような相手とは戦えませんw
ちなみにホラー映画で私のイチオシは「パラノーマルアクティビティ」です。
ジェイソンは出てきませんが、めっちゃ怖いです。
さて、少々脱線しましたが、
私が今回戦ったのはJSON(JavaScript Object Notationの略)です。
簡単に説明するとプログラムで使用するデータの入れ物の一つですw
(※注、あくまでも私の独自解釈です。正しくは表記方法の一つとかなんとか)
詳しく知りたい人は先人様が説明しているサイトが有ったのでこちらを見てください。
より具体的には実データを見てもらった方が分かりやすいと思います。
下のURLにアクセスするとcoinmarketcapというサイトが提供しているリアルタイムの
仮想通貨の値段を格納しているJSONデータが見れます。
https://api.coinmarketcap.com/v1/ticker/
とまあ、こんな感じにデータが格納されているのです。
(株とか為替とか競馬とか天気とかのデータも公開されているので
興味のある方はグーグル先生に「〇〇 JSON」って尋ねてみて下さい)
で、仮想通貨の現在の価値を取得してサイトに表示する的な改造を行ったのですが、
結論から言うとJSONは強敵でした。
数時間の格闘の末、今では強敵と書いて友と呼べるに至りました。
格闘時に苦戦した点は2点。
もしこれから戦う人がいれば以下2点は要注意です。
・「[」「{」は意味が違う。
「[」は配列扱いなのです。
詳しく書いてもプログラミングしない人には分からないと思いますので
物凄く端折って書きますが、
{"aaa":"1","bbb":"2"}というJSONデータからaaaの値を取得する時は〇〇.aaa
[{"aaa":"1","bbb":"2"}]というJSONデータからaaaの値を取得する時は〇〇[0].aaa
となるのです。
・取得する際にタイムラグが発生する場合がある。
JSONからのデータ取得処理と取得した値を使用する計算処理を記述すると
記述によってはデータ取得処理より先に計算処理が発生し、
計算結果が正しく出なかったりします。
※これに私はドはまりしました。
とまあ、こんな感じでジェイソンさんと戦った末に今回の作業はフィニッシュです♪
370.5円損した話
今日の帰りコンビニで珍しいタバコを発見しました。
BODYSHOTというタバコで、
なんかジュースとかお酒の味がするらしいって書いてあって
ちょっと気になったのでチャレンジ...
私が買ったのは青色のエナジードリンク味...
封を開けて、まず小さな後悔。
臭いで既にムリムリ感いっぱいです。
けど勿体ないからとりあえず一本火をつけて一服...
盛大にむせました。ゲッホ...ゲホ...
臭いも味も体が受け付けないし、肺の中がめっちゃ気持ち悪くなって盛大に後悔。
更に僅か一服しただけなのにホテルの一室(出張中なので)が
異様な甘い香りに征服されました。
むせて苦しいし、臭いがきついし、悪夢ですね。
こいつはいったい何者なのか...
「ボディショット 何者?」とグーグル先生に聞いてみると
どうやらジャンル的にはタバコではなくリトルシガー(葉巻の一種?詳しくは不明)らしいです。
葉巻なので肺に入れちゃいけない。
葉巻なので口の中で味と香りを楽しまなきゃいけない。
みたいな?
吸い方が違ったみたいなのでもう一回再チャレンジ・・・・・・・・・・・・
・・・・は、しませんでした。
だってマズイもん。
けど売ってるって事は好んで吸う人もきっといるんだろうなぁ~。
世の中って広いなぁ~。
なんて考えながらゴミ箱に投げ捨てました。
※タバコ屋さんや愛好家の人居たらすみません。
私には合わなかっただけなので怒らないでくださいねw
以上、定価390円で一本吸ったから370.5円損したお話でした。