初心者でも仮想通貨の投げ銭サービスを作れるチュートリアル

こんにちは、ブロックチェーンエンジニアのアカネヤ(@ToshioAkaneya)です。

このチュートリアルでは、プログラミング初心者でもイーサリアムで投げ銭をするためのサービスを開発することができます。

初めての仮想通貨・ブロックチェーンを活用したサービスを作るのにうってつけです。

開発したサービスは自分のWebサービスやブログに組み込むこともできますし、独立した独立したWebサイトとしてホスティングすることもできます。


イーサリアムは開発が盛んに行われているプロジェクトで、イーサリアムを活用した様々なアプリが開発されています。

例えば、クリプトキティーズ、マイクリプトヒーローズ、くりぷ豚といったブロックチェーンゲームは全てイーサリアムブロックチェーン上にアセットが保存されています。


さて、投げ銭に話を戻しましょう。アドレスをこのように貼り付けておいて、「ここにイーサを送金して下さい」という形で投げ銭を募ることは現在も可能です。

僕のアドレス: 0xEeA915408716533B5fD1841e00342d8d6EbB7CC6

しかし、これではアドレスをコピペして、別のウォレットアプリを起動して送金を行う必要があります。

これは面倒ですよね。スマホだと特にやりにくいでしょう。

そこでWeb3.0ブラウザという、従来のブラウザにウォレット機能が追加されたブラウザが登場してきました。

PC版ではMist、スマホではtokenPocketといったアプリが有名です。

なお現時点では、Google ChromeにMetaMaskというウォレット拡張機能を追加するのが最もメジャーです。

MetaMaskはChromeをWeb3.0ブラウザにしてくれます。

さて、先ほど上げたブロックチェーンゲームを利用するには全てWeb3.0ブラウザを利用する必要があります。

今回作成する投げ銭サービスは、Web3.0ブラウザに対応した投げ銭サービスです。

Web3.0に対応した投げ銭サービスはアドレスをコピペする必要がなく、優れたユーザー体験が実現できます。


出来るだけカンタンに作成できるように工夫をしたので、初心者でも安心して作成することができます。


今回のチュートリアルではイーサリアムは必要ありませんが、より発展的なサービスを作るためにはイーサが必要になります。

ブログでイーサを買うのにオススメの取引所を紹介していますので、ぜひ参考にして下さい。

なお、口座開設までには時間がかかることがありますので早めに口座開設を始めると良いと思います。口座開設は無料です。


このチュートリアルで必要な前提知識

このアプリを0から構築するための前提として必要な知識について書いていきたいと思います。チュートリアルをやる前に、必ずこれらの知識はつけておいてください!

1. JavaScriptの知識

JavaScriptの知識は必要になるので、Progateで勉強してきてください。ちなみにプログラミング未経験の人でも、Progateならわかりやすく学べるのでお勧めです!

2. MetaMaskの導入

今回はGoogle Chrome + MetaMaskで開発をします。

Google Chromeをインストールして、MetaMaskを追加して下さい。

MetaMaskはチュートリアル全体を通して使います。

この記事が使い方まとめとなっていますので、必要な時には参考にしてください。

3. テスト用のイーサを獲得する

イーサリアムには、メインネットの他に開発用のテストネットと呼ばれるネットワークがあります。

テストネットでは有志によるマイニングが行われており無料でイーサを獲得することができます。このイーサを開発用に使用します。

MetaMaskを開き、Ethereumメインネットワークをクリックして、Ropstenテストネットワークに変更して下さい。

そして、下のサイトに行き「request 1 ether from faucet」をクリックして、1ETHを獲得してください。

4. Web Server for Chromeを導入する

開発にはWebサーバーが必要になります。

最も簡単な方法はChrome拡張のWeb Server for Chromeを使用することでしょう。こちらをChromeに追加して下さい。

開発を始める

それではコードを書いていきましょう。

tipethという名前のフォルダを作成して、その中にindex.htmlと、index.jsというファイルを作成して下さい。

index.htmlは次のように記述して下さい。(本番はJavaScriptファイルなのでここはコピペで大丈夫です。)

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <!-- ライブラリの導入 -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.0.0/polyfill.js"></script>
    <script src="https://cdn.rawgit.com/ethereum/web3.js/1.0/dist/web3.min.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.5.8/firebase.js"></script>
    <script src="./index.js"></script>
