Dapps大全

solidity dapps ブロックチェーン技術の解説します

solidity 環境構築

前回はERC20トークンの発行方法についてご紹介しました。

順序が逆になっているような気もしますが今回は初心者の方に向けたsolidityの環境設定について解説していこうと思います。

主にsolidity、Dappsの開発に必要な環境、ソフトのインストール、使い方についての記事になります。

1.環境設定

まずは必要なものを準備しましょう。
こちらのERCトークン導入方法の記事でも同様の事をご紹介しています。

soliditystg.hateblo.jp

1.Node.js

まずはパッケージ管理用のソフトであるNode.jsを導入しnpmコマンドを使用できるようにしましょう。

macwindowsでそれぞれ異なります。mac ではbrewコマンドから直接インストールが可能です。今回はつまづきやすいwindowsユーザーの方向けにご説明します。

こちらのページから自分のコンピューターにあったバージョンのインストーラーをダウンロードします。

nodejs.org


その後コマンドライン上でnpmコマンドを使用できるようにするために環境パスを通します。windowsユーザーの方がつまづきやすい点がここです。

スタート→コントロールパネル→システム→システムの詳細設定を開き環境変数からパスを通します。

下の記事が参考になると思います。
techacademy.jp

2.truffle

1 のNode.jsのインストールが済んでいればすぐに終わります。
コマンドライン上で次のコマンドを起動しインストールします。

$ npm install -g truffle

このtruffleは分散型アプリケーションを作成する際のフレームワークとなります。多くのアプリはこのフレームワークにのっとって作成されています。今回はトリュフチュートリアルであるpet shopを利用して解説します。

3.Ganache

コンピューター上でローカルサーバーを立て自分用のチェーンを作成します。当然メインネットにデプロイすればガス代が消費されるわけですがこのローカルチェーンではその必要がありません。

Remixでも自動でテストネットに接続してテストを行えますがあちらとは異なりトークン作成やmetamaskとの連携でサーバー構築をすることができるためにこちらの方ができることは多いといえます。

下のページからインストーラーをダウンロードし起動する。終わり。

www.trufflesuite.com

4.Metamask

Google Chrome の拡張アプリです。web3とチェーン情報を接続します。コンパイルされた情報やトークン情報をweb3と同期してweb関数として引き出します。

https://metamask.io/

こちらから登録できます。Googleアカウントが必要です。

登録した後はoptionから接続先のサーバー設定が行えます。
Dapps作成で必要なのは多くの場合Ganacheのローカルサーバーとの接続です。

f:id:soliditystg:20191117182909j:plain
Ganache ローカルホスト

四角で囲ったところがサーバー情報です。Metamask上でこの情報を書くことで登録できます。

また右側の鍵マークは秘密鍵です。これも同様にアカウント追加でこの秘密鍵をペーストすれば登録できます。

5.VS Code

今回必須というわけではありませんがsolidityをエディタ上でコンパイルできるため非常に便利です。またDockerなどと合わせることで仮想的にLinux環境での開発も行えるため大変お勧めできます。これ無料なのは結構驚き。

azure.microsoft.com

短いですが今回はここまでです。後日petshopのチュートリアルについて追記したいと思います。

ここまで読んで頂きありがとうございました。

ERC トークンの導入方法

更新が空いてしまいました。今回はDappsを作る上で最も重要といっても過言ではないようなERCトークンについて解説していこうと思います。

ERCトークンといえばこんな記事を見つけました。かなり古い記事ですがあの有名なゲームMineCraftでもブロックチェーンを利用したサーバーが開かれているようですね。

dappsmarket.net


恥ずかしながら全く知りませんでした。この際使われているのがERCトークンです。しかしこれは通常のトークンとは異なり特殊なものを利用しているようです。

今回は一番基礎的なトークンであるERC20の導入方法について解説していきます。初心者の方にもわかりやすいように一からやっていきましょう。ERC20トークンについての解説はこちらの記事で詳しく書いています。
soliditystg.hateblo.jp


ERC20トークンとは最も基礎的なトークンであり各トークンは等価であるため定量的に等価交換が成立します。最も簡単に作成できる分改良されたトークンとは異なりトランザクション速度は速くありません。ですがこのERC20トークンを作成できればほかのトークン作成へと応用できます。早速見ていきましょう。

1.必要なもの

1. Node.jsのインストール

まずはnpmコマンドが使えるようにするためにNode.jsをインストールしましょう。npmとはコマンドラインから一括でパッケージやライブラリを管理できるようになるモジュールです。ERCトークンの導入もこれを用いるので必須といえます。導入に当たってはこちらの記事を参照させて頂きます。

qiita.com

blog.y-yuki.net

macの方とwindowsの方では方法が若干異なります。macの方はbrewコマンドから、windowsの方はインストーラーを用いてのインストールとなります。

windowsの方向け
1.インストーラーのダウンロード

以下のホームページからインストーラーをダウンロードし
起動、指示に従いインストールを行う。
nodejs.org

2.環境設定からパスを通す

windowsユーザーの方がつまづきやすい点がここです。npmをコマンドラインから使えるようにするためにはパスを通す必要があります。
スタート→コントロールパネル→システム→システムの詳細設定を開き環境変数からパスを通します。
下の記事が参考になると思います。

