FC2ブログ

翻訳: zk-SNARKs 入門 (その1) (原題:Introduction to zk-SNARKs (Part 1))

どうも、ぺろりんです。

TwitterのDMで怪しげな(笑)アカウントからオススメされたリンク先にあったzk-SNARKsの記事(Introduction to zk-SNARKs (Part 1))、読んでみたらすごく面白かったw
というかこのブログめっちゃ良いぞ!!

……というわけで、自分の勉強がてら翻訳してみました。
皆さんの勉強のご参考になれば幸いです。

そんなに英語が得意なわけではないので、間違いなどあればメールフォームから教えていただけると助かります!

(ちなみに、怪しげなアカウントはdecentriqの公式アカウントですw)


zk-SNARKs 入門 (その1)


概要


この連載では、確率論的なプロトコルの1つで、Goldwasser、Micali、Rackoffにより1985年に初めて記述され、分散台帳技術(DLT)の盛り上がりとともに人気が出てきたゼロ知識証明(ZKPs)について見ていく。まずはこの画期的な仕事の背後にあるいつくかの理論の紹介と、その複雑な機構の種々の要素をどのように実行するのか示すことから始める。Pinocchioプロトコルに従いPythonで実行して、最終的には例題に関するエンドツーエンド[訳注1]のゼロ知識証明になる。主な目標はこのトピックのやさしい入門を提供することで、ZKPsに関する簡潔な数学をかみ砕いて、その背後にあるいくつかの直観的なことを議論する。これに沿って、この技術によって可能になる、いくつかのエキサイティングな応用についても触れる。

そもそも、ZKPとは何のことで、なぜこれを気にしないといけないの?

ZKPは、「証明者(彼女のことはPeggyと呼ぶことにしよう)がある秘密を知っている」ことを秘密の内容を明かさず、承認者(彼のことはVictorと呼ぶことにしよう)にどんな合理的な疑問も残さない証明を与える。たとえばPeggyは、具体的な素因子を明かすことなく非常に大きい合成数の素因数分解を知っていることだったり、解答自体は明かさずに与えられた数独パズルの答えを知っていることをVictorに証明したいのかもしれない。もっと一般的には、ZKPsは検証可能な計算の構成要素として使える:これは弱いクライアントからより計算力の高いワーカーに計算を押し付ける方法で、元のプログラムを実行するのに比べてかなり小さい労力の計算でワーカーが実行した計算の正しさを、クライアントが暗号的学的に証明することができるようなもの。これは、クラウドだけでなく、オンラインのプライバシー、DLTのスケーラビリティや携帯アプリ、その他諸々の応用に影響する非常に強力なパラダイムになっている。

ZKPsについて別の有望な応用は、機械学習の分野にある。この文脈でこの技術は、第三者がモデルのトレーニングや予測の過程で特定のデータが使われたことを証明できるだけでなく、すべてを開示する必要なく特定のデータを持っていることを証明するのに使える。OpenMined は、活発に動いているプライベートでセキュアな機械学習のエコシステムを作るための多重暗号プリミティブ(multiple cryptographic primitives)[訳注2]の先駆的プレジェクト。

だけど、実のところ、ZKPって何?

非常に簡単に言うと、コンピューター上で表現されるとZKPは、Peggyによって注意深く計算され、Victorが計算が正しいことの証明を検証するために実行するたくさんあるブール型のチェックと一緒にして数を並べたものでしかない。したがって、ゼロ知識証明のプロトコルはこれらの数から導かれ、検証の確認で定義される。


非対話性と簡潔性


ゼロ知識分野での研究は増えていて、Goldwasser, Micali と Rackoff による初めの論文()が出版されてから色んなプロトコルも提案されている。

これらのプロトコルの主な違いの一つは対話性にある。対話的なゼロ知識プロトコルでは検証者が「証明者がある秘密を知っている」ということを信じられるまで、証明者と検証者がたくさんのメッセージをたがいに交換する。各やり取りのラウンドはVictorによって出された「Peggyが正しい解答を提出しないといけない」問題で、その解答はVictorに検証され、プロトコルによって特徴づけられるブール型のチェックを通過したときにだけ受理される。Peggyがその秘密を知らずにNラウンドすべてチェックに通貨してしまう確率は、Nについて指数関数的に減少する。したがって、Victorは内容については何も知ることがないにもかかわらず、「Peggyがその秘密を知っている」ことをVictorが確信できるまで好きなだけ長く、行ったり来たりするやり取りを続けられる。

逆に、非対話型のゼロ知識プロトコルでは、証明者と検証者の間でやり取りが繰り替えされることがない。代わりにただ1つの"ラウンド"があり、これは非同期的に実行される。公開されているデータ(続くセクションや投稿で議論される予定の内容)を使い、Peggyが証明を作り、Victorが利用できる場所に公開する(たとえば分散台帳上に置く)。これにより、Victorは"ラウンド"完了するため、いつでもその証明を検証できる。対話的な場合はたくさんの証明を作るのに対しPeggyはただ1つの証明を作るとしても、無視できる確率を除き、「彼女が、自分で主張する秘密を確かに知っている」ことを検証者は依然として確信できる。結果的に、非対話型アプローチの利点の1つとして、「検証者に依らない」ことがある。Peggyの証明は、手元にあるその問題の実例(たとえば数独パズル)について普遍的で、Victorだけでなくどんな検証者でも、Peggyの「私は解答を持っている」という主張を後から検証できる。