</head>
<body>
    <!-- 投げ銭ボタン -->
    <a id="tipButton" style="
        display: block;
        width: 8em;
        padding: 0.35em 1.2em;
        border: 0.1em solid #000000;
        margin: 0 0.3em 0.3em 0;
        border-radius: 0.12em;
        font-family: 'Roboto', sans-serif;
        font-weight: 300;
        color: #000000;
        text-align: center;">
        投げ銭する
    </a>
</body>
</html>

このコードでは、ライブラリ

jQuery
web3
firebase
babel-polyfill
firebase

の導入と、投げ銭をするためのボタンを設置します。

完了したら、Web Server for Chromeを起動して、CHOOSE FOLDERをクリックしてtipethフォルダを指定します。

そして http://127.0.0.1:8887/ にアクセスすると、投げ銭ボタンが現れるはずです。


JavaScriptを書く

さて、次はindex.jsを次のように書きましょう。

コードの解説はコメントで行なっています。noteでコメントが読みにくい場合は一度エディターにコピペするなどして下さい。

$(() => {
    $('#tipButton').on('click', async () => {        
        try {
            // Web3インスタンスの作成
            // MetaMaskを導入することでwindow.web3が定義されている。
            // Web3ライブラリはブラウザとイーサリアムブロックチェーンを繋ぐ役割を果たす。
            // 下のようにインスタンスを作成することでMetaMaskのアカウントに対し操作が行えるようになる。
            const web3 = new Web3(window.web3.currentProvider);
            // アカウントの取得
            // web3.eth.getAccountsでアカウントの配列が取得できる。
            // accountには、アカウントのアドレスが格納されている。
            const accounts = await web3.eth.getAccounts();            
            const account = accounts[0];            
            // トランザクションを送る
            // web3.eth.sendTransactionでトランザクションを送れれる。
            const res = await web3.eth.sendTransaction(
                {
                    from: account,
                    to: 'あなたのアドレス',
                    value: 10 ** 17
                }
            )
        } catch (e) {
            alert(`送金に失敗しました ${e.message}`);
        }
    })
});

'あなたのアドレス'の箇所は自分のMetaMaskのアドレスに変更するようにして下さい。こうすることで、自分から自分にイーサを送ることに問題はありません。

なお、最初の2行はjQueryを使用していますが「投げ銭する」をクリックした時に関数が実行されるようにしているだけです。

もうjQueryは出てきませんので、jQueryを学習していない方も安心して下さい。

これで、再びhtmlを開き、リロードして「投げ銭する」をクリックするとMetaMaskが起動してトランザクションの承認を求められるはずです。

承認すれば取引は完了です。

送るイーサの量を調節できるようにする

先ほどのコードでは送るイーサの量は10**17weiで固定でした。

weiはイーサの最小単位で、10 ** 18wei = 1ETHです。

promptを使うことでユーザーの好きな量の投げ銭ができるようにしましょう。

web3.eth.sendTransaction周りのコードを次のように変更して下さい。

            // もしも空欄だったり、キャンセルされた場合はreturnする
            const value = prompt('あげるETHの量(必須)', 0.01)
            if (!value) { return; }
            // トランザクションを送る
            // web3.eth.sendTransactionでトランザクションを送れれる。            
            const res = await web3.eth.sendTransaction({
                from: account,
                to: 'あなたのアドレス',
                // web3.utils.toWeiはETHからweiへ変換を行う
                value: web3.utils.toWei(value)
            });

ここでもまた動作を確認してみて下さい。

指定した量のイーサが送金できるようになっているはずです。

 送り主のTwitter IDとコメントを記録できるようにする

今まででのサービスで投げ銭が行われた場合、投げ銭された方は送り主のアドレスしか分かりません。

Twitter IDとひとことコメントも記録できるようにしましょう。

そのためにはデータベースが必要です。

最も簡単に利用できるデータベースはFirebaseのCloud Firestoreです。

FirebaseはGoogleが買収したサービスです。こちらからFirebaseでプロジェクトを作成して下さい。

プロジェクトを追加から、tipethという名前のプロジェクトを作成して下さい。

作成が完了したら左のメニューからDatabseを選択して、Cloud Firestoreを作成して下さい。