techacademy.jp

また必須ではないですがVS Codeを導入しておくと良いでしょう。Dapps作成以外にも作業をする際非常にはかどります。solidityコンパイルにも対応しているので大変有用なソフトといえます。無料なのすごい。

azure.microsoft.com

2.Ganacheのインストール

コンピューター上でローカルチェーンを作成し独自に起動させます。
下のリンクからインストールします。
www.trufflesuite.com

3.truffleのインストール

Dappsのフレームワークとなるtruffleをインストールします。npmの導入が済んでいれば簡単に行えます。

$ npm install -g truffle

これによりフレームワークの導入が済みました。なおトークンを用いらずにDappを作成する場合チュートリアルであるpet shopを作ることができます。これについては別記事にて解説したいと思います。

4.プロジェクトフォルダの作成

$ mkdir test && cd test

$ truffle init

プロジェクトファイルを作り移動します。その後truffle initコマンドによってtruffle プロジェクトを開始します。

このコマンドによってプロジェクトディレクトリ内に
contracts
migrations
test
truffle.js
truffle-config.js
が作成されます。

contractsには作成したコントラクトファイルを、migrationsにはコントラクトをデプロイするための設定用のファイルを、testには試験運用で関数が想像通りに動くかどうかをテストするためのファイルを入れます。

5.OpenZeppelinの導入

soliditystg.hateblo.jp


こちらの記事でも紹介しましたようにERCトークンはOpenZeppelinという規格化されたライブラリを用いることで安全性が確保されています。このライブラリを使用することで誰でも一定水準のセキュリティを確保でき堅牢な分散型アプリケーションを作成することができます。

github.com

npm init -f

このコマンドによりnpmコマンドのコンソールを開始します。

npm install openzeppelin-solidity

コンソール上でプロジェクトディレクトリにopenzeppelinを導入します。

5.ERC20トークンのimport用のファイル作成

ERC20の規格にのっとるために関数用のファイルをインポートします。こちらの記事で紹介しているようにこれらのファイルはトークン量(balance)を表示する関数、及びトークン作成用のmint、焼却用のburn関数を導入します。

Test1.sol

pragma solidity ^0.5.0;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";

contract testToken is ERC20, ERC20Detailed {
    
}

作成したTest1.solファイルをcontractsフォルダに置きます。


コントラクトをデプロイした直後にトークンを作成するためにconstructerを定義します。

Test1.sol

pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";

contract testToken is ERC20, ERC20Detailed {
    constructor(
        string memory name,
        string memory symbol,
        uint8 decimals,
        uint256 initSupply
    )
        ERC20Detailed(name, symbol, decimals)
        public
    {
        _mint(msg.sender, initSupply);
    }
}

見ての通りconstructer内ではトークンの名前、初期値を定義した後にmint関数を呼び出し関数を呼びだしたアカウントにトークンを送付します。

6.デプロイ用のmigrationファイルの作成

migrationフォルダの中に次のようなファイルを作成します。

2_deploy_testToken.js

const TestToken = artifacts.require("./TestToken1.sol");

module.exports = function(deployer, network, accounts) {
    const name = "TestToken";
    const symbol = "T2";
    const decimals = 18;
    const initSupply = web3.utils.toBN(100*(10**decimals));
    
    return deployer.then(()=>{
        return deployer.deploy(
            TestToken,
            name,
            symbol,
            decimals,
            initSupply
        );
    });
}

このファイルの名前は必ず2_deploy_testToken.jsにして下さい。
nameはトークンの名前、symbolはシンボル、トークンの略称です。デフォルトでは名前はTestTokenになっています。自由に変更してください。

decimalは単位の設定です。ERC721のように等価性のないトークンでは値を0に、それ以外では自由に設定します。デフォルトでは普通のEthereumと同じ単位量に設定されています。

7.testトークンの作成

次のファイルをtestフォルダに入れます。これによりトークンを試験運用します。このtestは規格化されているのでテンプレートをしましょう。今回はgithubにあるものをそのまま使用します。

const TestToken = artifacts.require("./TestToken1.sol");

contract("TestToken", accounts => {
    it("...should put 100ST in the first account.", async () => {
        //コントラクトのインスタンスを取得
        const TestTokenInstance = await testToken.deployed();

        //account[0]のトークンの残高を取得
        let balance = await TestTokenInstance.balanceOf(accounts[0]);
        //桁数が大きいのでether単位(10^18)に変換
        balance = web3.utils.fromWei(balance, "ether");

        //残高数と数字100を比較
        //同じであれば合格
        assert.equal(balance, 100, "First account don't have 100 ST.");
    });
});

8.truffleconfig.jsの設定変更

truffleconfig.jsファイルを開いて設定を変更します。デフォルト通りなら問題ありません。developmentを確認して
 host: "127.0.0.1",
port: 7545,
network_id: "*"
となっていればよいです。なってなければ変更してください。この値はGanacheへの接続の設定ができます。デフォルトの状態ではポート番号7545のローカルホストに接続します。

9.testの実行

$ truffle test

コンソール上でtruffle test コマンドを起動します。これにより作成したtestフォルダ内のコントラクトがデプロイされます。
エラーが出なければGanacheの0番目のアカウント残高が減りsuccessが表示されます。