ゼロ知識プロトコルたちの別の違いは簡潔性にあって、Peggyによって生成される証明のサイズを扱う。簡潔性は、ストレージ容量と検証時間という2つの理由で、分散台帳上に発行されたZKPについて重要な役割を担う。ストレージは非常に高価で、たとえば現時点でビットコイン、イーサリアム、NEO、EOSで各台帳に1KBを保存するときの費用はそれぞれ、$3.83、$2.86、$19.38、$3.00となっていて、ピーク時の費用はもっと高い!変動価格と高価なストレージの効果は、1KBあたり$0.001であるファクトムなどの安価で低価格の分散台帳を使うことで相殺できる。にもかかわらず、証明のサイズはできるだけ小さく保つことが依然として望ましい。加えて証明は素早く検証できることが必要で、そうでないとサードパーティにオフロードする効果が薄れる。したがって、チェーンなしのアプリケーションにとって、検証時間が一定であるだけでなく、生成された証明ができるだけ短くて、理想的には問題の内容によらないことが非常に重要となる。

自然な疑問として、「対話型の証明が好まれる場合があるのか?」ということがある。多くの非対話型プロトコルは、一般に「信頼されたセットアップ」といううるさい問題に悩まされていることがわかるが、これは各々を対話型にした代替プロトコルには存在しない。信頼されたセットアップは、証明を計算するときPeggyに利用される公開データの一部を生成するプロセスにある。このセットアップの詳細は後で議論予定だが、簡単に言うと、このセットアップは、乱数源から発生するある数(一般に「有害廃棄物」と呼ばれる)を公開する集団や、集団が集まった大きな集団による。この乱数源にアクセスする誰もが、プロトコルに従って検証者が受け入れるような偽の証明を生成できる。このような理由で、公開された数を生成する集団によって「有害廃棄物」が破壊されることが重要で、これはこのような集団が信頼される必要があることを意味する。これは実質的に、いつくかの非対話型ゼロ知識プロトコルの適用可能性を扱いにくいものにする。

しかしながら多くの場合、非対話性や簡潔性では大して得をするわけではない。非対話性は、たくさんの独立な検証者が、与えられた証明を各々個別に証明者へ問い合わせを行わずに検証したいときにのみ有用となる。簡潔性は、証明を保存するために使われる中間物が非常に高価か、非常に短い検証時間を求めているときのどちらかまたはこの両方であるときにのみ必要となる。しかしながら、分散台帳は特段の例外として一般にストレージは安価で、パブリックブロックチェーン上のブロック間時間に強いられるような厳しい制約がなければ検証時間もまた柔軟であり得る。

これは、2つの対象がHTTPSのように安全なチャネルを使ってやり取りするようなB2Bアプリケーションでは、対話型の証明でやっていけることを意味する。検証者は信頼されたセットアップを実行する責任があるとして、ユースケースに応じて企業がPeggyかVictorの皮をかぶることができる。このやり取りは自然に1対1なので、検証者は偽の証明には興味がなく、オンチェーンに証明を保存する必要もなく、Victorは検証を実行する時間をより多く割く余裕があり、このようなアプリケーションは対話型の状況ではたらく。

このちょっとした遠回りに続いて、この連載で興味のある主題である、非対話型で簡潔な証明に戻る。特に、ここではゼロ知識(zero-knowledge)で、簡潔(Succinct)かつ非対話型(Non-interactive)の計算による知識証明、またの名を「zk-SNARKs」というものに興味がある。特筆すべきアーリーアダプターの中でも匿名暗号通貨のZcashと、スマートコントラクトのプラットフォームであるEthereumで使われており、zk-SNARKsはゼロ知識プロトコルで最も広く使われている。


QAP:計算から多項式へ


zk-SNARKプロトコルをより厳密に説明する前に、いくつかの背景に言及しておかないといけない。
ゼロ知識プロトコル一般に言える複雑なことの1つとして、これらを適用可能にするために、元の問題を完全に変形してやらないといけない、ということがある。

PeggyがVictorに対して、「自分が方程式 x2-4=0 の解を知っている」ことを、この解が何かを明かすことなしに証明したい、という状況を考える。この場合解は自明で、誰でもこの解答を導けるので現実的にはこの問題にゼロ知識証明は不要だが。それもかかわらず、2次多項式に代わってこれを1万次の多項式に簡単に拡張できることを念頭に置きつつ、話を簡単にするために、この連載ではこの例を見る。

それで、この問題をどう読み替えていけば良いのだろうか?

この過程の詳細はVitalik Buterinによる素晴らしい投稿の2次算術プログラム(QAPs:Quadratic Arithmetic Programs)にあり、さらなる読みものとしてこれを強くおすすめする。ここでは、この「変形」の短いまとめを提供する。

まずはコードでこの問題を表すことから始める。すなわちPythonでは、計算を読み替える、次の簡単な関数を定義できる。
def f(x):
y=x**2-4

Peggyとしては「自分だけが知っているある秘密の値xにおいて上の関数を評価すると、yが0になる」ことが目標。明らかに、少なくとも2つの問題がある。
・xの値は知ることなく、関数を実行する最後にyの値の"ピーク"をVictorが得られる方法を見つける必要がある。
・Peggyはプログラムの実行者なので、コードの今の定式化では、VictorはPeggyが確かに実行したどんなコードも制御できない。たとえば、Peggyは条件を満たすy=0というだけのコードを走らせるズルをすることもできる。