その後、下の印のところをクリックして、表示されたコードのうち、configのところのオブジェクトをコピーして下さい。

そして、index.jsの先頭に次を追加して下さい。

const config = {
    // configオブジェクトは自分がコピーしたものを使うこと
};

const firebaseApp = firebase.initializeApp(config);
const firestore = firebaseApp.firestore();
firestore.settings({ timestampsInSnapshots: true });

これでfirestore変数に対し操作を行うことでデータベースに対し変更を加えることが出来るようになりました。

index.jsを次のように編集して下さい。

const config = {
    // configオブジェクトは自分がコピーしたものを使うこと
};

const firebaseApp = firebase.initializeApp(config);
const firestore = firebaseApp.firestore();
firestore.settings({ timestampsInSnapshots: true });
$(() => {
    $('#tipButton').on('click', async () => {
        try {
            // Web3インスタンスの作成
            // MetaMaskを導入することでwindow.web3が定義されている。
            // Web3ライブラリはブラウザとイーサリアムブロックチェーンを繋ぐ役割を果たす。
            // 下のようにインスタンスを作成することでMetaMaskのアカウントに対し操作が行えるようになる。
            const web3 = new Web3(window.web3.currentProvider);
            // アカウントの取得
            // web3.eth.getAccountsでアカウントの配列が取得できる。
            // accountには、アカウントのアドレスが格納されている。
            const accounts = await web3.eth.getAccounts();
            const account = accounts[0];
            // もしも空欄だったり、キャンセルされた場合はreturnする
            const value = prompt('あげるETHの量(必須)', 0.01)
            if (!value) { return; }
            const twitterId = prompt('あなたのTwitter ID(空欄可)');
            if (!(twitterId === '' || twitterId)) { return; }
            const comment = prompt('ひとこと(必須)');
            if (!comment) { return; }
            const tipData = { value, twitterId, comment };
            // トランザクションを送る
            // web3.eth.sendTransactionでトランザクションを送れれる。            
            web3.eth.sendTransaction({
                from: account,
                to: account,
                // web3.utils.toWeiはETHからweiへ変換を行う
                value: web3.utils.toWei(value)
            }, async (err) => {
                if (!err) {
                    await firestore.collection('tips').add(tipData)
                    alert('投げ銭が完了しました。');
                } else {
                    alert(`送金に失敗しました ${err.message}`);
                    return;
                }
            });
        } catch (e) {
            alert(`送金に失敗しました ${e.message}`);
        }
    })
});

これでデータベースにvalueとTwitter IDとコメントを記録できるようになりました。

おめでとうございます!これで機能は完成しました!

投げ銭サービスの2種類の使い方

独立したWebサイトとしてホスティングする方法と、ブログなどのサイトに埋め込んで使う2種類の方法があります。

それぞれの例をお見せします。

独立したWebサイトとしてホスティングする場合

ブログなどのサイトに埋め込んで使う場合

今回は、ブログなどのサイトに埋め込んで使う場合を解説します。

JavaScriptをコンパイルする

今回使用したJavaScriptは、ES6という新しいバージョンのJavaScriptを使用しています。

古いブラウザでは正常に動作しない可能性があるので、ES6を古いバージョンのJavaScriptに変換する必要があります。

これにはBabelというツールを使います。

これにindex.jsの中身をコピペしましょう。右側に

さらに、Uglifyというツールを使って空白や改行を消してコンパクトにしましょう。

こうして得られてたJavaScriptを使うことで、素早く読み込むことができるようになります。

さて、投げ銭を導入したいサイトに次のようにscriptタグとaタグを記述をしましょう。