これにてトークン作成準備は完了です。お疲れ様でした。あとは同様にテストネットにデプロイするか試験運用するかご自由に。

今回はこのあたりにしましょう。ERC20トークンが創れればあとは応用すればERC721トークンにも作り替えられます。
そのうちそれらのやり方も解説したいと思います。
ここまで読んで頂きありがとうございました。

ブロックチェーン技術の活用と今後5

前回は話題になっている量子コンピューターについてとEthereum上でドメイン取得を可能とするアプリであるMakerについてご紹介しました。このMakerは私が最も注目しているアプリの一つであり特に取り上げてsolidityのコード解説にも使わせて頂いております。
soliditystg.hateblo.jp


今回はブロックチェーン技術の活用方法として更なる分散型アプリケーションを紹介していきたいと思います。
前回までの記事はこちらから参照してください。

soliditystg.hateblo.jp

1.IBMの食品追跡ブロックチェーン

1.概要

IBMでは食品情報を管理する上でブロックチェーンを利用しています。農業においては作物の責任者、また輸送日時や手段、引いては輸送コストや排出二酸化炭素量にいたるまでをチェーン上で管理しています。

2.透明性について

これを企業内部で管理するわけではなく多くのノードが見えるようにすることで透明性が増すといわれています。

特に農薬使用量など消費者にとって重要な情報をチェーン上で管理すればステークホルダ(監視しているノード)が増え事実確認ができると考えられています。

3.ホタテの漁獲量の申告

最近ではこちらのニュースのように漁場におけるホタテの漁獲量を管理しようとしている動きがあります。
www.coindesk.com


ダニーアイスラーテン氏の漁団が収穫したホタテはシステム上に情報がアップロードされ重量、収穫された位置、時間が自動的にIBMブロックチェーン上で管理されます。

この情報を基にして流通業者や卸売業者に対する値段設定が行われます。この際値段と情報の関連性を機械学習を用いて算出するようです。ブロックチェーンでは多くの情報が多方面から同期的に管理される為ビッグデータ分析との親和性が高いと呼ばれています。

4.背景

どうしてこのようなブロックチェーンが導入されるに至ったかというとアメリカでは漁場データの虚偽申告が問題視されています。

中でもレストラン経営者などに携わる人々にとって正確な食品情報の取得は死活問題です。万が一にも不正申告された材料が明るみになれば評判はがた落ちですからね。

そこでこのブロックチェーンを利用した透明性のある食品情報管理は非常に注目を浴びているようですね。

今後は漁場の情報を動画などでも送れるようにアプリ化していく動きがあるようです。日本でも原子力発電などセンシティブな情報をこのように管理できればより信頼性のあるデータが取得できるのですがね…。中々難しいようです。

2.basic attention token

1.概要

ブロックチェーン上で広告の管理を行う分散型アプリケーションです。現在インターネット上には多くの広告がありこれにより膨大な通信料が使用されています。

basicattentiontoken.org

2.現在の広告ビジネスへの批判

加えてこれは大手のインターネットサービスが広告業を独占しているという現状もあります。このせいでブラウザを利用するユーザーはもちろんの事広告をしようとする広告主も適切な価格で広告を張り出せないことが問題視されています。

さらに広告を用いたマルウェアも増加傾向にあり広告ビジネスの在り方も多くの批判を集めています。

3.BATによる改善点

この点において新たな広告の在り方を提示するサービスがこのbasic attention tokenです。これはbraveというブラウザと提携をし広告情報をブロックチェーンで管理、リアルタイムでユーザーが最も注目している情報を広告しようとする取り組みのようです。

braveにはユーザーが見ている情報、注目する広告の傾向を匿名の情報として収集する機能が搭載されています。

このbasic attention tokenはこのサービスと連携し掲載された広告に対してユーザーがどれだけ注目していたかをチェーンにアップロードし注目を受けた時間や質に応じて広告掲載主にトークンで報酬を支払います。広告主はBATコインを購入し広告を掲載してもらえるようにチェーン上で送金します。

これにより各ノードがどれだけその広告に興味を持っていたかがチェーンで一目でわかるようになるためより質の高い広告が掲載されるようになるようです。

匿名とは言えユーザー情報が勝手にチェーンに乗って広告の有用化につながる、というのは少し怖い気もしますね。(実際私たちが使っているブラウザも可視化されていないだけで同じことは行われているわけですが)

とはいえ現在のままでは広告ビジネスはユーザーに悪影響がある方向へ進んでしまう恐れがあるのは否めません。
そこでこのようにブロックチェーンが使われ改善、ユーザーにやさしい方向性へと進むのであればそれは健全なのではないでしょうか。



短いですが今回はここまでとします。
今回の記事ではブロックチェーンの使い方として現実とリンクした使い方とインターネット上で機能する広告ビジネスとして紹介しました。

次回も同様にビジネスモデルとしてどのように使われているかについてご紹介していきたいと思います。

ここまで読んで頂きありがとうございました。

solidity コード解説4

前回から少し期間が空いてしまいましたが今回はsolidityのコーディングを行っていこうと思います。Ethereumブロックチェーン上でドメイン取得ができるように試みているアプリケーション、Makerのコードを用いて解説しています。