これらの問題のどちらも、解決がとても難しいように見える。当然、この答えは上述した問題のかなり非自明な再定式化を必要とし、すなわちこれのQAPへの変換が必要となる。これは、コードの平坦化(code flattening)、rank 1の拘束系(R1CS: rank-1 constraint system)への変換、最後にQAPの定式化、という3つのステップを踏む。

コード平坦化のゴールは、任意の複雑な主張や表現を含むような元のコードを、次の2つの形からなる一続きの主張に変換することとなる。
・x=y(ここで、yは変数でもある数でも良い)
・x=y(op)z (ここで、op∈(+,-,*,/)であり、yとzは変数でも、ある数でも、部分式でも良い)

これらの主張を算術回路のゲートとして考えられる。ここで出している例のプログラムの回路は、次のように見られる。
元記事の図も参照)

x -----┐
x ---------→ * ---(out_1)---┐
-4----------------------------→ + ---(y)---→

対応する「平坦化されたコード」は次のようなものになる。
def f(x):
out_1 = x * x
y = out_1 - 4

次のステップでは、これをR1CSに変形する。R1CSというのははベクトル(ai, bi, ci[訳注3]のトリプレットのリストで、この解は、任意の i について
ai, s〉 * 〈bi, s〉 - 〈ci, s〉 = 0
を満たすようなベクトル s となる。ここで、〈・,・〉は2つのベクトルのドット積(内積)を表す。このトリプレットは、この方程式を満たすような s を探して満たす必要のあるような拘束条件を定義していると解釈できる。

例に挙げているコードの平坦化したものをR1CSに変換する、自然な方法がある。まずプログラムの主張を満たすようなベクトル(すなわち、プログラム内で使われるすべての変数)を定義する。このベクトルの各成分は1つの変数で、その解 s は各変数を割り当てたものになる。

今のプログラムの変数ベクトルは、次のようなものになる。
s = (1, x, out_1, y)T
1つ目の成分として1を含むのは、後で簡単に見るように、これによって拘束条件を満たすようにするため。

このベクトルを定義して、平坦化したコードの各行を順次処理して適切なaibiciを定義することで、今の行に含まれる計算の読み替えを続ける。

たとえば、この関数の中身で最初の行を読み替えるには、以下のように設定する。
a1 = (0, 1, 0, 0)T
b1 = (0, 1, 0, 0)T
c1 = (0, 0, 1, 0)T

2行目の読み替えには以下を使う。
a2 = (-4, 0, 1, 0)T
b2 = (1, 0, 0, 0)T
c2 = (0, 0, 0, 1)T

この2つの行について、読み替えを展開してチェックしてみる。2行目で-4という定数を表すために、aiの定義のところでsの第1成分で1をどう使うかも見る。

1行目:
a1, s〉 * 〈b1, s〉 - 〈c1, s
= Σni=1 a1 si * Σni=1 b1 si - Σni=1 c1 si
= x * x - out_1
=0

2行目:
a2, s〉 * 〈b2, s〉 - 〈c2, s
= Σni=1 a2 si * Σni=1 b2 si - Σni=1 c2 si
= out_1 - 4 - y
=0

上記によって、このPythonプログラムがコンピュータのコードから高速条件の集合へうまく変換された!コードのロジックは制限されたベクトル(ai, bi, ci)のトリプレットに"移送"された。このプログラムの実行は、R1CS方程式
ai, s〉 * 〈bi, s〉 - 〈ci, s〉 = 0 ( i は任意)
を満たすようなsの成分を見つけることと等価になっている。
QAPへの変形を完了するのに、ベクトルから多項式へ転換する必要がある。 i ∈ [1, N] として、多項式 Ai(x)、Bi(x)、Ci(x)を定義することから始める。ここで、Nは制限ベクトルの成分の数(今の場合は4)となっている。Ai(n) = an,i (Bi(n)、Ci(n)も同様)と要請し、これらの点に基づいたLagrange補完をすることでこれらの多項式を構成する。

今の例では次のように要請する(Bi、Ciも同様)。
A1(1) = 0
A1(2) = -4
A2(1) = 1
A2(2) = 0
Lagrange補完をすると、次の多項式に到達する。
A1(x) = - 4x + 4
A2(x) = - x + 2
A3(x) = x - 1
A4(x) = 0

B1(x) = x - 1
B2(x) = - x + 2
B3(x) = B4(x) = 0

C1(x) = C2(x) = 0
C3(x) = - x + 2
C4(x) = x - 1

これらの定義によって、今や1つの方程式として上記をR1CSで表現できる。
A(x) * B(x) - C(x) = H(x) * Z(x)
ここで、
A = (A1(x), A2(x), A3(x), A4(x))
B = (B1(x), B2(x), B3(x), B4(x))
C = (C1(x), C2(x), C3(x), C4(x))
A(x) = 〈A, s
B(x) = 〈B, s
C(x) = 〈C, s
Z(x) = (x - 1) (x - 2)
また、H(x)はすべてのxについてA(x) * B(x) - C(x) = H(x) * Z(x)を満たすようなものであると要求する。

まだここ?よろしい!ここで、次のようなことが疑問じゃないだろうか。
・なんでこんなことしたの?
・Z(x)ってなんやねん
・H(x)は何者で、誰が思いつくの?

これらの質問に答えるため、まず次のようなことを見る。定義により
A(1) = a1
A(2) = a2
として、B(x)C(x)も同様とする。A(x)、B(x)、C(x)の定義も用いると、これは元のR1CS系が以下と等価であることを意味する。
A(x) * B(x) - C(x) = 0 (x∈{1, 2})
これを満たす唯一の方法は、A(x) * B(x) - C(x)が (x - 1) (x - 2) で割り切れるとき、すなわち以下のような H(x) が存在するときとなる。
A(x) * B(x) - C(x) = H(x) (x - 1) (x - 2)
これはH(x)とZ(x)が何かを明らかにしてくれる。しかし、誰がH(x)を計算するのだろうか?H(x)を(A(x) * B(x) - C(x))/Z(x) として計算することにより、背後にあるR1CSを満たすsの成分を知っていることを示すので、H(x)を計算するのは証明者だろう。したがって大雑把に、QAPを(A, B, C, Z)という4-タプル[訳注4]sをこのQAPの"解"と考えることができる。

最も大事な質問にまだ答えていない。なぜこんなことをする必要があるのだろうか?

Pythonのプログラムとして今の問題を表現していたことを思い出すと、次のような1組の大きな問題に突き当たる。
・Peggyが正しいプログラムを動かしていることを検証する方法が無い
・他のどのんな情報も明かさずに、プログラム実行の最後におけるyの値をどうやってVictorに観測させるかが明確でない

R1CSとして表現された計算だと、Victor妥当なsの割り当てを見るとすると、Peggyが対応するR1CSのプログラムを実行したことを確信できる!これは主な問題の1つをすでに解決している。

QAPを得るためにR1CSをさらに変形する理由は、多項式で説明する方がR1CSで説明するよりも有益だから。次のセクションではこの新しく提案された「問題の再定式化」を、zk-SNARKsを構成する中心となる1つの技術を説明するのに使うが、これは多項式の構造を利用する。


隠れた点における多項式の評価


多項式を処理するうまいやり方の1つに、知らない点で多項式を評価するものがある。これは多項式の目隠し評価(?blind evaluation of polynomials)としても知られる。まってwつまり……どういうことだってばよ?!そう、お分かりの通りこれは不可能に違いない。与えられた多項式
P(x) = a0 + a1 x + a2 x2 + ... + an xn
について、この多項式を評価したいとすれば、xを知らなければいけない。実際に今はこういう場合だけど、いつくかの追加情報を使えるとすれば、評価するときのその点xを知ることなく、多項式を評価できる!

次に、次のような性質を持つある関数 f(x) を使うことを考える。
1.1方向性:与えられた x について簡単に y = f(x) が計算できるが、与えられた y について y = f(x) となる x を見つけることは難しい
2.線形性: f(αx + βy) = αf(x) + βf(y)
3.x≠y ⇒ f(x)≠f(y)

このような関数がどのように目隠し評価する助けになるのか見てみよう。簡単に可視化するために、Peggyがこの問題においてその点で多項式を評価したとVictorが検証できるような方法で、VictorがPeggyに、どちらもが知っているPの目隠し評価を問い合わせるとする。さらに、fは存在して、PeggyもVictorも知っている知っているとする。

まずVictorは、その多項式を評価したいある点 x0 を選ぶ。そしてこの点 x0 を f に食わせて新たな点(zとする)を出して、この z をPeggyに送る。fの1つ目の性質により、Peggyが z から x0 を得られないことに注意する。さらに、f の3つ目の性質から、f(x'0) = z となるような x'0(≠x0)を見つけることもできない。これら2つの事実から、ひとたびPeggyがVictorから z を受け取ると、Peggyが元の x0 を逆算する手段がないことを意味する。

P(x) = a1 x である場合を考える。与えられた z = f(x0) について、Peggyは簡単に P(z) = a1 z を計算できる。 f の線形性により、以下に注意する。
P(z) = P(f(x0)) = a1 f(x0) = f(a1x0) = f (P(x0))
これはまさしく欲しいもので、P(z) の計算により、x0については何も知らず、Peggyが実質的に f (P(x0)) を計算したことになっている!f、P、x0は知っているのでVictorは、ここでPeggyによって計算された P(z) を見て自分のところで f (P(x0)) と比べる。 もしこれら2つの結果が一致すれば、x'0(≠x0)での評価は別の結果になることを考慮すれば、VictorはP が x0 で評価されたことを確信できる。

上記のアプローチを任意の多項式に一般化するために必要な変更は1つで、Victorがより多くの情報をPeggyに送ればよい。特に、d を評価したい多項式の字数として、Victorは以下の情報をPeggyに送れば良い。
f(1), f(x0), f(x02), ..., f(x0d)
この情報を使い、今やPeggyは、x0 について何も知ることなく
f (P(x0))
= f(a0 + a1 x0 + ... + an x0d)
= f(a0) + f(a1 x0) + ... + f(an x0d)
= a0 f(1) + a1 f(x0) + ... + an f(x0d)
を計算でき、さらにVictorは、f、P、x0 を知っているので、この結果が正しいことをチェックできる。


結論


この連載の1つ目の投稿では、簡潔性と対話性というような、ゼロ知識プロトコルのレベルの高い性質のいくつかを議論した。これらに基づいて、zk-SNARKsというこの連頼の主題を導入し、Pythonで書いた簡単なプログラムについてzk-SNARKを構成しようとしたときに生じつ問題のいくつかを紹介した。これはR1CSとQAPの導入に動機づけられていて、コンピュータのコードを、zk-SNARKの構成に親しませてくれて、より形式的で数学的に柔軟な方法でコンピュータのコードを理解させてくれるような、QAPに変形する例を挙げた。最後に、この連載の続編で中心となる予定の、多項式の目隠し評価という強力な道具を道具箱に加えた。

次回は、zk-SNARKという十徳ナイフ(Swiss army knife)[訳注4]を、隠れた点で多項式の評価に使った"魔法の"関数 f を構成するのに必要な道具に拡張し、Pythonでこの技術の実装を提供する。ではまた!


(原文)
zk-SNARKs 入門 (その1)(decentriq)

(参考)
増える開発者、増える破壊:Zcashの暗号セレモニーが進行中(COINPOST)
イーサリアムに導入されたプライバシー保護技術「zk-SNARK」とは(ZOOM)


[訳注1] エンドツーエンド…以下を参考。
 ・エンドツーエンド原理(Wikipedia)

[訳注2] 暗号プリミティブ…以下を参考。
 ・公開鍵暗号方式の構成(シニアエンジニアの庵)

[訳注3] この訳では、ベクトルを太字で表現し、上付き添え字の「T」は転置を表す。(矢印表記とか縦ベクトルをブログで書くのがめんどくさかったのでw)
[訳注4] タプル…以下を参考。
 ・タプル(Wikipedia)

[訳注5] スイス・アーミーナイフ…以下を参考。
 ・アーミーナイフ(Wikipedia)

テーマ : プログラミング
ジャンル : コンピュータ

Keyword : ブロックチェーン blockcahin ZK-SNARKs Ethereum イーサリアム Zcash

ブロックチェーン関連の記事紹介まとめ(2019年2月:#32-59)

どうも、ぺろりんです。

ブロックチェーンや暗号資産(仮想通貨)関連の記事や論文などのデイリー紹介ツイート、2か月目のまとめです!
ご興味ある記事があれば、ぜひ元記事も読んでみてください!

<< 2019年1月:#1-31


記事紹介まとめ(2019年2月:#32-59)



























































テーマ : ビジネスアイディア
ジャンル : ビジネス

Keyword : ブロックチェーン blockcahin 暗号資産 仮想通貨 イーサリアム Ethereum リップル Ripple

コントラクトの継承と連携(他のコントラクトのメソッド実行)

どうも、ぺろりんです。

「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門 (DEV Engineer's Books)」をテキストとして使った勉強のつづきです。(前回の記事はこちら

実を言うと今回はChapter 4の「会員管理」をやりたかったんですが、以前サラッと流し読みしたところがソースコードに出てきて詰まりましたw
というわけで、今回はChapter 3の「コントラクトの継承」と「他のコントラクトのメソッドを実行」というセクションに戻って理解を深めようと思います。

ここで私が理解したいのは「(1つのソースコードに)2つ以上のコントラクトが書いてあるときの動き」です。
これを「コントラクトの継承」と、「他のコントラクトのメソッドを実行」という2つの切り口から調べていきます。(テキストを参照しつつ)


前提知識

お恥ずかしながらオブジェクト指向言語の理解が浅くて、まず単語でつまずきましたw

なので、このへんからちゃんと理解しておこうかと思います。


「クラス」、「インスタンス」とは?

「クラス」は“鋳型”とか“設計図”にあたるもので、これをもとに作られた“実体”が「インスタンス」です。


「メソッド」とは?

実質的には関数だったりしますが、関数とは別の概念です。

オブジェクト指向では
・属性(どんなもの?)…a,b,cという性質を持つ
・操作(何ができる?)…X,Yという動作ができる
をひとまとめにした(a,b,c,X,Y)を1つの「オブジェクト」と考えます。

オブジェクトができる「操作」のことを「メソッド」と呼びます。

ちなみに、
〈オブジェクト〉.〈オブジェクト内の変数や関数名〉

と書くことで、〈オブジェクト〉内で定義された属性や操作を呼び出せます。


「継承」、「オーバーライド」とは?

オブジェクト指向では、親子関係をつけたクラスを定義することができます。

何がうれしいかと言うと、たとえば2つのクラスAとBを定義するときに、AとBには共通の性質Pがあったとします。

「性質Pを持った親クラスX」を作ってAとBをXの子クラスとすれば、子クラスは親クラスの性質を引き継ぐため、AとBの中で共通の性質Pを定義する必要がなくなります。

この「子クラスは親クラスの性質を引き継ぐ」性質を「継承」と呼びます。

子クラスの中で、継承した親クラスの変数などを上書きするのが「オーバーライド」です。

ここまでがオブジェクト指向についての前提知識です。
このへんの理解をちゃんとしておかないと分からない!(私だけか……?w)


「コントラクト」、「デプロイ」とは?

オブジェクト指向の言葉はすこし分かった気がしますが、今度はイーサリアムの言葉の理解も浅いことに気付きましたw
まだいまいち「コントラクト」と「デプロイ」のイメージがつかめてなかったので、これらも調べてみました。

ここまでオブジェクト指向の言葉を復習しておくと、以下のような理解ができるようです。
ブロックチェーンEthereum入門 3(NTTデータ先端技術株式会社)より)

オブジェクト指向言語との対比ではコントラクトのソースコードはクラスであり、デプロイはインスタンス化すること



(参考)
“たい焼き”であま~く理解するJava文法と言語仕様 (1/2)(@IT)
【PHP超入門】クラス~例外処理~PDOの基礎(Qiita)
Javaでインスタンスを使う方法【初心者向け】(TECHACADEMYmagazine)
メソッド (method)とは(「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典)
ブロックチェーンEthereum入門 3(NTTデータ先端技術株式会社)


コントラクトの継承

さて、ここまでの前提知識をもとに、「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門 (DEV Engineer's Books)」へ戻ってきます。

コンパイラのバージョンをソースに合わせつつ、サンプルコードをコンパイルします。



このサンプルコードの概要としては以下のようなものです。
・1つのソースコードの中に
  ①コントラクトA
  ②AのサブコントラクトB
  ③コントラクトC
 という3つのコントラクトが書いてある。
・コントラクトCの中で、AとBをデプロイしている(「new」コマンドを使うことでデプロイできる)。

このサンプルコードで、コントラクトの継承について動きを見ていきます。

初心者の私としては、はじめは素朴に「上に書いてるAから順にSolidityでデプロイしていくべきなのかな?」と考えました。

しかしよく考えてみると、コントラクトCの中でAとBのインスタンスを作っている(デプロイしている)ので、コントラクトCだけデプロイすれば事足りるのでは?

……と思って、コントラクトCのみデプロイすることを試してみました。
Cだけ選んで、EnvironmentをJavaScript VMにしつつデプロイしてみます。



できたのはCだけです。


この状態で「c」と「getData」を押してみても初期状態という感じです。



ソースコードの中で、コントラクトAとBのインスタンスを作っている(中でnewしている)関数「makeContract」を押してみます。
この後ふただび「c」と「getData」を押してみると、値を拾っています。


今度は、はじめに考えていた通り、A、B、Cの順にすべてデプロイしてみました。



この状態で、青いボタンだけ押してみます。

特に何も値は入っていません。



ちなみにここで、BはAを継承しているため、Bの中では定義されていない「setA」と「a」のボタンがBのところにもあります。

ためしに、Aのところで
a=15
と設定して「setA」を実行してみます。


この直後にA、B、Cで青いボタンを押してみます。
すると、Aの「a」と「getData」の値のみ変わりました。



次に、Bのところで
a=20
と設定して「setA」を実行してみます。


この直後にもA、B、Cで青いボタンを押してみると、今度はBの「a」と「getData」の値のみ変わりました。



Aの中に定義された「a」をBの中でも定義していますが、これは別に、BがAの中で定義した「a」の値を参照する動きにはなっていないようです。

この時点でCの「makeContract」をするとどうなるでしょうか?
これを実行しつつ、Cの中の「c」と「getData」を押してみます。


Cの中ではあくまで
a=1
としてAとBのインスタンスを作成して計算しているので、先ほどAやBの中で設定した「a」とは関係なくCの中で計算されていることがわかります。

ちなみに、Cで「makeContract」した後も、AとBの中にある「a」と「getData」は変わっていませんでした。


どうやら、以下のようなことが言えるようです。
・AとBのインスタンスを中で作っているCだけデプロイすれば、AとBをデプロイしなくてもCは結果を出せる。
・A、B、Cをそれぞれデプロイすると、それぞれは独立に動く(設定した「a」の値は、あくまで各A、B、C内でのみ使われる)。

ちなみに、「new」コマンドを消して、Cの中でインスタンスを作らずAやBを呼んでみる……みたいなことを試したかったのですが、そもそもコンパイルできるコードにできず断念しましたw


他のコントラクトのメソッドを実行

次に、他のコントラクトのメソッドを実行するサンプルコードをコンパイルしてみます。


コードの概要としては、以下のようなものです。
・1つのコードに
  ①コントラクトA
  ②コントラクトB
 の2つが書いてある。
・コントラクトBの中で「コントラクトA」や「Aの中で定義した変数」を呼ぶけど、Aの“インスタンス化”(newコマンド)はやらない。

先ほどの「継承」ではコントラクトCの中でAとBをインスタンス化していたので、CだけデプロイすればAやBの中にあるデータを拾ってきました。

しかし今回はコントラクトBの中でAのインスタンス化はしていないので、おそらくBだけデプロイしても「Bで呼んでいる、Aの中で定義した変数」の値は拾えないでしょう……という想定のもと、まずはBだけデプロイしてみます。



ためしにBだけデプロイした状態で青いボタンだけ押してみると、どれも初期状態です。
(というかコントラクトAをデプロイしていないので、そもそもコントラクトAのアドレスを入れなさいという場所に何も入れられない……)


次に、Aもデプロイしてみます。



さて、Aのアドレスを入れて「setA」を押してから、Bの青いボタンを押してみます。



めでたく値を拾うことができました。

コントラクトAをデプロイしたときのアドレスを使うことでAとBが紐づいて、BからAの中で定義された変数の値を呼び出すことができました。

コントラクトBで定義されているsetA(A _a)の中では、setA(A _a)の引数として与えられたAのアドレス_aを
a = A(_a)

というようにセットします。

aNum()はa.num()を返すことで(numはコントラクトAの中で定義された状態変数)、Aで定義されたnumの値を返します。

〈オブジェクト〉.〈オブジェクト内の変数や関数名〉

とすることで〈オブジェクト〉内で定義された変数や関数が呼び出せることを思い出すと、「a = A(_a)」は「オブジェクト」になっているようです。

つまり、コントラクト名の引数にそのコントラクトのデプロイアドレスを指定したら「オブジェクト」化(もしくはインスタンス化)されるようです。

(参考)
インスタンスの考え方・クラス型変数・コンストラクタ・静的メンバ(Qiita)
【基本の基本】Javaのデータ型とは?と簡単な使い方まとめ(エンジニアの入り口)
Ethereum 外部コントラクトの呼び出し方法(Remix, MetaMask連携)(Qiita)


まとめ

オブジェクト指向言語に慣れている方だとそんなに困らないのかも知れませんが、私は慣れておらず詰まりながらいくつか試してみましたw
オブジェクト指向言語の本も手元に置いておく方が良さそうだなぁ。。

今回触ってみて、個人的には以下のような理解が得られました。
・1つのコード内に複数のコントラクトが含まれるとき、
 ①あるコントラクトXの中で別のコントラクトYをデプロイしているならば、XをデプロイすればYのデプロイは不要。
 ②それぞれのコントラクトを別々にデプロイすると、各々が独立して動く。
・コントラクトZの引数にそのコントラクトZのデプロイアドレスWを指定したZ(W)は「オブジェクト」化(インスタンス化)される。

デプロイアドレスがJavaなどで何にあたるのか分からないのですが、デプロイアドレスを引数に指定するとオブジェクト化するというのが分かったような分からないような……w

では今回はこのへんで~(´・ω・`)

テーマ : プログラミング
ジャンル : コンピュータ

Keyword : ブロックチェーン blockcahin 仮想通貨 暗号資産 イーサリアム Ethereum Solidity

ブロックチェーン関連の記事紹介まとめ(2019年1月:#1-31)

どうも、ぺろりんです。

ブロックチェーンや暗号資産(仮想通貨)関連の記事や論文などについて、Twitterで1日1つ紹介&コメントをつぶやく試みを2019年1月1日から始めてみました!
増えてくると見づらいと思うので、1か月ごとにツイートをこのブログにまとめていこうかと思います。

2019年2月:#32-59 >>


記事紹介まとめ(2019年1月:#1-31)

































































テーマ : ビジネスアイディア
ジャンル : ビジネス

Keyword : ブロックチェーン blockcahin 仮想通貨 暗号資産 イーサリアム リップル

「価値のインターネット」ってなんだろう?

どうも、ぺろりんです。

今回は、Rippleの言う「価値のインターネット」について自分なりに考えて再構築してみました。

抽象化して考えを再構築することで、より広い範囲に応用できるんじゃないかと思っています。

ここでは、「価値」を“資本主義経済における”「価値」であると考えることにします。
この前提で、まず経済学的に「価値」がどう考えられているかを調べ、「インターネット」がどんなものか考えた上で、「価値のインターネット」がどんなものか、どうあるべきものかを考えてみます。


価値とは何だろう?

結論

はじめに結論を書いておくと、資本主義経済において「価値=交換可能性」です。

資本主義経済の本質は「交換」で、この交換の動機は「差異」から生じます。
「差異」のある対象同士が「交換」されたとき、対象の「価値」が実現されます。

私の考えでは、この「差異」には以下の2種類が存在します。
(1)交換“対象”自体が持つ、“質”および“量”の差異
(2)交換対象の“所有者”が持つ、“主観価値”の差異

また、「交換」であるということは、以下のような点を含むことが重要だと考えています。
(A)絶対価値は存在せず、「価値」は常に相対的
(B)やり取りは一方的ではなく、常に2つ以上の対象(「交換するもの」と「交換されるもの」)が登場する


補足

経済学の本なんかには、ここで書いた「交換対象」は「商品」と書かれていたりします。
資本主義経済はこの「商品」の交換によって成り立っているわけですが、交換しようと思うのはなぜかというと、「自分が持っているもの」と「他人が持っているもの」に「差異」があるからです。
まったく同じものだったら交換する意味はありません。

経済学の価値論では、「価値」には「価値(or 交換価値)」と「使用価値」があると言います。

前者の「価値(or 交換価値)」は(1)につながる概念かと思います。
後者の「使用価値」は(2)に当たるもので、近年になって「効用価値」という考えが出てきた流れで「主観価値」とも呼ばれるようになったと理解しています。

(1)の「差異」はわかりやすいのですが、(2)の「差異」は経済学でも議論されるレベルで測定(というか定義)がむずかしいものです。

(2)の「差異」を考える上で、調べていた中で面白かったのが「マズローの欲求5段階説」を用いた話です。
これでもまだギャップがありますが、「主観価値」を定量化する足掛かりにはなりそうに思います。
少なくとも、「主観価値」とか「効用」とだけ言うよりは具体化されています。

(参考)
Textbook 資本主義経済の理論
市場経済と価値―価値論の新機軸 (明治大学社会科学研究所叢書)
限界効用価値説の展開と労働価値説との対比 : マルクス経済学と「限界革命」Ⅳ(山梨学院リポジトリ)
利益を生み出す「価格」の秘密(帝国書院)
経済学と労働価値説(九州大学)
文化と固有価値の経済学(J-Stage)
「価値」とは何か~あなたは価値を生み出せていますか~(Eureka!)
創造性における自己実現欲求と価値について―マズローの自己実現的創造性の検討―(CiNii)
マズロー=ウィルソン欲求理論が含意するもの(II)(明治学院大学)


インターネットとは何だったの?

結論

インターネットは、ひと言で表すなら「“データをやり取りするネットワーク”の、分散管理ネットワーク」です。


補足

Internetの単語自体も、「Inter-(間)Net(=Network)」というつくりをしています。

インターネット以前は、世界各地に点在する企業や学校などが各々が独自にコンピュータのネットワークを構成して、自分たちの中でコンピュータ同士のデータのやり取りをしていました。
インターネットの登場により、個々の組織で閉じていたネットワーク同士がデータのやり取りをできるようになりました。

そしてインターネットは、一元管理する「管理者」は存在しない「分散管理ネットワーク」になっています。

(参考)
平成11年版 通信白書 第1章 特集 インターネット コラム2 インターネット -「ネットワークのネットワーク」-(総務省)
インターネットって何?(総務省)
インターネットとは(日本ネットワークインフォメーションセンター)
【違い2】インターネットとネットワーク(OWLet)
Rippleプロトコル入門(Ripple総合まとめ)


じゃあ、価値のインターネットとは?

結論

私なりの結論としては、「価値のインターネット」とは「分散ネットワークにおける、データ差異の交換」です。

このとき、以下の点に注意する必要があります。
(1)分散ネットワークにおいて、データの一意性が保証されないといけない
(2)「交換」であるので、一方が“全取り”することはできない(「“0”と交換」という広義の解釈はアリだと思います)

すべての“モノ”や“コト”は何らかの方法でデータ化(もしくは「トークン化」)された時点からインターネット上でやり取りが可能になり、それらの差異はデータの一意性が保証された「価値のインターネット」上で「交換」が可能になります。


補足

これまで書いた内容から「価値のインターネット」は、「価値=交換可能性」にあたるデータを「分散ネットワーク」でやり取りするものだと言えます。

インターネット上でやり取りするのはあくまで「データ」で、「価値」の源泉が「差異」にあることから、やり取りされるものは「データの差異」であるはずです。
また、「価値」が実現されるためには「交換」される必要があります。

このような考えから、上記の結論に至りました。

(1)について、「交換可能性」の源泉である「差異」が、(コピペするようなノリで)消えたり簡単に現れたりしては困ります。
「差異」がなくなれば「交換」の動機はなくなるため、この「差異」はやり取り(=「交換」)の間、保存されないといけません。
これは分散ネットワーク上で、データの一意性が保証されていれば良いかと思います。

「データが一意であること」は「同じ時刻にそのデータが1か所にしか存在できない」わけです。
分散ネットワークにおいて、これはブロックチェーンによる「データの順序付け」により達成されます。

(2)について、一方が、もしくは交換の仲介者が“全取り”することを防ぐのは、RippleからすればInterledger Protocol(ILP)で実現できます。
私がここで言う「交換」は何らかの通貨で媒介してもしなくても良いと思っていますが、Ripple的にはXRPに仲介させて「交換」するのがベスト、ということになるのでしょうw

(参考)
価値のインターネット:何を意味し、どのような恩恵を人々に与えるか(Ripple)
Ripple Protocol Consensus Algorithm日本語訳(Qitta)
価値のインターネットとは(Ripple総合まとめ)
IoV(Internet of Value:価値のインターネット)とは・意味(HEDGE GUIDE)
ブロックチェーンがもたらす次の破壊と創造 第6回 日本銀行・副島豊、gumi・國光宏尚、アクセンチュア・高橋良之の3氏による鼎談(日経BizGate)
日本政府は“トークンエコノミー”を理解できていない(アゴラ)


まとめ

資本主義経済における「価値」を前提として、「価値のインターネット」がどんなものか自分なりに考えて再構築してみました。

私の結論としては、「分散ネットワークにおける、データ差異の交換」が「価値のインターネット」であるという考えに至りました。

これは以下のような考えからきています。
(1)インターネットであるからには「分散ネットワーク」でデータがやり取りされる
(2)価値の源泉が差異であることからやり取りされるべきは「データの差異」である
(3)価値を実現するためにやり取りは「交換」でなければならない

抽象化しすぎて無意味になっていたりすると悲しいですが(笑)、ブロックチェーン応用の足しにちょっとでもなれば良いなと思います(´・ω・`)

現状ある考えでの、もう少し具体化された応用というのがイケハヤさんの記事だったり赤メガネとコムギさんのVoicy配信だったりで取り上げられている「トークンエコノミー」の世界観だったりします。
これに関しては、「ポイント」との違いについて考えるのも面白いです。

……といったところで、今回はこのへんで。

テーマ : ビジネスアイディア
ジャンル : ビジネス

Keyword : ブロックチェーン blockcahin 仮想通貨 暗号資産 Ripple リップル 価値のインターネット

プロフィール

ぺろりん

Author:ぺろりん
まだ始まってもいない暗号資産(仮想通貨)、今後が楽しみです。
基本的な技術をちゃんと知りたいなぁと思いつつ、まったりお勉強していこうかと思います。

twitter:ぺろりん@ぶろっくちぇーん

カテゴリ
最新記事
最新コメント
月別アーカイブ
カレンダー
02 | 2019/03 | 04
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
メールフォーム

名前:
メール:
件名:
本文: