マルウェア+ブロックチェーン=❤️

この記事では、Ethereumプラットフォームでスマートコントラクトを作成するサイクルを続けます。 最初の部分では、 Solidityで新しい暗号通貨を作成する方法を示すことを約束しました(ブロックチェーンの世界では、これは「Hello、world!」の類似物のようなものです)。 しかし実際には、これについてはいくつかの良い記事が既に書かれているので、これは意味がありません( Solidity docks の例、Ethereumメインページの例 )。







それで、少し考えて、スマート契約の別のユースケースを見つけました。 この記事では、理論上、暗号化トロイの木馬の作成者がスマートコントラクトを使用して復号化用のキーを販売することで、彼の子供を収益化する方法を示します。







ところで、以下に書かれているものはすべて純粋に教育的な性質のものです。









一般的な考え方



暗号作成者は昨日登場せず、ほぼ同様の作業スキームを持っています。 そして、このスキームのルールとして、フォームのステップがあります









システムのこれら3つのフラグメントをブロックチェーンに転送しようとします。







プロジェクトの一般的な構造



プロジェクトは、管理モジュールと「ストア」モジュールの2つの部分で構成されます。 管理パネルは別の契約として作成し、ストアの契約を単純に継承します。 一般的に、イーサリアムでは、ブロックチェーン内の2つの異なるコントラクト間で対話できます。それらのアドレスと、関心のある関数の名前を知る必要がありますが、次回はこれについて説明します。







ツールボックス



Solidityバージョン0.4.2に書き込みます(現在のバージョンは2016年10月26日です)。 開発環境として、 オンラインコンパイラまたは最近リリースされたオンラインプラットフォームEthereum studioを使用できます。 後者はc9.ioに基づいていますが 、イーサリアムで開発するための機能を備えています。 リリースされたばかりなので、自分では使用しませんでしたが、見た目はきれいですが、作成者はおそらくドキュメントを意図的に隠しています。







Mistをクライアントウォレットとして使用し、PoCを実行するだけなので、プライベートブロックチェーンですべての契約を開始します(これを行う方法をここで説明しました )。 それはより簡単で、より安く(無料という意味で)、より速くなります。







コードを書く



最初に、管理モジュールを作成します。 管理者の追加と削除、資金の引き出し、「契約の解除」のための機能を追加します。 まず、必要なすべての変数とコンストラクター関数を定義します。 コントラクト自体と同じ方法で呼び出す必要があり、一度だけ(自動的に)呼び出されます-コントラクトがブロックチェーンにロードされるとき。







pragma solidity ^0.4.2; //    - ,   0.4.2  0.5   contract admin { // VARIABLES struct user { address addr; string name; // '$uPeR_p0wner_1999' string desc; // 'CEO & CTO' } user owner; mapping (address => user) adminInfo; mapping (address => bool) isAdmin; function admin (string _name, string _desc) { owner = user({ addr : msg.sender, // msg -       name : _name, //  . msg.sender -   desc : _desc // msg.value -   wei,    .. }); isAdmin[msg.sender] = true; adminInfo[msg.sender] = owner; } }
      
      





構文はC ++、JS、Cなどを連想させるため、コード自体はシンプルで簡単です。 念のため、struct演算子を使用すると、 既存のデータ型からカスタムデータ型を作成できることを思い出させてください。 ご想像のとおり、マッピングは連想配列(Pythonではdict、C ++ではmap)を実装します。







ここで、所有者変数を作成しました。この変数には、構造体の助けを借りて、契約作成者の住所、名前、および説明を保存します。 イーサリアムの契約には、いわゆる状態があります。つまり、将来、誰かが契約を呼び出すときに、この変数を使用できます。