昨日入ったニュースでは中国国内での仮想通貨の市場規模が1兆円を超えたようですね。先日のブロックチェーン技術解説でも触れた通り中国の持つ性質とブロックチェーンは極めて親和性が高いです。

また中国当局もドル相場からの脱却を狙いブロックチェーン経済の発展を推進しているようです。

技術が革新的に広まっていくのが興奮する反面異様な広まり方にはどことなく怖い感じもありますね...。日本国内でもどのように拡大していくか、注目していかなければならないと思います。

それでは本編に移りましょう。
前回までの2つの記事はこちらからどうぞ。
soliditystg.hateblo.jp
soliditystg.hateblo.jp

今回でMakerを用いたコード解説は最後となります。ERC721トークンを発行する重要なコードとなるので最も大切な部分といえます。
コードは次のようになります。

コード

contract ERC20 {
    function totalSupply() public view returns (uint supply);
    function balanceOf( address who ) public view returns (uint value);
    function allowance( address owner, address spender ) public view returns (uint _allowance); 1

    function transfer( address to, uint value) public returns (bool ok);
    function transferFrom( address from, address to, uint value) public returns (bool ok);
    function approve( address spender, uint value ) public returns (bool ok); 2

    event Transfer( address indexed from, address indexed to, uint value);
    event Approval( address indexed owner, address indexed spender, uint value); 3
}

////// lib/ds-token/src/base.sol
/// base.sol -- basic ERC20 implementation

// Copyright (C) 2015, 2016, 2017  DappHub, LLC

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

/* pragma solidity ^0.4.13; */

/* import "erc20/erc20.sol"; */
/* import "ds-math/math.sol"; */

contract DSTokenBase is ERC20, DSMath {
    uint256                                            _supply;
    mapping (address => uint256)                       _balances;
    mapping (address => mapping (address => uint256))  _approvals; 4


    function DSTokenBase(uint supply) public {
        _balances[msg.sender] = supply;
        _supply = supply;
    } 

    function totalSupply() public view returns (uint) {
        return _supply;
    } 1
    function balanceOf(address src) public view returns (uint) {
        return _balances[src];
    }
    function allowance(address src, address guy) public view returns (uint) {
        return _approvals[src][guy];
    }  2

    function transfer(address dst, uint wad) public returns (bool) {
        return transferFrom(msg.sender, dst, wad);
    } 5

    function transferFrom(address src, address dst, uint wad)
        public
        returns (bool)
    {
        if (src != msg.sender) {
            _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
        } 1

        _balances[src] = sub(_balances[src], wad);
        _balances[dst] = add(_balances[dst], wad);

        Transfer(src, dst, wad);

        return true; 2
    } 6

    function approve(address guy, uint wad) public returns (bool) {
        _approvals[msg.sender][guy] = wad;

        Approval(msg.sender, guy, wad);

        return true;
    }
} 7

contract DSToken is DSTokenBase(0), DSStop {

    bytes32  public  symbol;
    uint256  public  decimals = 18;  
// standard token precision. override to customize 

    function DSToken(bytes32 symbol_) public {
        symbol = symbol_;
    }

    event Mint(address indexed guy, uint wad);
    event Burn(address indexed guy, uint wad); 8

    function approve(address guy) public stoppable returns (bool) {
        return super.approve(guy, uint(-1));
    }

    function approve(address guy, uint wad) public stoppable returns (bool) {
        return super.approve(guy, wad);
    }

    function transferFrom(address src, address dst, uint wad)
        public
        stoppable
        returns (bool)
    {
        if (src != msg.sender && _approvals[src][msg.sender] != uint(-1)) {
            _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
        }

        _balances[src] = sub(_balances[src], wad);
        _balances[dst] = add(_balances[dst], wad);

        Transfer(src, dst, wad);

        return true;
    } 9

    function push(address dst, uint wad) public {
        transferFrom(msg.sender, dst, wad);
    }
    function pull(address src, uint wad) public {
        transferFrom(src, msg.sender, wad);
    }
    function move(address src, address dst, uint wad) public {
        transferFrom(src, dst, wad);
    }

    function mint(uint wad) public {
        mint(msg.sender, wad);
    }
    function burn(uint wad) public {
        burn(msg.sender, wad);
    } 
    function mint(address guy, uint wad) public auth stoppable {
        _balances[guy] = add(_balances[guy], wad);
        _supply = add(_supply, wad);
        Mint(guy, wad);
    } 10
    function burn(address guy, uint wad) public auth stoppable {
        if (guy != msg.sender && _approvals[guy][msg.sender] != uint(-1)) {
            _approvals[guy][msg.sender] = sub(_approvals[guy][msg.sender], wad);
        } 11
 
        _balances[guy] = sub(_balances[guy], wad);
        _supply = sub(_supply, wad);
        Burn(guy, wad);
    }

    // Optional token name
    bytes32   public  name = "";

    function setName(bytes32 name_) public auth {
        name = name_;
    } 12
}

1. ERC20トークンの導入

ERCトークンには規格(テンプレート)が存在しているためそれを参照することで誰でも堅牢なアプリケーション開発ができます。
これはその中での指定したアカウントのバランス(保有しているトークン量)を返します。いうなら各アカウントのバランス量取得をトークンように独自定義している形です。

