ブロックチェーンプログラミングを始めよう
この記事は、Febin John James氏の「A Beginner’s Guide to Blockchain Programming」を翻訳したものです。全てのクレジットは、Febin John Jamesに属します。
ブロックチェーンプログラミングの手引き
ブロックチェーンはどのように動いているのか、ということを理解する上で立ちはだかる疑問は多く存在します。重要な問いの一つとして「ブロックチェーン上でどのようにアプリケーションを構築していくのか」ということが挙げられます。このことについて深く理解するのに数週間を要しました。その間、専門書を読んだり、手を動かすことでやっと理解することができました。簡潔に表すことはできませんが、皆さんに向けて包括的に語っていきたいと思います。学習の無駄をなくすために、いくつかのチャプターに分けて説明をしていきます。
項目
- ブロックチェーン技術を使う目的
- ブロックチェーン技術はどのように生まれたのか
- イーサリアムとスマートコントラクトの導入
- イーサリアムじょうでのスマートコントラクトの実装
- 最後に
ブロックチェーン技術を使う目的
インドのデリーの辺鄙な地域に住んでいるルーパさんがいます。インド政府は毎月、BPL(Below Poverty Line, 貧困ライン上)に属する彼女に対して食料物資を僅かながら提供しています。インド政府はこれらの食料物資を提供するために仲介業者を雇っています。わずか三分の一の食料がルーパのような貧しい人の元に行き渡り、残りは業者の利益追究のために販売されます。
サラさんという女性は小説を書き、出版したものをAmazonで販売しています。そこでAmazonは50%引きのセールを実施したせいで、彼女は動揺してしまいます。サラさんは執筆とマーケティング活動をたった一人で行っているにも関わらず、これでは不公平です。
ここで問題なのは、仲介業者は権力と財力に関して貪欲であるということです。彼らのモットーはコストをかけて儲けを得ることになりつつあります。
著作者を支援したり、貧しい人を養っていくためには倫理的に振る舞う仲介業者が必要となります。これを達成することはほとんど不可能に近いですが、仲介業者を自動化されたシステムに置き換えることができたらどうなるでしょうか?
コンピュータが広く普及してから、それを扱うには莫大なお金も卓越した能力も必要なくなりました。2008年にサトシ・ナカモトがブロックチェーン技術を用いたビットコインを開発してから、サトシ・ナカモトの思想がそれを可能にし始めました。
ブロックチェーン技術はどのように発明されたのか
お金は時代を超えて変化してきました。変化の度にお金の製造コストを削減し、お金の取引はより便利なものになってきました。金貨は製造コストが大きいものでした。紙幣の発明によりこの問題は解決しました。しかしコンピューター及びインターネットの発達以後、人々はお金の取引を便利かつスピーディーにする、より良い方法を見つけ出しました。
私たちが労働から得るお金を保管し、デジタル上での資産のやりとりを正当化するためには、仲介役である銀行が必要となります。このことにより銀行は力を持ち、顧客が口座から資産を引き出したり取引をする度に高い手数料を請求してきたり、顧客の個人情報を売ったりすることができます。
銀行のお金に対する執着は2008年の金融危機を引き起こしました。銀行は顧客のプライバシーを遵守することができませんでした。銀行の脆いセキュリティシステムがデジタル上での詐欺にまで発展しました。
今からお金の枠組みを変革するには以下の問題を解決する必要があります。
- お金は中央管理主体に預けておくべきではない
- 高い安全性が要求される
- プライバシーを保護する必要がある
法定通貨が政府によってコントロールされていることから、サトシナカモトは新しいお金、ビットコインを発明するしかないと思い立ったわけです。彼は既存のシステムが抱える問題をP2Pネットワークと暗号学によって解決したのです。
非中央集権化
多くのサイトはファイルを共有するためにP2Pの技術を使用しています。アプリは中央のサーバー、もしくは一つのコンピューターからファイルをダウンロードしないかわりに、ネットワーク上に存在する人同士をつなぎあわせ、ファイルを所有しコンピュータ上からアプリをダウンロードする人を見つけ出しています。
世界中の異なるコンピューターから数種類のファイルを取得するとします。ネット上のとある一人がどこかに行ったとしても、取得したファイルはウイルスに感染しません。なぜなら他の人たちも同じファイルを共有することができるからです。
サトシナカモトは分散化された方法でお金を保管する目的でこの技術を採用しました。この技術のもとでは、誰一人としてコントロールできる権限は持ちません。
暗号学
暗号学を使えば、誰でも暗号を使ってメッセージを送ることができます。使いこなすためには、公開鍵・秘密鍵・メッセージを理解しておく必要があります。
公開鍵と秘密鍵は数学的に繋ぎ合わせられた、複雑な文字列です。公開鍵はユーザー名のような具合に公開されており。秘密鍵はパスワードのように非公開にしておく必要があります。
メッセージは「私はジョンに100ドル払うことを認める」といった具合に、あなたが承認したい情報のことをさします。
公開鍵、秘密鍵、メッセージをアルゴリズムに組み込んだとします。すると暗号アルゴリズムは署名を発行します。この署名はそのメッセージの内容とは別の独自の文字列です。
Public Key
-----BEGIN EC PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE50uE+YSxqDgMkFByhpcgTVqXCqHO h68Ljt1z0jklDff/WV7xo+U6o3REBtK/C0/LM+Ef3FB3wR9aXMGNMLb9EA== -----END EC PUBLIC KEY-----Private Key
-----BEGIN EC PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgwqIsXl9FqsgrzMdx axI6flBwWIev0Z7i+WF4j8BGnrKhRANCAATnS4T5hLGoOAyQUHKGlyBNWpcKoc6H rwuO3XPSOSUN9/9ZXvGj5TqjdEQG0r8LT8sz4R/cUHfBH1pcwY0wtv0Q -----END EC PRIVATE KEY-----Message
Hello WorldSignature
B0A9A4F641D3A2E3A65576B7311DCD62ABE78BBF4D3F5FE856598508E24FCB2E6F0277C2F8D57E9E2E108B7C493986E783F5316B8046597019951669B4EE6922
メッセージを承認するには公開鍵、メッセージ、そして署名を入力する必要があります。公開鍵の所有者からメッセージが記された場合、アルゴリズムが承認されます。
暗号学のアルゴリズムが打ち砕かれるには1000年もの時を要するでしょう。コンピュータには限界があるため、早急に解決することは困難でしょう。近い将来、量子コンピュータがこれに挑むと期待されていますが、ビットコインが安全性を確保するために性能が強化されています。
サトシナカモトは、ウォレットから生じたビットコインの取引をなるべく簡単に承認できるよう暗号学を組み入れたのです。
プライバシー
公開鍵と秘密鍵を生成するウォレットを作成することによりビットコインを使用することができます。Eメールアドレスや個人の名前と行った個人情報を抜き取られることはありません。自ら公開鍵を提示しない限りは誰にも知られずに済みます。
まとめ
サトシナカモトは暗号学とP2Pネットワークを用いて暗号学を用いて分散型台帳を設計しました。ビットコインを誰かに送ったら、メッセージが承認され、ネットワーク上にいるすべての人々に伝えられます。送金を行うことで台帳が更新され続け、ネットワーク上にいる人々は誰が何を所有しているのかがわかるのです。
ブロックチェーン
十分毎にトランザクションはブロックに取り入れられ、前のブロックに組み入れられます。このプロセスによって連続的なブロックチェーンが構成されます。マイニングはブロックを構成する行為の一つで、コンピューターが数学的な問題を解きます。この問題を一番最初に説いたコンピューターおよびマイナーはビットコインで報酬を受けよります。
一度ブロックが構成されネットワークに組み入れられると、ネットワーク全体を超えてブロックは複製されます。ブロックチェーンは人間の介入なしにトランザクションを完結するビットコインのシステムを作成する価値で発明されました。
イーサリアムとスマートコントラクトの導入
多くの人々にとってビットコインのシステムをコードによって表現するのは難しいものでした。
そこでVitalik Buterinはイーサリアムを創始しました。分散化された暗号通貨であるだけでなく、スマートコントラクトの機能を備えたアプリケーションプラットフォームでもあります。
スマートコントラクトを使えば、気軽にプログラムを作れます。分散化された書店を作りたいと考えたとしましょう。最初に、著者が新著をリリースするための約束事や、一度消費者が購入手続きを済ませたら本をダウンロードするためのリンクを送付するといった約束事を決めましょう。
スマートコントラクトはconditionsだけでなくデータを保存する機能があります。分散化された書店のスマートコントラクトはその中自体に、販売している本の在庫状況や購買情報を保存しています。
しかし、スマートコントラクトには限界があることも知っておきましょう。何らかの問題が起こった場合、人間の手を介する必要があり、コンピューターがそれを自動で制御するといったことができないケースがあります。現実世界でスマートコントラクトを実行することは簡単なことではないのです。スマートコントラクトは一度実行されると変更を加えることはできないので、ちょっとしたミスが全体的なミスへの引き金になります。
イーサリアム上でのスマートコントラクト実装
生徒の成績を管理し、検索することのできる簡単なスマートコントラクトを実装してみましょう。Solidityというスクリプト言語を使って実装していきます。Githubのレポジトリはこちら
pragma solidity ^0.4.18;contract Grades{}
一行目ではSolidityのバージョンをコンパイラに伝えています。そこでコントラクトのグレードを定義しています。
コントラクトの中には生徒の名前と学年を記述する必要があります。なので生徒の名前を保存する配列、学年を保存する連想配列を作成しましょう。
pragma solidity ^0.4.18;contract Grades{mapping (bytes32 => string) public grades;
bytes32[] public studentList;}
いま生徒の名前のリストを作成しました。これをコンストラクタに送信します。
pragma solidity ^0.4.18;contract Grades{mapping (bytes32 => string) public grades;
bytes32[] public studentList;function Grades(bytes32[] studentNames) public {
studentList = studentNames;
}}
solidityでは一回だけコンストラクタを呼び出すことになります。生徒の名前を引数として渡すことで最初に宣言した生徒のリストの配列の中に格納されることになります。
ここで、生徒の学年を確認するために関数を記述する必要があります。そして、生徒が本当に実在するかチェックするために別の関数も用意します。
pragma solidity ^0.4.18;contract Grades{mapping (bytes32 => string) public grades;
bytes32[] public studentList;function Grades(bytes32[] studentNames) public {
studentList = studentNames;
}function giveGradeToStudent(bytes32 student, string grade) public {
require(validStudent(student));
grades[student] = grade;
}function validStudent(bytes32 student) view public returns (bool) {
for(uint i = 0; i < studentList.length; i++) {
if (studentList[i] == student) {
return true;
}
}
return false;
}}
関数giveGradeToStudent は「生徒の名前」と「学年」の二つの引数を持ちます。この関数giveGradeToStudentは関数validStudent が真偽を判定したかをチェックします。「偽」として返ってきたらコントラクトの実行はキャンセルされます。
最後に、生徒の学年をfetchする関数を記述していきます。関数getGradeForStudent は生徒の名前を引数として取って来て、連想配列からそれぞれの学年を返り値として渡します。
pragma solidity ^0.4.18;contract Grades{mapping (bytes32 => string) public grades;
bytes32[] public studentList;function Grades(bytes32[] studentNames) public {
studentList = studentNames;
}function giveGradeToStudent(bytes32 student, string grade) public {
require(validStudent(student));
grades[student] = grade;
}function validStudent(bytes32 student) view public returns (bool) {
for(uint i = 0; i < studentList.length; i++) {
if (studentList[i] == student) {
return true;
}
}
return false;
}function getGradeForStudent(bytes32 student) view public returns (string) {
require(validStudent(student));
return grades[student];
}}
このチュートリアルの目的は、自力で実装した物をローカルでデプロイできるようになることにあります。この際、Ganacheを使うと便利です。
npm install ganache-cli web3@0.20.3 solc
node_modules/.bin/ganache-cli
Ganacheを動かしながら、新しいターミナルで先ほどのコントラクトをデプロイしてみましょう。「Grades.sol」として保存してください。
node
code = fs.readFileSync('Grades.sol').toString()
solc = require('solc')
compiledCode = solc.compile(code)
ブロックチェーン上でコントラクトをデプロイするとなるとGas(手数料)が必要となります。Gasはデプロイを実行している人に対し、計算コストを提供している人への報酬となります。よってデプロイする際はコストを負担している人に割り当てるGasを設定する必要があります。gas calculatorを使えば設定すべきGas量がわかります。しかし現在ローカルでデプロイしており、使われているリソースはあなた自身の物であるはずなので、この場合はGasを支払う必要はありません。パブリックチェーン上でコントラクトをデプロイする際はきちんとGasを支払う必要があるので注意しましょう。
Web3 = require('web3')web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));abiDefinition = JSON.parse(compiledCode.contracts[':Grades'].interface)GradesContract = web3.eth.contract(abiDefinition)byteCode = compiledCode.contracts[':Grades'].bytecodedeployedContract = GradesContract.new(['John','James'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})
Johnという生徒に「A+」という成績を与えるために新しい関数を呼び出しましょう。呼び出せたら関数getGradeForStudent を介して成績が更新されているか確認してみましょう。
deployedContract.giveGradeToStudent('John', 'A+', {from: web3.eth.accounts[0]})deployedContract.getGradeForStudent.call('John')
'A+'
これでスマートコントラクトをデプロイできました。
これからの学習
以下の内容を踏まえたことでイーサリアムを使ってスマートコントラクトを実装するための手法は確認できたと思います。しかしこれだけでは不十分なのでこれからやっていくと良い学習教材をいくつかご紹介します。
CryptoZombies
CryptoZombiesは何もダウンロードをすることなく、ネット上でゲームを作成していくことでSolidityの概念を習得することができます。CryptoZombiesは無料でプレイすることができます。
Zastrin
Zastrinは無料のコースと有料のコースが用意されています。Zastrinで学習すれば、eBayのような分散化されたマーケットプレイスを一通り作ることができるようになります。
EthereumTech Lab.ではブロックチェーン、特にイーサリアムに対して強い興味を持った学生または社会人のメンバーを募集しています。
発信はMedium上で行い、本格的な開発状況に関する分析、または開発者それぞれの思想をリサーチし、日本語にて発信するなど様々な方向性の記事を作成しています。
EthereumTech Lab.はイーサリアムのモバイルウォレットを開発している”Wei Wallet Team”(*https://github.com/popshootjapan/WeiWallet-iOS) が中心となり、活動を行っています。そのため、オフラインでのイベント/ミートアップ実施の機会も多く開催していく予定です。
ご興味のある方は、こちらよりご応募お待ちしております!!
EthereumTech Lab | イーサリアム研究所
EthereumTech Lab. | イーサリアム研究所
We make Ethereum & DApps Community in Japan. EthereumTech…medium.com
今後の記事更新のお知らせ・イベント情報・最新ニュースはFacebookグループへの参加がおすすめです。