index.jsの代わりに、コンパイルしたJavaScriptを使うようにします。

    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.0.0/polyfill.js"></script>
    <script src="https://cdn.rawgit.com/ethereum/web3.js/1.0/dist/web3.min.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.5.8/firebase.js"></script>
    <script>"use strict";function _asyncToGenerator(e){return function(){var t=e.apply(this,arguments);return new Promise(function(e,r){return function n(a,i){try{var o=t[a](i),s=o.value}catch(e){return void r(e)}if(!o.done)return Promise.resolve(s).then(function(e){n("next",e)},function(e){n("throw",e)});e(s)}("next")})}}var config={apiKey:"AIzaSyBl4YL4vpu6AoYEqqKbN3XzB8bFYHTxVFg",authDomain:"tipeth.firebaseapp.com",databaseURL:"https://tipeth.firebaseio.com",projectId:"tipeth",storageBucket:"tipeth.appspot.com",messagingSenderId:"725174227985"},firebaseApp=firebase.initializeApp(config),firestore=firebaseApp.firestore();firestore.settings({timestampsInSnapshots:!0}),$(function(){$("#tipButton").on("click",_asyncToGenerator(regeneratorRuntime.mark(function e(){var t,r,n,a,i,o,s;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,t=new Web3(window.web3.currentProvider),e.next=4,t.eth.getAccounts();case 4:if(r=e.sent,n=r[0],a=prompt("あげるETHの量(必須)",.01)){e.next=9;break}return e.abrupt("return");case 9:if(""===(i=prompt("あなたのTwitter ID(空欄可)"))||i){e.next=12;break}return e.abrupt("return");case 12:if(o=prompt("ひとこと(必須)")){e.next=15;break}return e.abrupt("return");case 15:s={value:a,twitterId:i,comment:o},t.eth.sendTransaction({from:n,to:"0xEeA915408716533B5fD1841e00342d8d6EbB7CC6",value:t.utils.toWei(a)},function(){var e=_asyncToGenerator(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t){e.next=6;break}return e.next=3,firestore.collection("tips").add(s);case 3:alert("投げ銭が完了しました。"),e.next=8;break;case 6:return alert("送金に失敗しました "+t.message),e.abrupt("return");case 8:case"end":return e.stop()}},e,void 0)}));return function(t){return e.apply(this,arguments)}}()),e.next=22;break;case 19:e.prev=19,e.t0=e.catch(0),alert("送金に失敗しました "+e.t0.message);case 22:case"end":return e.stop()}},e,void 0,[[0,19]])})))});</script>
    <!-- 投げ銭ボタン -->
    <a id="tipButton" style="
        display: block;
        width: 8em;
        padding: 0.35em 1.2em;
        border: 0.1em solid #000000;
        margin: 0 0.3em 0.3em 0;
        border-radius: 0.12em;
        font-family: 'Roboto', sans-serif;
        font-weight: 300;
        color: #000000;
        text-align: center;">
        投げ銭する
    </a>

発展 独立したWebサイトとしてホスティングする

独立したWebサイトとしてホスティングする場合は、

github pagesか、firebase hostingを利用すると良いでしょう。

各自調べながらやってみて下さい。

まとめ

いかがでしたでしょうか。ブロックチェーンを使用したアプリケーションが簡単に作れることがお分かりいただけたと思います。

また、記事中に何か間違いなどがありましたらぜひお気軽にコメントをお願いします。

ぜひチュートリアルの感想をお聞かせ下さい。


11/24(土)に仮想通貨・ブロックチェーン業界合同企業説明会in東京が開催されます。

こちらの記事に注目ポイントをまとめたので、興味のある方はぜひ参加して下さい。



この記事が気に入ったら、サポートをしてみませんか?気軽にクリエイターを支援できます。

9

アカネヤ

コメント3件

ブロックチェーンに興味を持ったのでネットであれこれ調べていたところ、こちらのnoteに行き着き、「初心者でも仮想通貨の投げ銭を作れる」という表題に引かれて、試させていただきました(まったくのド素人です)。
コードをコピペさせていただき、127.0.0.1:8887で「投げ銭する」をクリックすると、「送金に失敗しました Cannot read property '0' of undefined」となってしまいました。
どうやらindex.js の「const account = accounts[0];」の [0] のところが引っかかっているらしい、ということまでは判るのですが、なにぶん全くの素人ゆえ、そこから先が判りません。
もしよろしければご教示ください。よろしくお願いいたします。
コメントありがとうございます^^
ぜひ問題を解決しましょう!

本文にもありますがMetamaskにログインして、Ropstenテストネットに変更する必要があります。これを忘れていませんか?
返信ありがとうございます。
(こんなに早くご連絡がいただけるとは思っていませんでした。)
Metamaskへのログイン、Ropstenテストネットへの変更、いずれも行っています。
本日、再度コピペしなおして試してみましたが、やはり同様のエラーでした。
その他、どこかチェックすべき箇所がありますでしょうか。
コメントを投稿するには、 ログイン または 会員登録 をする必要があります。