2.送金システム

1と同様にトークンの送金を行います。transfer関数が複数あるのは自分のアカウントからの送金、指定されたノード間の送金、を分けて行うためです。

3.イベントログ

1,2、での送金情報について受け取ったbool(成功か失敗か)に対応しログを残します。

4.DSMATH

これもERCトークン規格です。前回紹介したDSMATHコントラクトを継承しています。接続されたアカウント(アドレス)と持っているトークン量を接続します。このマッピングによって各アカウントの保有しているトークン量を表示できるようになります。

5.保有量表示

難しく見えますがやっていることは全てアカウントのトークン量を表示しているに過ぎません。

5.1. チェーン上での呼び出し

コントラクトアドレスが呼びだされ直接接続を行った際にはこの関数が呼びだされます。(普通はないでしょうが)gethのローカルサーバーや個人のチェーンでこのコントラクトが呼ばれた際はこの関数でトークン量を処理します。

5.2.web3からの呼び出し

普通にコントラクトを使用する際はこちらの関数が呼びだされると思います。metamaskなどで管理される際はsrcでweb3jsとの接続が行われます。

おそらくこれにより接続が初めてならアカウントが登録され2回目以降ならmetamask上の各アカウントに対応するトークン量をWAD単位で表示します。

6.送金関数

5同様に難しく見えますがやっていることは送金です。

6.1.チェーン上での処理

コントラクトをチェーンから直接呼び出して送金処理を行う際はこの関数が使われます。最初はこの処理から入りweb3からの接続であればif文の処理に移行します。

6.2.web3での呼び出し処理

非常に原始的な形でわかりやすく送金処理を行っています。前回四則演算を定義しました。これを用いて送金元のトークン量を減少させ送金先のトークン量を加算しています。その後上で定義されたtransfer関数を用いて送金を行っています。

7.イベント通知

送金額を避難しログにその送金額を通知します。おわり。

8.Mint, Burnの通知

ERCトークンを作る上でopen-zeppelinという組み込みライブラリを用います。このライブラリはDAppsを作る上で必須といえます。

このMintメソッドはトークン発行を行います。Burnメソッドはトークンを焼却するのに使います。

これらの使い方については別記事でERCトークンの使い方で解説しようと思います。ここではそれらのトークン発行、削除が行われた際にその返り値を受け取りログに記述するイベントを定義しています。

9.送金処理

6番と同様の処理です。継承先の関数を呼び出しています。多分。

10.Mint関数

この関数を呼び出し引数に取った値分WAD単位で全トークン量を増加させる、つまり新規発行を行います。auth,stoppableのmodifierがついていることからわかるように当然運営側しか操作できない仕様になっています。

11.Burn関数

おそらくアカウントの保有しているトークン量を使用不可能にしています。直接トークンを使用不可能にするのではなくアカウントを確認しているようですね。正直ここの処理がよくわかりませんでした。申し訳ない。

12.トークン名設定

運営側のみが呼びだせる関数です。これによりトークンの名前を設定します。これもopenzeppelinライブラリだと思います。



今回はここまでとします。非常に長かったですがお疲れ様でした。3回に分割してMakerのコードの解説を行いました。

少し大変だったと思いますが実際に世の中で稼働している分散型アプリケーションがどのようにコーディングされているか雰囲気だけでもつかめていただけたと思います。

分量は多く見えますが実際大半はopenzeppelinやERCトークンにおけるテンプレートを使用しているためオリジナルで記述する部分はそれほど多くありません。

これを機に皆さんがDappsに興味を持っていただければ幸いです。次回以降も別のアプリケーションを用いて解説を行っていこうと思います。

ここまで読んで頂きありがとうございました。

ブロックチェーン技術解説6

今回も前回から引き続き仮想通貨を代表例にしてブロックチェーン技術について解説していこうと思います。今日は前回紹介したPoW PoSに代わる2つのブロックチェーンを機能させるシステムについてご紹介します。前回までの解説はこちら。  

 

soliditystg.hateblo.jp

soliditystg.hateblo.jp

 

 

 

Proof of Importance 

これは仮想通貨NEMに導入されているシステムです。

 

1.NEMの独自性

NEMは各トランザクションにおいての重要度を測定するパラメーターを導入しています。これはノードが保有している通貨額のみならずそのトランザクションNEMコミュニティ内での通貨流動性を高めたかを評価します。

このトランザクションNEMコミュニティの発展に寄与したかどうかのパラメーターが次のブロックを作成できる確率になります。当然高いほど作成確率も高まるため必然的に協力的なノードが影響力を高めていく事になります。

 

前回紹介したPoSと異なり保有しているだけでは次のブロックを作成する権利が得られないためノードの発言力を上げたい場合は積極的にコミュニティ内で協力的なトランザクションを行う必要があるものになっています。

 

2.NEMの安定性

 
またほかの仮想通貨と異なりNEMは発行総額が固定されているため相場が変動しづらい安定的な通貨と呼ばれています。しかし実際のところは昨年のコインチェックでの流出を受け評価額はおよそ4分の1に下落していたなど言うほど安定的なシステムを作っているわけではありません。ちなみにこれのせいで結構損した。許さない。
 