次に、管理者の追加/削除、資金の引き出し、契約の破棄を担当する機能を追加します。 ここでのすべては、オペレーターイベントという1つのことを除いて、一般に些細なことです。 これは、UIと一般的なユーザビリティの観点から非常に魅力的な演算子であり、これにより、コントラクト内にプッシュ通知のようなものを実装できます。 以下のスクリーンショットがありますが、そこから実際にどのように見えるかがわかります。







 // EVENTS event adminAdded(address _address, string _name, string _desc); event adminRemoved(address _address, string _name, string _desc); event moneySend(address _address, uint _amount); // FUNCTIONS function addAdmin (address _address, string _name, string _desc) { if (owner.addr != msg.sender || isAdmin[_address]) throw; //     /   isAdmin[_address] = true; adminInfo[_address] = user({addr : _address, name : _name, desc : _desc}); adminAdded( _address, _name, _desc ); // Call event } function removeAdmin (address _address) { if (owner.addr != msg.sender || !isAdmin[_address]) throw; isAdmin[_address] = false; adminRemoved( _address, adminInfo[_address].name, adminInfo[_address].desc ); // Call event delete adminInfo[_address]; } function getMoneyOut(address _receiver, uint _amount) { if (owner.addr != msg.sender || _amount <= 0 || this.balance < _amount) throw; //     ,      //   -        if (_receiver.send(_amount)) moneySend(_receiver, _amount); //    -  event } function killContract () { if (owner.addr != msg.sender) throw; selfdestruct(owner.addr); //           }
      
      





このコードはすべて、すでに作成されて管理モジュールの準備ができた後、契約管理者{...}内に追加されるだけです。







ブロックチェーンに注いで結果を楽しんでください



このステップについては、最初の部分で詳しく説明しますが、ここでは詳しく説明しません。 すでに準備された契約での作業のスクリーンショットをいくつか添付します。 Mistのadmin add関数の呼び出し例を次に示します。









そして、約束されたイベントは次のようになります。









ショップ



まず、肝心なのは、キーに対して既に支払済みのアプリケーションのキューを作成することです。 私たちの場合、管理者はこのパイルを手ですくって(自動化できますが、次回はいつでもできます)、即席データベースに各アプリケーションのキーを追加します(_id→_keyの形式のマップを作成しましょう)。 ID、簡単にするために、自然数があり、キーは文字列(たとえば、pastebinへのリンク)になります。







コード自体は85行に収まります。ここは次のとおりです。







 contract shop is admin { // VARIABLES uint[] orders; //     uint currentOrder = 0; //     mapping (uint => string) keys; //  ID -  // EVENTS event keyAdded(uint _ID, string _name, string _desc); event keyBought(address _address, uint _ID); // FUNCTIONS function buyKey(uint _ID) payable { //   payable      if (msg.value < 15000000000000000000) throw; // ,      15  orders.push(_ID); //       keyBought( msg.sender, _ID ); } function getKeyByID(uint _ID) returns (string) { //    ,    return keys[_ID]; //     ID   ,     } function getLastOrder() returns (uint) { if (!isAdmin[msg.sender]) throw; return orders[currentOrder]; //   ID currentOrder += 1; } function addKey(uint _ID, string _key) { if (!isAdmin[msg.sender]) throw; //       - ID keys[_ID] = _key; keyAdded( _ID, adminInfo[msg.sender].name, adminInfo[msg.sender].desc ); } }
      
      





まとめ



ここで書かれているのは、多くのエラーと不完全さを持つプロトタイプであることをもう一度強調します。 簡単な例-私たちの場合、アプリケーションの配列はまったくクリーニングされず、サイズが大きくなるだけです。 このため、いつかbuyKey関数を呼び出すコストは、キー自体のコストまで増加しますが、これは何らかの形で間違っています。







別のより難しい点-最後に処理された注文のシリアル番号を保存するために、currentOrder変数を使用します。 ここで状況を想像してください。2人の管理者がいます。北京のVasyaとニューヨークのPetyaです。 ある時点で、彼らはgetLastOrder関数に目を向け、両方とも何らかの種類の番号を受け取りました-23412としましょう。それぞれがaddKey関数を呼び出し、この注文のキーを「ベース」に追加し、その名前とdescを保存しました。 その結果、鉱夫がこれらの行動を実行し始めると、北京に近いものはより早くヴァシンの要求を満たし、州は1つの見解を持ち、ニューヨークに近いものはペティンと州が異なることが判明します。 その結果、ある種のマージの競合が発生します。







いずれにせよ、ブロックチェーン技術が私たちに提供する素晴らしい機会を実証できたことを願っています。 この単純な契約でも、ハッカーはマルウェアを従来のスキームよりもはるかに簡単かつ安全に収益化する機会を得ることができます。







次の記事では、Mist以外のインターフェースをコントラクトに接続する方法(通常のサイトを介した対話など)、またはPythonなどのプログラミング言語と連動してイーサリアムを操作する方法を説明します。 しかし、何か提案があれば、コメントに書いてください。








All Articles