3.Multisig

 
またNEMMultisig(複数署名)という概念をトランザクションの中に導入しています。これはトランザクションブロックチェーンに乗る前に複数のノードの合意署名が必要であるという設定の事です。
 
1.使用例 個人利用
 
これは使用方法に応じてどれだけの署名を得ればよいかが異なります。例えば自分を含めたすべてのノードが合意する必要があるとします。
 
この場合は証明に時間がかかる代わりに堅牢なセキュリティチェックが可能になります。仮に自分のウォレット情報が盗まれ不正に利用されそうになっても自分がこのトランザクションに合意しない限り盗んだ人がそのんウォレットから引き出すことができないためです。
 
2.使用例 グループ利用
 
またあるコミュニティ内での過半数の合意が必要と設定したとします。こうすることでコミュニティ内での一部の人間が不正にその資金を利用することを防ぐことができます。
 
例えば寄付金や企業資金など一人のものではなくチーム全体で管理される運営資金などがあった際リーダーが抜け駆けしてその資金を持ち逃げることを未然に防ぐことができます
 
因みに個人的な話ですが昨今作成していたDaapsはチームで起業しようと草案していたものでしたが先日チームメンバーの離脱により持ち逃げられました。わりと壮絶。最近滞ってるのもそのせい。
 
と、このようにNEMを利用することでコミュニティ内での資金利用を分散させるとともにより安全なトランザクションが可能となります。
 
またこれらのシステムを応用したMijinというプライベートチェーンが動かされており大手銀行などの参入も期待されています。このことについては仮想通貨の今後についての記事で紹介していこうと思います。
 

Proof of Burn

 
CounterpertyというサービスのXCPというコインで導入されたシステムです。
 

1.PoW,PoSの不平等性

 
PoWPoSでは創設期のメンバーが多くの通貨を保持しているという現実があります。現在のEthereum,BitCoinコミュニティでもこれらの批判は上がっており創設期の7人程度が全体の通貨の大部分を占めていた時期もあるくらいです。
 
これらの現象はコインの創設期の価値は極めて低いことからきています。つまりアルトコインを作成しても価値が低いため創設者が大量に保持してしまう、またシステム上それらの大量保持が可能である、というところが問題視されました。
 
当然これはブロックチェーンが望む非中央集権制とはかけ離れているからです。
ここで導入されたシステムがProof of Burnです。
 

2.Proof of Burnの仕組み

 
Proof of Burnは焼却したBitCoin量に応じて新たな通貨の発行権を得ることができるようになっています。
 
焼却といっても実際に燃やす、という意味ではなくアクセス不可能なアドレス 1CounterpartyXXXXXXXXXXXXXXXUWLpVr へと送金することで 誰もそのBitCoinに触れられなくするということです
 
創設期にXCPはおよそ2000BTC焼却され265万枚程度発行されました。Counterpertyではこれ以上XCPが発行されることはありません。そしてこのXCPをさらに焼却することで同額のアルトコインを発行できるシステムになっています。
 

3.得られる利点

 
これにより間接的ではありますがBitCoinを同価値の別通貨に換えることができ中央集権制を分散させることができるといえます。
 
こちらの記事で紹介したEthereum上のERCトークンに関してもこれらのシステムは踏襲されておりburnメソッドによりトークンを破棄することができるようになっています。
 
一見無駄に見えるBitCoinの焼却ですがその本質は価値の変換、分散化です。すでに資本の偏りが見えつつあるBitCoinを焼却(逃がす)対価として新たな通貨を発行させることで初期創設者以外にも等しくコインを受け取る権利を作ろうと試みているといえます。
 
今回はここまでとします。次回はブロックチェーンから目を離し仮想通貨がどのような取り組みで分散して成り立っているのかを解説していきたいと思います。ここまで読んで頂きありがとうございました。

ブロックチェーン技術解説5

前回ご説明した通りブロックチェーントランザクションが書き込まれる事で接続されます。(当然ですが) このとき重要なのはどのようなメカニズムによって次のブロックが作成されるかということです。今回はこのシステムについて解説していきます。

前回までの解説はこちらからご覧ください。

 

soliditystg.hateblo.jp

soliditystg.hateblo.jp

soliditystg.hateblo.jp

soliditystg.hateblo.jp

 

 

 

 

Proof of Work

PoWのメカニズム

前回BitCoinを代表にして解説したメカニズムです。今なお多くの仮想通貨ではこのシステムが採用されております。

 

これは全ノードのマイニングパワー(計算能力)から逆算されたターゲットと呼ばれる難易度が設定されます。このターゲット(難易度)を満たすようなナンス値を求めマイナーは競い合うのです。

 

ハッシュ関数は衝突耐性があり出力は入力に関して予測不能です。従ってマイナーは上の関係を満たすナンスを総当たり的に探して行くしかありません。この総当たりで幸運にも解答を見つけられたノードはそのナンスの値をプールにアナウンスします。(この際勿論ナンスは1通りではありません。様々な値が存在し得ます。)ハッシュ関数は入力に対し一対一で出力を返します。従ってこのアナウンスされたナンスを入力すればだれでもそれが解答だと確かめることが出来るのです。

 

これにより発見したノードは晴れて次のブロックを作る権利を得て報酬として新たなBitCoinを作成し受け取ることができます。これは新たなBitCoinを作ることから通過全体量は増加しています。いわばインフレと同じ現象であるためいつまでも続けるわけには行きません。

 

現在の計算ではこのプロセスは2100年まで続くとされその後新たなシステムへの移行が検討されています。 

 

しかしこのメカニズムには多くの批判があります。

 

PoWへの批判点

1.電力消費

一つは電力を消費することです。プロセスの中で私達は意図して難易度を高めそれを越えるために膨大な計算をコンピュータを用いて行います。

 

本来これは必要のないはずの行為です。このことを資源の無駄だと批判する人もいるようですね。

 

またここまでの説明でお気づきの方もいるでしょうがこのプロセスの成功率は計算能力に依存しています。当然高い程成功しやすい訳ですがこれにより新たな課題が生じます。コンピュータを動かすには電気が必要である以上電気が安く調達できる人間が有利になるのです。

 

するとどうなるか。お隣の国中国は電気代が安く人口も極めて多いです。はい。

2.非中央集権性の崩壊

これに付随しブロックチェーンのマイニングコミュニティの大半を中国勢力が占めてしまうことになります。これはブロックチェーンの非中央集権性に反しています。

 

これに対応するためにEthereumのコミュニティなどでは意図的にコミュニティ内のハッシュパワーを分散させ一極集中による発言力の偏りが生じることを防いでいます。これはハッシュパワーの過半数を占めたコミュニティが51%攻撃を仕掛けられることにも起因しています。

 

ハッシュパワーの過半数を有すれば理論上長期的には全ノードの中で最大の報酬を得ることができます(もちろん上で説明した通りナンスの発見は確率に依存するためいつでも発見できるとは限りません)。

従って「51%攻撃を仕掛けるよりは自分がそのコミュニティ内で最大勢力として報酬を得続ける方が本人にとってもおいしい話である。故にそのノードがブロックチェーンに害なすことは仕掛けないだろう。」 

 

Proof of Workはこのようなある種の性善説、より厳密には人間の合理性を前提にした上で成立しています。

 

3.合理性への依存

この前提は一見うまく機能しているように見えますが常にうまくいくとは限りません。実際昨年monacoinは51%攻撃を仕掛けられ多くの通貨が流出しています。

これはmonacoinにセキュリティ上の落ち度があった、というよりはブロックチェーンのシステム、原理の持つ宿命だといえます。このような問題を内在していることもPoWが問題視されている一因だといえます。

 

Proof of Stake

 

上で解説したPoWの抱える問題を解決するために新たなメカニズムが導入されました。それがこのProof of Stake というシステムです。

 

PoSとは

これは次のブロック作成権利をランダムでいずれかのノードにゆだねる、というものです。確率で抽選され当選したノードはトランザクションを纏め新たなブロックとして接続します。

 

PoSの改善点

この際これに当選する確率はそのノードが有している通貨額に比例します。具体的には 保有量/通貨総量 の確率で当選します。

 

1.計算資源の削減

このようにして次のブロックを作成する何よりのメリットはPoWで必要であったナンスを探す膨大な計算が必要ないということです。これによりPoWの批判点であった計算資源の無駄遣いを防ぐことができます。

2.ブロック承認時間の削減

また難解な計算を行わないためブロックの承認時間を短く済ませることができます。このシステムは保有している通貨量が多いほど次のブロックを作成できる確率が高まります。

PoSの問題点

1.影響力の偏り

これも仮に全体の通貨量の過半数(実際は別に過半数である必然性はありませんが一例として)を保有しているノードは長期的にはもっとも影響力を持つノードとなります。

つまり理論上このノードは51%攻撃を仕掛けることができるようになります。

 

しかし51%攻撃が起これば当然その仮想通貨に価値はなくなります。

「多くの通貨を保有しているノードは自分の仮想通貨の価値をなるべく下げたくないはずだ。故により多くの通貨を保有しているノードほどコミュニティに協力的な姿勢をとるはずだ。」 

このような前提によってProof of Stakeは成立しています。

 

2.合理性が前提

これも本質的にはPoW同様ある種の合理性を前提としています。つまり不合理な多額保有ノードがあれば彼がコミュニティに不利益な攻撃を仕掛ける可能性が考慮されていません。これもある種の不安点を抱えているといえるでしょう。

このことがいまだにブロックチェーンが社会に浸透しない原因の一つといえます。

 

今後について

このシステムはPeerCoinなどが導入しており今後より多くの通貨が移行してくることが予想されています。実際EthereumもPoWからPoSへの移行が考えられています。

 

しかしEthereumの場合ただの通貨のみならずプログラムを実行できる性質上中央に意思決定を行うコミュニティが存在します。彼らは以前Ethereumの致命的バグを修復するためチェーンの巻き戻しを決定しました。(これは非中央集権に反するという批判が集まり最終的に巻き戻しを認める勢力と認めない勢力によるハードフォーク、(チェーンの分裂が)行われました。これが今日におけるEthereumとEthereumClassicです。)

 

このようにEthereumではある種コミュニティ全体の安定を考慮した意思決定者があるためこのように保有額でブロックの行方が左右されると安定性を欠くのでは、という懸念もなされています。

 

今回はここまでとしましょう。次回はさらに別のアルトコインを紹介しつつ各通貨がどのようにして非中央集権性を保とうとしているかの試みについて解説していこうと思います。またライトニングという更なる概念も登場しています。

 

ブロックチェーン技術は日進月歩で進んでいるようですね。それではここまで読んでいただきありがとうございました。

ブロックチェーン技術解説4

前回はブロックチェーンがどのような発想のもとで作られたか、
その暗号学的なコンセプトをビザンティン将軍問題を通して考えました。
このビザンティン将軍問題の解決方法こそが今日における暗号学、
ブロックチェーン技術の応用へとつながっているわけです。

soliditystg.hateblo.jp


今回は実際にブロックチェーンが書き込まれるトランザクション
そのチェーンがどのようにして動いているかを解説していきたいと思います。

ここまでのブロックチェーン技術解説については次の記事を参照してください。

soliditystg.hateblo.jp



ひとえにブロックチェーンといっても、そのトランザクション情報の組み込み方は多くのチェーンで異なっています。今回はもっとも有名な仮想通貨であるBItCoinの場合を用いて解説します。

1.トランザクション

私たちがチェーンに書き込む際直接情報がチェーンに書き込まれるわけではなくマイナープールと呼ばれる場所に情報がアナウンスされます。

この時ブロックチェーンに書き込むのはマイナーと呼ばれるノードです。
彼らはマイナープールにアナウンスされた個々のトランザクション情報を拾い上げ、そのルートの値を組み合わせ更なるルートを作り出します。
この際彼らは必ず現在から一つ前のブロックのハッシュ情報を読み取り
メープルルートの中に組み込むのです。

こうして出来上がったルート情報が次のブロック候補になります。しかしこうして作られたブロックがそのままチェーン上につながれるわけではありません。

ブロックチェーン情報への書き込みはマイナーが行うといいましたが彼らはなぜマイニングをしてくれるのでしょうか?決してボランティアでやって言るわけではありません。ブロックチェーンに次のブロックを書き込むと報酬として新たなコインが発行され書き込んだものに渡されます。このコインは新たなコインとして発行される為最初の段階ではだれのものでもありません。新規発行されたのちにマイニングに成功したノードのものとして書き込まれるわけです。

しかしマイニングをしているノードは世界中にたくさん存在しています。ではいったい誰が報酬を貰えるように調整されるのでしょうか。

ここでナンスとターゲットいう2つの概念をブロックチェーンに導入します。ターゲットはブロックチェーン全体のハッシュパワー(全ユーザーのコンピューターの計算能力を合算したもの)に応じて指定される値です。ナンス値とはユーザーが指定する任意の値です。このナンスを受け取ってトランザクション情報、及び前のブロックのルートハッシュと組み合わせて次のブロックを構成します。この際ターゲットとナンスは次の関係を満たさなければなりません。


Hash(ナンスの値 || 前のブロックハッシュ || トランザクション情報) < ターゲット


以前こちらの記事でご説明した通りハッシュ関数は入力に対して予測できない不規則な値を出力します。

soliditystg.hateblo.jp


従ってハッシュ化した値がターゲットよりも小さく出力されるは確率次第ということになります。これが満たされるようなナンスの値を自分で探すことがいわゆるマイニングと呼ばれる行為になります。

当然このナンスをどのように探せばよいのかの手掛かりはありません。総当たり的に適当な値を入れてハッシュ関数に入力し幸運にもターゲットをみたすことを祈るしかありません。例えばターゲットの大きさが出力空間の10%であれば成功する確率も10%ということになります。実際にはもっとはるかに小さい値です。

偶然このナンスを発見したノードはブロックチェーン全体にそのナンス値をアナウンスします。以前も解説しましたがハッシュ関数は出力から入力は予測できませんが入力と出力は一対一で対応します。従って他のノードでもそのアナウンスされたナンス値を入力すると成功が確認できるわけです。

これにてナンスを見つけたノードが発掘者して次のブロックを作ることができ報酬を受け取れるのです。

このターゲットの難易度が具体的にどのように調整されるかというと、出力されたハッシュ値の先頭の0の桁数です。およそ出力されたハッシュ値の上40数桁が連続して0の時成功とみなされ次のブロックとして接続されます。これだけでもどれだけ低い確率化が伺えますね。

この確率(難易度)はハッシュパワーの成長(現実のコンピューターの計算性能)に伴い上昇していきます。BItCoinの承認時間、つまりあるブロックが創られてから次のブロックが接続されるまでの時間は15分です。現実のハッシュパワーに即して多くのノードが計算を行った際およそ15分間隔で成功者が出るような確率でこの難易度は設定されています。

以上の仕組みでブロックチェーンを機能させるシステムの事をProof of Work(PoW)と呼びます。この仕組みはブロックチェーンのマイニングをするうえで意図的に難易度を上げ多くのノードでその難易度を突破するための計算をしなければならないため電気や計算能力のリソースを無駄に浪費しているという批判を浴びています。

それを改善するために所持している仮想通貨の額で次のブロック接続確率が変わるProof of Stake(PoS)が検討されています。

これらのシステムについて次回様々な仮想通貨の代表例を基にして解説していきたいと思います。今回はここまでです。見ていただきありがとうございました。