(57)【要約】【課題】プログラムにおける非決定的動作の検証を高速化する。【解決手段】記憶部１１は、同一の変数への複数回の値の代入を許容するソースコード１３を記憶する。処理部１２は、ソースコード１３を、各変数への値の代入を１回に制限する静的単一代入形式のソースコード１４に変換する。処理部１２は、ソースコード１４から、データベースへの書き込みを示す命令１５を検索し、命令１５において書き込む値が格納されている変数を検出し、ソースコード１４から、検出した変数への値の代入を示す命令１６を検索する。処理部１２は、命令１６における検出した変数に代入される値の取得方法に基づいて、データベースへの書き込みが、ソースコード１３の引数およびデータベースのデータ以外の実行状況に依存する非決定的動作であるか否か判定する。【選択図】図１
2020038482.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータに、
同一の変数への複数回の値の代入を許容する第１のソースコードを、各変数への値の代入を１回に制限する静的単一代入形式の第２のソースコードに変換し、
前記第２のソースコードから、データベースへの書き込みを示す第１の命令を検索し、前記第１の命令において書き込む値が格納されている変数を検出し、前記第２のソースコードから、前記検出した変数への値の代入を示す第２の命令を検索し、
前記第２の命令における前記検出した変数に代入される値の取得方法に基づいて、前記データベースへの書き込みが、前記第１のソースコードの引数および前記データベースのデータ以外の実行状況に依存する非決定的動作であるか否か判定する、
処理を実行させるプログラム検証プログラム。
【請求項２】
前記第２の命令の検索では、前記第１の命令から前記第２のソースコードの先頭に向かって、前記第２のソースコードに含まれる命令を走査する、
請求項１記載のプログラム検証プログラム。
【請求項３】
前記コンピュータに更に、
前記第２の命令において前記検出した変数への値の代入の際に参照される他の変数を検出し、前記第２の命令から前記第２のソースコードの先頭に向かって命令を走査して、前記検出した他の変数への値の代入を示す第３の命令を検索し、
前記第３の命令に基づいて、前記検出した変数に代入される値の取得方法を追跡する、
処理を実行させる請求項１記載のプログラム検証プログラム。
【請求項４】
前記非決定的動作の判定では、前記検出した変数に代入される値の取得方法が、乱数の取得、タイムスタンプの取得およびグローバル変数の参照の少なくとも１つを含む場合、前記データベースへの書き込みが前記非決定的動作であると判定する、
請求項１記載のプログラム検証プログラム。
【請求項５】
コンピュータが、
同一の変数への複数回の値の代入を許容する第１のソースコードを、各変数への値の代入を１回に制限する静的単一代入形式の第２のソースコードに変換し、
前記第２のソースコードから、データベースへの書き込みを示す第１の命令を検索し、前記第１の命令において書き込む値が格納されている変数を検出し、前記第２のソースコードから、前記検出した変数への値の代入を示す第２の命令を検索し、
前記第２の命令における前記検出した変数に代入される値の取得方法に基づいて、前記データベースへの書き込みが、前記第１のソースコードの引数および前記データベースのデータ以外の実行状況に依存する非決定的動作であるか否か判定する、
プログラム検証方法。
【請求項６】
同一の変数への複数回の値の代入を許容する第１のソースコードを記憶する記憶部と、
前記第１のソースコードを、各変数への値の代入を１回に制限する静的単一代入形式の第２のソースコードに変換し、前記第２のソースコードから、データベースへの書き込みを示す第１の命令を検索し、前記第１の命令において書き込む値が格納されている変数を検出し、前記第２のソースコードから、前記検出した変数への値の代入を示す第２の命令を検索し、前記第２の命令における前記検出した変数に代入される値の取得方法に基づいて、前記データベースへの書き込みが、前記第１のソースコードの引数および前記データベースのデータ以外の実行状況に依存する非決定的動作であるか否か判定する処理部と、
を有するプログラム検証装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はプログラム検証プログラム、プログラム検証方法およびプログラム検証装置に関する。
【背景技術】
【０００２】
同一内容のデータを記憶する複数のデータベースをネットワーク上に配置した分散データベースシステムがある。例えば、トランザクション（取引）の履歴を示すブロックチェーンと呼ばれるデータベースを構築し、複数のサーバ装置が同一内容のブロックチェーンを保持することでトランザクションの正当性を担保するブロックチェーンシステムがある。分散データベースシステムにおけるデータベースの更新は、複数のサーバ装置に同じプログラムを配置しておき、それら複数のサーバ装置のプログラムに同一の入力を与えることで、複数のデータベースを並列に更新することによって行うことがある。
【０００３】
なお、ソースコードのコンパイル時に、ソースコードから生成される中間コードに対して制御フローやデータフローの静的解析を行う静的解析方法が提案されている。提案の静的解析方法は、静的解析にあたって中間コードを静的単一代入（ＳＳＡ： Static Single Assignment）形式に変換する。また、ソースコードから検証式を生成し、モデル検証ツールを用いてプログラム動作を検証するプログラム検証装置が提案されている。提案のプログラム検証装置は、ソースコードをＳＳＡ形式に変換し、元のソースコードとＳＳＡ形式ソースコードに基づいて検証対象の処理部分を決定する。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開平９−２８２１７３号公報
【特許文献２】特開２０１２−２３８２３５号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
分散データベースシステムの複数のサーバ装置に配置されるプログラムは、同一のデータベースの内容および同一の入力に対して、データベースに書き込まれる値が同一になるという決定性をもっていることが要求される。プログラムに非決定的動作が含まれると、複数のデータベースの同一性が失われ、トランザクションの正当性の担保といった分散データベースシステムの目的を達成できなくなるおそれがある。
【０００６】
プログラムの非決定的動作は、データベースに書き込む値が、乱数の取得やタイムスタンプの取得などの所定の種類の操作に依存することによって発生する。そこで、複数のサーバ装置に配置されるプログラムを開発する際に、データベースへの書き込みが非決定的動作になるという不具合を発見するため、プログラムを検証することが考えられる。しかし、抽象構文木（ＡＳＴ：Abstract Syntax Tree）の探索やシンボリック実行など、従来のソースコードの静的解析方法では、データベースへの書き込みに関連する命令の追跡が非効率となり検証時間が増大するという問題がある。
【０００７】
１つの側面では、本発明は、非決定的動作の検証を高速化できるプログラム検証プログラム、プログラム検証方法およびプログラム検証装置を提供することを目的とする。
【課題を解決するための手段】
【０００８】
１つの態様では、コンピュータに以下の処理を実行させるプログラム検証プログラムが提供される。同一の変数への複数回の値の代入を許容する第１のソースコードを、各変数への値の代入を１回に制限する静的単一代入形式の第２のソースコードに変換する。第２のソースコードから、データベースへの書き込みを示す第１の命令を検索し、第１の命令において書き込む値が格納されている変数を検出し、第２のソースコードから、検出した変数への値の代入を示す第２の命令を検索する。第２の命令における検出した変数に代入される値の取得方法に基づいて、データベースへの書き込みが、第１のソースコードの引数およびデータベースのデータ以外の実行状況に依存する非決定的動作であるか否か判定する。また、１つの態様では、コンピュータが実行するプログラム検証方法が提供される。また、１つの態様では、記憶部と処理部とを有するプログラム検証装置が提供される。
【発明の効果】
【０００９】
１つの側面では、非決定的動作の検証を高速化できる。
【図面の簡単な説明】
【００１０】
【図１】第１の実施の形態のプログラム検証装置の例を説明する図である。
【図２】第２の実施の形態の情報処理システムの例を示す図である。
【図３】開発装置のハードウェア例を示すブロック図である。
【図４】ブロックチェーンのデータ構造例を示す図である。
【図５】スマートコントラクトの非決定的動作の例を示す図である。
【図６】スマートコントラクトの例を示す図である。
【図７】抽象構文木の第１の例を示す図である。
【図８】抽象構文木の第２の例を示す図である。
【図９】シンボリック実行の例を示す図である。
【図１０】ＳＳＡソースコードの例を示す図である。
【図１１】開発装置の機能例を示すブロック図である。
【図１２】開発装置が保持するテーブルの例を示す図である。
【図１３】プログラム検証の手順例を示すフローチャートである。
【図１４】スマートコントラクトとＳＳＡソースコードの他の例を示す図である。
【発明を実施するための形態】
【００１１】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
第１の実施の形態を説明する。
【００１２】
図１は、第１の実施の形態のプログラム検証装置の例を説明する図である。
第１の実施の形態のプログラム検証装置１０は、開発したプログラムを検証する。検証するプログラムは、同一内容のデータを記憶する複数のデータベースを並列に更新する分散データベースシステムに用いられるプログラムであってもよい。例えば、検証するプログラムは、ブロックチェーンを管理する複数のサーバ装置で並列に実行されるものである。プログラム検証装置１０は、情報処理装置やコンピュータと呼ばれることもある。プログラム検証装置１０は、クライアント装置でもよいしサーバ装置でもよい。
【００１３】
プログラム検証装置１０は、記憶部１１および処理部１２を有する。記憶部１１は、ＲＡＭ（Random Access Memory）などの揮発性の半導体メモリでもよいし、ＨＤＤ（Hard Disk Drive）やフラッシュメモリなどの不揮発性ストレージでもよい。処理部１２は、例えば、ＣＰＵ（Central Processing Unit）、ＧＰＵ（Graphics Processing Unit）、ＤＳＰ（Digital Signal Processor）などのプロセッサである。ただし、処理部１２は、ＡＳＩＣ（Application Specific Integrated Circuit）やＦＰＧＡ（Field Programmable Gate Array）などの特定用途の電子回路を含んでもよい。複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００１４】
記憶部１１は、検証対象のソースコード１３（第１のソースコード）を記憶する。ソースコード１３は、高水準言語であるプログラミング言語によって記述されている。ソースコード１３は、同一の変数への複数回の値の代入を許容している。また、記憶部１１は、後述するようにソースコード１３から変換されたソースコード１４（第２のソースコード）を記憶する。ソースコード１４は、ソースコード１３と同様に高水準言語であるプログラミング言語によって記述されている。ソースコード１４は、静的単一代入形式（ＳＳＡ形式）であり、各変数への値の代入を１回に制限している。
【００１５】
処理部１２は、ソースコード１３を検証するにあたり、まずソースコード１３をソースコード１４に変換する。ＳＳＡ形式への変換では、処理部１２は、ソースコード１３の中から同一の変数に対する２回目の値の代入を検出する。すると、処理部１２は、ソースコード１３で使用されていない新たな変数を定義し、値の代入先を新たな変数に変更し、それ以降の当該変数の参照を当該新たな変数の参照に置換する。これによって、各変数への値の代入を高々１回に制限することができる。
【００１６】
例えば、ソースコード１３は、引数の値を変数ｖａｌｕｅに代入する命令と、変数ｖａｌｕｅの値に乱数を加えた値を変数ｖａｌｕｅに代入する命令と、変数ｖａｌｕｅの値をデータベースに書き込む命令を含む。これに対してソースコード１４は、引数の値を変数ｖａｌｕｅ０に代入する命令と、変数ｖａｌｕｅ０の値に乱数を加えた値を変数ｖａｌｕｅ１に代入する命令と、変数ｖａｌｕｅ１の値をデータベースに書き込む命令を含む。
【００１７】
次に、処理部１２は、ソースコード１４から、データベースへの書き込みを示す命令１５（第１の命令）を検索する。処理部１２は、命令１５において書き込む値が格納されている変数を検出する。書き込む値が格納されている変数は、例えば、命令１５の右辺に記載されているオペランドである。処理部１２は、ソースコード１４から、検出した変数への値の代入を示す命令１６（第２の命令）を検索する。検出した変数は、例えば、命令１６の左辺に記載されている。処理部１２は、例えば、命令１５からソースコード１４の先頭に向かって、ソースコード１４の命令を走査することで命令１６を検索する。
【００１８】
例えば、処理部１２は、ソースコード１４から、ＰｕｔＳｔａｔｅ（”ｋｅｙ”，ｖａｌｕｅ１）を命令１５として検出する。この命令は、”ｋｅｙ”に対応するバリューとして変数ｖａｌｕｅ１の値をデータベースに書き込むものである。すると、処理部１２は、ソースコード１４を命令１５から遡って走査し、ｖａｌｕｅ１＝ｖａｌｕｅ０＋ｒａｎｄ．Ｉｎｔ３２（）を命令１６として検出する。この命令は、変数ｖａｌｕｅ０の値に乱数を加えた値をｖａｌｕｅ１に代入するものである。
【００１９】
処理部１２は、命令１６における検出した変数に代入される値の取得方法を特定し、特定した取得方法に基づいて、データベースへの書き込みが非決定的動作であるか判定する。変数に代入される値の取得方法は、例えば、命令１６の右辺から特定することができる。非決定的動作は、書き込まれる値が、ソースコード１３の引数およびデータベースに格納されているデータ以外の実行状況に依存して変化し得る動作である。
【００２０】
非決定的動作の原因には、例えば、書き込まれる値が乱数またはタイムスタンプ（現在時刻）に依存することが含まれる。また、非決定的動作の原因には、例えば、書き込まれる値が、複数のスレッドによって共有されるグローバル変数に依存することが含まれる。また、非決定的動作の原因には、例えば、書き込まれる値が、ソースコード１３に規定する処理を実行するサーバ装置の外部のＡＰＩ（Application Programming Interface）を呼び出すことで取得される値に依存することが含まれる。また、非決定的動作の原因には、例えば、書き込まれる値が、Ｍａｐオブジェクトなど、複数のデータ要素を保持しておりデータ要素間の順序が保証されないデータ構造に依存することが含まれる。
【００２１】
例えば、処理部１２は、ｖａｌｕｅ１＝ｖａｌｕｅ０＋ｒａｎｄ．Ｉｎｔ３２（）を命令１６として検出すると、変数ｖａｌｕｅ１に代入される値の取得方法の中に、乱数の使用が含まれていることを検出する。すると、処理部１２は、命令１６において変数ｖａｌｕｅ１に代入される値が非決定的であり、その結果として命令１５でデータベースに書き込まれる値が非決定的であると判定する。
【００２２】
処理部１２は、データベースへの書き込みが非決定的動作であるか否かの判定結果を出力する。例えば、処理部１２は、プログラム検証装置１０が有するディスプレイに判定結果を表示する。ただし、処理部１２は、プログラム検証装置１０が有するストレージ装置に判定結果を記録してもよく、ディスプレイ以外の出力デバイスに判定結果を出力してもよい。また、処理部１２は、他の情報処理装置に判定結果を送信してもよい。判定結果は、データベースへの書き込みを示す命令１５を識別する情報を含んでもよく、書き込まれる値の代入を示す命令１６を識別する情報を含んでもよい。命令１６の右辺に乱数が含まれている場合、例えば、処理部１２は、ソースコード１３が規定するデータベースへの書き込みが非決定的動作であることを示す警告をディスプレイに表示する。
【００２３】
第１の実施の形態のプログラム検証装置１０によれば、ソースコード１３がＳＳＡ形式のソースコード１４に変換される。そして、ソースコード１４を用いて、データベースに書き込む値を保持する変数に関連する命令が検索され、データベースへの書き込みが非決定的動作であるか否か判定される。これにより、ソースコード１３の開発時に、データベースに書き込まれる値が引数およびデータベースのデータ以外の実行状況に依存して変化するという不具合を検出することが可能となる。よって、ソースコード１３に規定する処理を複数のコンピュータで並列に実行した場合に、ソースコード１３の不具合によりデータベース間の整合性が失われることを抑制することができる。
【００２４】
また、ＳＳＡ形式のソースコード１４を利用することで、データベースに書き込む値に関連する命令を検索することが容易となり、非決定的動作の検証を高速化することができる。ソースコード１４では、データベースに書き込む値を保持する変数への代入は１回のみ行われ、かつ、同一関数内ではデータフローの順に命令が並んでいる。よって、例えば、データベースへの書き込みを示す命令１５から逆順に命令を走査することで、変数への値の代入を示す命令１６を高速に検索することができる。また、ソースコード１３に対応する抽象構文木を利用する方法と比べて、変数に関連する命令を追跡するために抽象構文木を繰り返し走査しなくてよく、検索が高速化される。また、シンボリック実行を利用する方法と比べて、複雑なパス抽出を行わなくてよく検索が高速化される。
【００２５】
［第２の実施の形態］
次に、第２の実施の形態を説明する。
図２は、第２の実施の形態の情報処理システムの例を示す図である。
【００２６】
第２の実施の形態の情報処理システムは、複数のサーバ装置を用いてブロックチェーンを管理する分散データベースシステムである。ブロックチェーンは、一連のトランザクションの履歴を示すデータベースであり、それらトランザクションに対応するブロックを連結したリストである。複数のサーバ装置が同一内容のブロックチェーンを保持して相互に確認することで、トランザクションの正当性を担保することができる。
【００２７】
第２の実施の形態の情報処理システムは、開発装置１００およびサーバ装置２００，２００−１，２００−２，２００−３，２００−４を含む。開発装置１００およびサーバ装置２００，２００−１，２００−２，２００−３，２００−４は、ネットワーク３０に接続されている。ネットワーク３０は、インターネットなどの広域ネットワークである。
【００２８】
開発装置１００は、サーバ装置２００，２００−１，２００−２，２００−３，２００−４で実行されるプログラムであるスマートコントラクトの開発に用いられる情報処理装置である。スマートコントラクトは、新たなトランザクションの発生に応じて、ブロックチェーンの末尾に新たなブロックを追加する。開発装置１００は、同一のスマートコントラクトをサーバ装置２００，２００−１，２００−２，２００−３，２００−４に配布する。開発装置１００は、クライアント装置でもよいしサーバ装置でもよい。
【００２９】
サーバ装置２００，２００−１，２００−２，２００−３，２００−４は、同一内容のブロックチェーンを保持する情報処理装置である。サーバ装置２００，２００−１，２００−２，２００−３，２００−４には同一のスマートコントラクトが配置されている。サーバ装置２００，２００−１，２００−２，２００−３，２００−４は、新たに発生したトランザクションを示す入力情報を受信し、受信した入力情報を用いてスマートコントラクトを実行することで並列にブロックチェーンを更新する。
【００３０】
サーバ装置２００は、ブロックチェーン２１０を保持し、スマートコントラクトを実行してブロックチェーン２１０を更新する。サーバ装置２００−１は、ブロックチェーン２１０−１を保持し、スマートコントラクトを実行してブロックチェーン２１０−１を更新する。サーバ装置２００−２は、ブロックチェーン２１０−２を保持し、スマートコントラクトを実行してブロックチェーン２１０−２を更新する。サーバ装置２００−３は、ブロックチェーン２１０−３を保持し、スマートコントラクトを実行してブロックチェーン２１０−３を更新する。サーバ装置２００−４は、ブロックチェーン２１０−４を保持し、スマートコントラクトを実行してブロックチェーン２１０−４を更新する。
【００３１】
図３は、開発装置のハードウェア例を示すブロック図である。
開発装置１００は、バスに接続されたＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像信号処理部１０４、入力信号処理部１０５、媒体リーダ１０６および通信インタフェース１０７を有する。開発装置１００は、第１の実施の形態のプログラム検証装置１０に対応する。ＣＰＵ１０１は、第１の実施の形態の処理部１２に対応する。ＲＡＭ１０２またはＨＤＤ１０３は、第１の実施の形態の記憶部１１に対応する。サーバ装置２００，２００−１，２００−２，２００−３，２００−４も同様のハードウェアを有する。
【００３２】
ＣＰＵ１０１は、プログラムの命令を実行するプロセッサである。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部をＲＡＭ１０２にロードし、プログラムを実行する。なお、ＣＰＵ１０１は複数のプロセッサコアを備えてもよく、開発装置１００は複数のプロセッサを備えてもよい。複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００３３】
ＲＡＭ１０２は、ＣＰＵ１０１が実行するプログラムやＣＰＵ１０１が演算に使用するデータを一時的に記憶する揮発性の半導体メモリである。なお、開発装置１００は、ＲＡＭ以外の種類のメモリを備えてもよく、複数のメモリを備えてもよい。
【００３４】
ＨＤＤ１０３は、ＯＳ（Operating System）やミドルウェアやアプリケーションソフトウェアなどのソフトウェアのプログラム、および、データを記憶する不揮発性ストレージである。なお、開発装置１００は、フラッシュメモリやＳＳＤ（Solid State Drive）など他の種類のストレージを備えてもよく、複数のストレージを備えてもよい。
【００３５】
画像信号処理部１０４は、ＣＰＵ１０１からの命令に従って、開発装置１００に接続されたディスプレイ１１１に画像を出力する。ディスプレイ１１１としては、ＣＲＴ（Cathode Ray Tube）ディスプレイ、液晶ディスプレイ（ＬＣＤ：Liquid Crystal Display）、有機ＥＬ（ＯＥＬ：Organic Electro-Luminescence）ディスプレイなど、任意の種類のディスプレイを使用することができる。
【００３６】
入力信号処理部１０５は、開発装置１００に接続された入力デバイス１１２から入力信号を受信する。入力デバイス１１２として、マウス、タッチパネル、タッチパッド、キーボードなど、任意の種類の入力デバイスを使用できる。また、開発装置１００に複数の種類の入力デバイスが接続されてもよい。
【００３７】
媒体リーダ１０６は、記録媒体１１３に記録されたプログラムやデータを読み取る読み取り装置である。記録媒体１１３として、例えば、フレキシブルディスク（ＦＤ：Flexible Disk）やＨＤＤなどの磁気ディスク、ＣＤ（Compact Disc）やＤＶＤ（Digital Versatile Disc）などの光ディスク、光磁気ディスク（ＭＯ：Magneto-Optical disk）、半導体メモリなどを使用できる。媒体リーダ１０６は、例えば、記録媒体１１３から読み取ったプログラムやデータをＲＡＭ１０２またはＨＤＤ１０３に格納する。
【００３８】
通信インタフェース１０７は、ネットワーク３０に接続され、ネットワーク３０を介してサーバ装置２００，２００−１〜２００−４などの情報処理装置と通信を行うインタフェースである。通信インタフェース１０７は、スイッチやルータなどの有線通信装置に接続される有線通信インタフェースである。ただし、基地局やアクセスポイントなどの無線通信装置に接続される無線通信インタフェースを利用してもよい。
【００３９】
図４は、ブロックチェーンのデータ構造例を示す図である。
サーバ装置２００，２００−１，２００−２，２００−３，２００−４は、図４に示すようなデータ構造のブロックチェーンを保持する。ブロックチェーンは、ブロック４０，４０−１，４０−２などの複数のブロックを含む。１つのブロックは１つのトランザクション（取引）を示す。ブロック４０−１はブロック４０の前段のブロックである。ブロック４０−２はブロック４０の後段のブロックである。各ブロックは、例えば、データをキーとバリューの組であるキーバリュー形式で保持することができる。ブロック４０は、ハッシュ値４１、取引データ４２、公開鍵４３および署名４４を含む。ブロック４０−１，４０−２などの他のブロックも、ブロック４０と同様のデータ構造をもつ。
【００４０】
ハッシュ値４１は、前段のブロック４０−１の全体を所定のハッシュ関数に入力することで算出されるハッシュ値である。ハッシュ値４１により、ブロック４０とその前段のブロック４０−１とが関連付けられる。また、ブロック４０−２に含まれるハッシュ値により、ブロック４０−２とその前段のブロック４０とが関連付けられる。取引データ４２は、取引金額などトランザクションの内容を示す。
【００４１】
公開鍵４３は、取引相手の公開鍵である。ブロック４０が示すトランザクションの取引相手は、後段のブロック４０−２が示すトランザクションの取引主体になることが期待される。よって、公開鍵４３を用いて、後段のブロック４０−２に含まれる署名を検証することができる。署名４４は、取引主体（取引元）の秘密鍵を用いて生成されたデジタル署名である。ブロック４０が示すトランザクションの取引主体は、前段のブロック４０−１が示すトランザクションの取引相手であることが期待される。よって、前段のブロック４０−１の公開鍵を用いて、ブロック４０の署名４４を検証することができる。
【００４２】
次に、スマートコントラクトの開発における問題点について説明する。
図５は、スマートコントラクトの非決定的動作の例を示す図である。
サーバ装置２００，２００−１，２００−２，２００−３，２００−４は、同一の入力情報を受信して同一のスマートコントラクトを実行し、並列にブロックチェーン２１０，２１０−１，２１０−２，２１０−３，２１０−４を更新する。更新後のブロックチェーン２１０，２１０−１，２１０−２，２１０−３，２１０−４の内容は同一であることが求められる。よって、スマートコントラクトは、ブロックチェーンに書き込む値が、入力情報および更新前のブロックチェーンの内容から一意に決定されるようにし、それ以外の外部状態に依存して決定されることがないようにすることが求められる。
【００４３】
ブロックチェーンに書き込む値が、入力情報および更新前のブロックチェーンの内容のみに依存する場合、書き込みが決定的であると言うことができる。一方、ブロックチェーンに書き込む値が、入力情報および更新前のブロックチェーンの内容以外の外部状態に依存する場合、書き込みが非決定的であると言うことができる。外部状態への依存として、乱数の使用、タイムスタンプの使用、外部ＡＰＩの呼び出し、グローバル変数の参照およびＭａｐオブジェクトの反復参照が挙げられる。
【００４４】
乱数を使用すると、ブロックチェーンに書き込む値がランダムに変化してしまう。タイムスタンプを使用すると、スマートコントラクトを実行する時刻の違いによってブロックチェーンに書き込む値が変化してしまう。外部ＡＰＩを呼び出すと、外部ＡＰＩを呼び出すことでサーバ装置の外部から受信される情報が不変であることが保証されず、ブロックチェーンに書き込む値がサーバ装置によって変化してしまう。
【００４５】
グローバル変数を参照すると、あるスレッドが参照するグローバル変数の値が他のスレッドによって書き換えられることがあり、同一サーバ装置上の複数のスレッドの実行タイミングによってブロックチェーンに書き込む値が変化してしまう。Ｍａｐオブジェクトは、複数のデータ要素（エントリやレコードと言うこともある）を格納可能なデータ構造であって、それら複数のデータ要素の格納順序が保証されないデータ構造である。そのため、ｆｏｒ文などの反復構造を用いてＭａｐオブジェクトに格納された複数のデータ要素を順に参照すると、それら複数のデータ要素の参照順序がサーバ装置によって変わり、ブロックチェーンに書き込む値が変化してしまう。
【００４６】
例えば、タイムスタンプ（現在時刻）をブロックチェーンに書き込むスマートコントラクト５１がサーバ装置２００，２００−１，２００−２，２００−３，２００−４に配置されたとする。すると、ブロックチェーン２１０，２１０−１，２１０−２，２１０−３，２１０−４に書き込まれる値が同一になるとは限らない。例えば、ブロックチェーン２１０には時刻「１０：２０：０６  ４３０Ｚ」が書き込まれる。ブロックチェーン２１０−１には時刻「１０：２０：０６  ４５０Ｚ」が書き込まれる。ブロックチェーン２１０−２には時刻「１０：２０：０６  ４５０Ｚ」が書き込まれる。ブロックチェーン２１０−３には時刻「１０：２０：０６  ４００Ｚ」が書き込まれる。ブロックチェーン２１０−４には時刻「１０：２０：０６  ４１９Ｚ」が書き込まれる。
【００４７】
ブロックチェーンへの書き込みが非決定的動作になるスマートコントラクトをサーバ装置２００，２００−１，２００−２，２００−３，２００−４に配置すると、情報処理システムに不具合が発生する。そこで、開発装置１００は、開発したスマートコントラクトに非決定的動作が含まれていないか検証する。
【００４８】
図６は、スマートコントラクトの例を示す図である。
開発装置１００は、開発したスマートコントラクトを記憶する。スマートコントラクト５２，５３は、検証対象のスマートコントラクトの例である。
【００４９】
スマートコントラクト５２は、関数Ｉｎｉｔを含む。関数Ｉｎｉｔは、呼び出されるときに４つの引数ａｒｇｓ［０］〜ａｒｇｓ［３］を受け付ける。関数Ｉｎｉｔは、引数ａｒｇｓ［０］の文字列を変数Ａに代入し、整数の乱数を変数Ａｖａｌに代入し、引数ａｒｇｓ［２］の文字列を変数Ｂに代入し、引数ａｒｇｓ［３］の文字列が表す整数を変数Ｂｖａｌに代入する。乱数は関数ｒａｎｄ．Ｉｎｔ３２を呼び出すことで取得される。
【００５０】
引数ａｒｇｓ［３］の文字列を整数に変換できない場合、関数Ｉｎｉｔはエラーメッセージを出力する。関数Ｉｎｉｔは、変数Ａの文字列をキーとし、変数Ａｖａｌの整数を表す文字列をバリューとしてブロックチェーンに書き込む。ブロックチェーンへの書き込みは、関数ＰｕｔＳｔａｔｅを呼び出すことで行う。このときエラーが発生すると、関数Ｉｎｉｔはエラーメッセージを出力する。また、関数Ｉｎｉｔは、変数Ｂの文字列をキーとし、変数Ｂｖａｌの整数を表す文字列をバリューとしてブロックチェーンに書き込む。このときエラーが発生すると、関数Ｉｎｉｔはエラーメッセージを出力する。
【００５１】
スマートコントラクト５３は、文字列型の変数Ａ、整数型の変数Ａｖａｌおよび整数型の変数Ｘを定義する。スマートコントラクト５３は、文字列「ｋｅｙ」を変数Ａに代入し、整数「１」を変数Ａｖａｌに代入し、整数の乱数を変数Ｘに代入する。スマートコントラクト５３は、変数Ａｖａｌの値に変数Ｘの値を加算し、加算結果を変数Ａｖａｌに代入する。そして、スマートコントラクト５３は、変数Ａの文字列をキーとし、変数Ａｖａｌの整数を表す文字列をバリューとしてブロックチェーンに書き込む。
【００５２】
スマートコントラクトの非決定的動作を検証する方法としては、抽象構文木を利用する方法やシンボリック実行を利用する方法も考えられる。以下では、抽象構文木を利用する方法とシンボリック実行を利用する方法について説明する。
【００５３】
図７は、抽象構文木の第１の例を示す図である。
抽象構文木６１は、スマートコントラクト５２から生成される抽象構文木である。抽象構文木６１は、ソースコードであるスマートコントラクト５２の構文を表す木構造データである。抽象構文木６１は、変数の宣言（変数宣言）を示すノードや、変数への値の代入（代入演算）を示すノードを含む。また、抽象構文木６１は、代入演算を示すノードの子ノードとして、代入先の変数（左辺の変数）を示すノード、演算子を示すノード、代入値を格納している変数（右辺の変数）を示すノード、代入値を算出する関数の呼び出し（関数呼び出し）を示すノードなどを含む。また、抽象構文木６１は、関数呼び出しを示すノードの子ノードとして、関数の引数としての変数を示すノードを含む。
【００５４】
ブロックチェーンへの書き込みが非決定的であるか否かを抽象構文木６１を用いて検証する場合、次のような検証方法が考えられる。まず、抽象構文木６１をルートノードから順に幅優先探索または深さ優先探索により走査し、ブロックチェーンへの書き込みを示す関数呼び出しのノードを検索する。関数呼び出しのノードが検出されると、その子ノードに基づいてブロックチェーンに書き込む値が格納されている変数を特定する。
【００５５】
すると、抽象構文木６１をルートノードから順に再び走査して、当該変数に値を代入する代入演算を示すノードを検索する。検出された代入演算の右辺に変数が存在する場合、抽象構文木６１をルートノードから順に再び走査して、当該変数に値を代入する代入演算を示すノードを検索する。これを繰り返すことで、ブロックチェーンに書き込む値を算出する過程が追跡される。書き込む値を算出する過程で、乱数を取得する関数の呼び出しやタイムスタンプを取得する関数の呼び出しなど、非決定性の原因となる操作が行われた場合、書き込みが非決定的動作であると判定される。
【００５６】
例えば、図７の例では、まず関数ＰｕｔＳｔａｔｅの呼び出しを示すノードが検出され、関数ＰｕｔＳｔａｔｅの引数を示すノードとして変数Ａを示すノードと変数Ａｖａｌを示すノードが検出される。すると、抽象構文木６１がルートノードから順に再び走査され、変数Ａに引数ａｒｇｓ［０］の値を代入する代入演算を示すノードと、変数Ａｖａｌに関数ｒａｎｄ．Ｉｎｔ３２の戻り値を代入する代入演算を示すノードとが検出される。関数ｒａｎｄ．Ｉｎｔ３２は乱数を取得する関数であるため、書き込む値が乱数に依存することになり、ブロックチェーンへの書き込みが非決定的であると判定される。
【００５７】
しかし、抽象構文木６１は複数の演算の間の順序関係を表現していない。また、同一の変数に対する値の代入が複数回行われることがあり、同一の変数についての代入演算を示すノードが抽象構文木６１に複数存在することがある。このため、ブロックチェーンに書き込む値を格納する変数に関連するノードが抽象構文木６１の様々な箇所に分散している可能性があり、抽象構文木６１の走査を何度も繰り返すことになる。
【００５８】
このため、スマートコントラクト５２のサイズの増大に応じて抽象構文木６１のノード数が増大し、プログラム検証の実行時間が増大する。例えば、約１６０行のソースコードから約６００個のノードを含む抽象構文木が生成されることがある。また、約１７００行のソースコードから約７５００個のノードを含む抽象構文木が生成されることがある。その結果、プログラム検証が非効率になるおそれがある。
【００５９】
図８は、抽象構文木の第２の例を示す図である。
抽象構文木６２は、スマートコントラクト５３から生成される抽象構文木である。ブロックチェーンへの書き込みが非決定的であるか否かを抽象構文木６２を用いて検証する場合、上記の抽象構文木６１と同様の検証方法が行われる。
【００６０】
例えば、図８の例では、まず関数ＰｕｔＳｔａｔｅの呼び出しを示すノードが検出され、関数ＰｕｔＳｔａｔｅの引数を示すノードとして変数Ａを示すノードと変数Ａｖａｌを示すノードが検出される。すると、抽象構文木６２がルートノードから順に再び走査され、変数Ａに文字列「ｋｅｙ」を代入する代入演算を示すノードが検出される。また、変数Ａｖａｌの値に変数Ｘの値を加算して変数Ａｖａｌに代入する代入演算を示すノードが検出される。これらの代入演算そのものには、非決定性の原因は存在しない。
【００６１】
一方、変数Ａｖａｌの代入演算には変数Ａｖａｌの前の値と変数Ｘの値とが使用されている。そこで、抽象構文木６２がルートノードから順に再び走査され、変数Ａｖａｌに整数「１」を代入する代入演算を示すノードと、変数Ｘに関数ｒａｎｄ．Ｉｎｔ３２の戻り値を代入する代入演算を示すノードとが検出される。関数ｒａｎｄ．Ｉｎｔ３２は乱数を取得する関数であるため、書き込む値が乱数に依存することになり、ブロックチェーンへの書き込みが非決定的であると判定される。このように、抽象構文木６２の走査を何度も繰り返すことになり、非決定的動作の検証が非効率になる。
【００６２】
図９は、シンボリック実行の例を示す図である。
シンボリック実行は、ソースコードを解析して異なる複数の実行パスを検出する静的解析方法である。シンボリック実行では、変数に具体的な値ではなく抽象的なシンボルを代入し、ソースコードを仮想的に実行して演算結果をシンボルを用いた式で表現する。シンボルを用いた式で表された変数の値の変化を追跡することで、実行パスを検出する。
【００６３】
シンボリック実行フロー６３は、スマートコントラクト５２のシンボリック実行の処理ステップを表す。処理ｐ１は、変数Ａにシンボルａ０を代入し、変数Ａｖａｌにシンボルａｖａｌ０を代入し、変数Ｂにシンボルｂ０を代入し、変数Ｂｖａｌにシンボルｂｖａｌ０を代入し、変数ｅｒｒにシンボルｅ０を代入する。処理ｐ２は、変数ｅｒｒの値がｎｉｌ（空文字）でないか、すなわち、シンボルｅ０がｎｉｌでないか判断する。シンボルｅ０とｎｉｌの比較に応じて、実行パスが処理ｐ３と処理ｐ４に分岐する。シンボルｅ０がｎｉｌである場合（条件「ｅ０  ！＝  ｎｉｌ」が偽の場合）、処理ｐ３が実行される。処理ｐ３は、シンボルａ０をキーとし、シンボルａｖａｌ０を表す文字列をバリューとしてブロックチェーンに書き込む。シンボルｅ０がｎｉｌでない場合（条件「ｅ０  ！＝  ｎｉｌ」が真の場合）、処理ｐ４が実行される。処理ｐ４は、エラーを出力する。
【００６４】
パステーブル６４は、シンボリック実行によって検出された実行パスを示すテーブルである。パステーブル６４は、パスＩＤ、パス条件およびパスの項目を含む。パスＩＤは、検出された実行パスを識別する識別子である。パス条件は、その実行パスが選択されるためにシンボルが満たすべき条件、すなわち、変数に代入されるべき値の条件である。パスは、その実行パスが通過する一連の処理ステップである。
【００６５】
シンボリック実行フロー６３からは２つの実行パスが検出される。１つの実行パスは、シンボルｅ０がｎｉｌである場合に選択される実行パスであり、処理ｐ１，ｐ２，ｐ３を通過する。もう１つの実行パスは、シンボルｅ０がｎｉｌでない場合に選択される実行パスであり、処理ｐ１，ｐ２，ｐ４を通過する。
【００６６】
ブロックチェーンへの書き込みが非決定的であるか否かをシンボリック実行を用いて検証する場合、まずシンボリック実行によって実行パス毎のパス条件を判定し、各実行パスのパス条件に当てはまる複数の入力値をテストデータとして用意する。そして、スマートコントラクト５２に複数の入力値を与えて実行結果を観察し、意図しない実行結果の変化が生じていないか判断する。意図しない実行結果の変化が存在する場合、スマートコントラクト５２に非決定的動作が含まれると推定される。例えば、ある実行パスが選択されることを期待して与えた入力値から、別の実行パスが選択されて意図しない出力が得られた場合、シンボリック実行によって解析されなかった非決定性が存在すると判定される。
【００６７】
しかし、スマートコントラクト５２のサイズの増大に応じてシンボリック実行フロー６３の条件分岐が多くなり、検出される実行パスが増大してプログラム検証の実行時間が増大する。また、シンボリック実行では、実行パス毎のパス条件を算出するために、ＳＭＴ（Satisfiability Modulo Theories）ソルバなどの数式処理を行う制約ソルバが用いられる。しかしながら、スマートコントラクト５２の中にパス条件を判断するための情報が不足している場合など、制約ソルバによって実行パス毎のパス条件を算出できないことがある。その場合、テストデータを効率的に生成することができない。
【００６８】
そこで、第２の実施の形態の開発装置１００は、スマートコントラクト５２，５３を静的単一代入（ＳＳＡ）形式に変換し、ＳＳＡソースコードの静的解析によってスマートコントラクト５２，５３の非決定的動作を検証する。
【００６９】
図１０は、ＳＳＡソースコードの例を示す図である。
開発装置１００は、スマートコントラクト５２をＳＳＡソースコード７１に変換して記憶し、スマートコントラクト５３をＳＳＡソースコード７２に変換して記憶する。ＳＳＡソースコード７１，７２は、スマートコントラクト５２，５３と意味的に等価である。ただし、ＳＳＡソースコード７１，７２は、スマートコントラクト５２，５３と異なり、１つの変数に対する代入演算は１回だけ行うという制約をもつ。スマートコントラクト５２，５３からＳＳＡソースコード７１，７２への変換は次のように行うことができる。
【００７０】
開発装置１００は、あるスマートコントラクトを先頭から末尾に向かって走査し、同じ変数に対する２回目の代入演算を検出する。２回目の代入演算が検出されると、開発装置１００は、当該スマートコントラクトで使用されていない新たな変数を定義し、２回目の代入演算の代入先を新たな変数に書き換える。そして、開発装置１００は、それ以降の処理における当該変数の参照を当該新たな変数の参照に書き換える。３回目以降の代入演算についても、その都度新たな変数を定義してそれ以降の変数の参照を書き換える。これにより、プログラムの意味を変えずに１つの変数への値の代入を１回に制限できる。
【００７１】
ＳＳＡソースコード７１は、スマートコントラクト５２と同様に関数Ｉｎｉｔを含む。ＳＳＡソースコード７１は、引数である４つの文字列を含む文字列型配列を変数ｔ１に代入し、変数ｔ１の１番目の文字列を変数ｔ２に代入し、整数の乱数を変数ｔ３に代入する。その後、ＳＳＡソースコード７１は、変数ｔ２，ｔ３を引数として関数ＰｕｔＳｔａｔｅを呼び出し、関数ＰｕｔＳｔａｔｅの戻り値を変数ｔ４５に代入する。
【００７２】
ＳＳＡソースコード７２は、変数ｔ０として文字列型の変数Ａを定義し、変数ｔ１として整数型の変数Ａｖａｌを定義し、変数ｔ２として整数型の変数Ｘを定義する。ＳＳＡソースコード７２は、変数ｔ０に対応して新たに定義した変数ｔ３に文字列「ｋｅｙ」を代入する。また、ＳＳＡソースコード７２は、変数ｔ１に対応して新たに定義した変数ｔ４に整数「１」を代入する。また、ＳＳＡソースコード７２は、変数ｔ２に対応して新たに定義した変数ｔ５に整数の乱数を代入する。ＳＳＡソースコード７２は、変数ｔ４の値と変数ｔ５の値の和を算出して新たな変数ｔ６に代入する。そして、ＳＳＡソースコード７２は、変数ｔ３，ｔ６を引数として関数ＰｕｔＳｔａｔｅを呼び出し、関数ＰｕｔＳｔａｔｅの戻り値を新たな変数ｔ７に代入する。
【００７３】
このようなＳＳＡソースコード７１，７２を利用することで、開発装置１００は効率的にスマートコントラクト５２，５３の非決定的動作を検証することができる。開発装置１００は、あるＳＳＡソースコードを先頭から末尾に向かって走査し、ブロックチェーンへの書き込みを示す書き込み操作を検索する。書き込み操作を検出すると、開発装置１００は、書き込み操作の引数に用いられている変数を特定し、当該ＳＳＡソースコードを逆方向に走査して、特定した変数への値の代入を示す代入操作を検索する。
【００７４】
代入操作を検出すると、開発装置１００は、乱数を取得する関数の呼び出しなど非決定性の原因となる非決定的操作が、代入操作の右辺に存在するか確認する。代入操作の右辺に非決定的操作が存在しないものの他の変数が存在する場合、開発装置１００は、当該ＳＳＡソースコードを更に逆方向に走査して当該他の変数への値の代入を示す代入操作を検索する。変数の代入操作を再帰的に検索することで、ブロックチェーンに書き込む値を格納する変数に影響を与える非決定的操作を探索することができる。
【００７５】
例えば、ＳＳＡソースコード７１について、開発装置１００は、関数ＰｕｔＳｔａｔｅの呼び出しを検出し、引数である変数ｔ２，ｔ３を特定する。開発装置１００は、関数ＰｕｔＳｔａｔｅの呼び出し位置からＳＳＡソースコード７１を先頭に向かって走査し、変数ｔ３の代入操作を検出する。変数ｔ３の代入操作の右辺では関数ｒａｎｄ．Ｉｎｔ３２が呼び出されているため、開発装置１００は、ブロックチェーンに書き込まれる変数ｔ３の値が乱数に依存しており非決定的であると判定する。
【００７６】
また、ＳＳＡソースコード７２について、開発装置１００は、関数ＰｕｔＳｔａｔｅの呼び出しを検出し、引数である変数ｔ３，ｔ６を特定する。開発装置１００は、関数ＰｕｔＳｔａｔｅの呼び出し位置からＳＳＡソースコード７２を先頭に向かって走査し、変数ｔ６の代入操作を検出する。変数ｔ６の代入操作の右辺は、非決定的操作を含まないものの変数ｔ４，ｔ５を含むため、開発装置１００は変数ｔ４，ｔ５を検索対象に追加する。開発装置１００は、ＳＳＡソースコード７２を更に先頭に向かって走査し、変数ｔ５の代入操作を検出する。変数ｔ５の代入操作の右辺では関数ｒａｎｄ．Ｉｎｔ３２が呼び出されているため、開発装置１００は、ブロックチェーンに書き込まれる変数ｔ６の値が乱数に依存しており非決定的であると判定する。
【００７７】
このように、ＳＳＡソースコード７１，７２は、同一関数内ではデータフローの順に各種操作を記述している。また、ＳＳＡソースコード７１，７２は、１つの変数に対する代入操作を１回に限定し、それ以降は当該変数について参照のみ許容する。このため、開発装置１００は、ブロックチェーンの書き込み操作の位置から逆順に１回だけＳＳＡソースコード７１，７２を走査することで、非決定性を判定することができる。
【００７８】
次に、開発装置１００の機能および処理手順について説明する。
図１１は、開発装置の機能例を示すブロック図である。
開発装置１００は、ソースコード記憶部１２１、ＳＳＡソースコード記憶部１２２、制御情報記憶部１２３、ＳＳＡ変換部１２４、非決定性検出部１２５および結果表示部１２６を有する。ソースコード記憶部１２１、ＳＳＡソースコード記憶部１２２および制御情報記憶部１２３は、ＲＡＭ１０２またはＨＤＤ１０３の記憶領域を用いて実装することができる。ＳＳＡ変換部１２４、非決定性検出部１２５および結果表示部１２６は、ＣＰＵ１０１が実行するプログラムを用いて実装することができる。
【００７９】
ソースコード記憶部１２１は、スマートコントラクト５２，５３など、検証対象のスマートコントラクトを記憶する。ＳＳＡソースコード記憶部１２２は、ＳＳＡソースコード７１，７２など、検証対象のスマートコントラクトから変換されたＳＳＡ形式のソースコードを記憶する。制御情報記憶部１２３は、スマートコントラクトの非決定的動作を検証する際に参照される制御情報を記憶する。制御情報は、ブロックチェーンの書き込み操作を示すプログラム記述や、非決定性の原因となる非決定的操作を示すプログラム記述を含む。これらのプログラム記述は、プログラミング言語毎に予め定義される。
【００８０】
ＳＳＡ変換部１２４は、ソースコード記憶部１２１から検証対象のスマートコントラクトを読み出し、スマートコントラクトをＳＳＡソースコードに変換し、ＳＳＡソースコードをＳＳＡソースコード記憶部１２２に格納する。非決定性検出部１２５は、ＳＳＡソースコード記憶部１２２からＳＳＡソースコードを読み出し、制御情報記憶部１２３に記憶された制御情報を参照して、ブロックチェーンに書き込まれる値に影響する非決定的操作をＳＳＡソースコードから検索する。結果表示部１２６は、非決定的動作の検出結果をディスプレイ１１１に表示する。検出結果には、ブロックチェーンへの書き込みが非決定的であるか否かを示すメッセージが含まれる。ブロックチェーンへの書き込みが非決定的である場合、検出結果には、問題となる非決定的操作の識別情報が含まれてもよい。
【００８１】
図１２は、開発装置が保持するテーブルの例を示す図である。
書き込み操作テーブル１３１は、予め作成されて制御情報記憶部１２３に記憶されている。書き込み操作テーブル１３１は、プログラミング言語および操作の項目を含む。プログラミング言語は、ソースコードであるスマートコントラクトの記述に用いられている高水準言語である。書き込み操作テーブル１３１の操作は、特定のプログラミング言語においてブロックチェーンへの書き込みに用いられるプログラム記述である。例えば、書き込み操作に用いる関数の名称とその関数の引数の個数が定義される。
【００８２】
例えば、あるプログラミング言語（ｌａｎｇｕａｇｅＸ）では、書き込み操作としてＰｕｔＳｔａｔｅ（ｋｅｙ，ｖａｌｕｅ）というプログラム記述が用いられる。また、別のプログラミング言語（ｌａｎｇｕａｇｅＹ）では、書き込み操作としてｐｕｔＳｔａｔｅ（ｋｅｙ，ｖａｌｕｅ）というプログラム記述が用いられる。
【００８３】
非決定的操作テーブル１３２は、予め作成されて制御情報記憶部１２３に記憶されている。非決定的操作テーブル１３２は、プログラミング言語、カテゴリおよび操作の項目を含む。プログラミング言語は、ソースコードであるスマートコントラクトの記述に用いられている高水準言語である。カテゴリは、非決定性の原因となる非決定的操作の種類である。カテゴリには、前述のように、乱数、タイムスタンプ、外部ＡＰＩ、グローバル変数およびＭａｐオブジェクトが含まれる。非決定的操作テーブル１３２の操作は、特定のプログラミング言語において非決定的操作に用いられるプログラム記述である。例えば、非決定的操作に用いる関数の名称とその関数の引数の個数が定義される。
【００８４】
例えば、あるプログラミング言語では、乱数を取得する非決定的操作として、ｒａｎｄ．Ｉｎｔ３２（）というプログラム記述やｒａｎｄ．Ｆｌｏａｔ３２（）というプログラム記述が用いられる。また、あるプログラミング言語では、タイムスタンプを取得する非決定的操作として、ｔｉｍｅ．Ｎｏｗ（）というプログラム記述が用いられる。
【００８５】
検出結果テーブル１３３は、１つのスマートコントラクトの検証に対して非決定性検出部１２５によって生成される。検出結果テーブル１３３の情報は、ＲＡＭ１０２やＨＤＤ１０３に保存されてもよく、ディスプレイ１１１に表示されてもよい。検出結果テーブル１３３は、位置、非決定的操作およびカテゴリの項目を含む。
【００８６】
位置は、ブロックチェーンに書き込む値に影響を与える非決定的操作が記述されているスマートコントラクト上の位置であり、例えば、スマートコントラクトの行番号で特定される。検出結果テーブル１３３の非決定的操作として、非決定的操作のプログラム記述が登録される。カテゴリは、非決定的操作テーブル１３２に定義されたカテゴリである。
【００８７】
図１３は、プログラム検証の手順例を示すフローチャートである。
（Ｓ１０）ＳＳＡ変換部１２４は、ソースコードであるスマートコントラクトを、ＳＳＡ形式のソースコード（ＳＳＡソースコード）に変換する。ＳＳＡソースコードへの変換では、ＳＳＡ変換部１２４は、同一の変数に対する２回目以降の代入操作を検出し、代入先の変数を新たな変数に置換し、それ以降の変数の参照を新たな変数の参照に置換する。
【００８８】
（Ｓ１１）非決定性検出部１２５は、ＳＳＡソースコードの初回の読み出しではＳＳＡソースコードの先頭行を読む。また、非決定性検出部１２５は、ＳＳＡソースコードの２回目以降の読み出しでは、前回読んだ行の次の行をＳＳＡソースコードから読む。
【００８９】
（Ｓ１２）非決定性検出部１２５は、ステップＳ１１で読んだ行が、書き込み操作テーブル１３１に定義された何れかの書き込み操作を含むか判断する。書き込み操作を含む場合はステップＳ１４に進み、書き込み操作を含まない場合はステップＳ１３に進む。
【００９０】
（Ｓ１３）非決定性検出部１２５は、ステップＳ１１でＳＳＡソースコードの最終行まで読んだか判断する。ＳＳＡソースコードの最終行まで読んだ場合、検証対象のスマートコントラクトはブロックチェーンの書き込み操作を含まないとして、プログラム検証が終了する。ＳＳＡソースコードの最終行に到達していない場合、ステップＳ１１に進む。
【００９１】
（Ｓ１４）非決定性検出部１２５は、ステップＳ１１で読んだ行から、ブロックチェーンに書き込む値を格納している変数を抽出する。非決定性検出部１２５は、抽出した変数を、以降の検索対象の変数として登録する。
【００９２】
（Ｓ１５）非決定性検出部１２５は、ＳＳＡソースコードから１つ前の行を読む。
（Ｓ１６）非決定性検出部１２５は、ステップＳ１５で読んだ行が、検索対象として登録された何れかの変数に値を代入する代入文であるか判断する。登録された変数の代入文である場合はステップＳ１７に進み、それ以外の場合はステップＳ２０に進む。
【００９３】
（Ｓ１７）非決定性検出部１２５は、ステップＳ１５で読んだ行が、非決定的操作テーブル１３２に定義された何れかの非決定的操作を含むか判断する。非決定的操作を含む場合はステップＳ２１に進み、非決定的操作を含まない場合はステップＳ１８に進む。
【００９４】
（Ｓ１８）非決定性検出部１２５は、ステップＳ１５で読んだ行が代入値を示す変数を含むか、すなわち、代入文の右辺が他の変数を含むか判断する。代入値を示す変数を含む場合はステップＳ１９に進み、含まない場合はステップＳ２０に進む。
【００９５】
（Ｓ１９）非決定性検出部１２５は、ステップＳ１５で読んだ行から代入値を示す変数を抽出する。非決定性検出部１２５は、抽出した変数を検索対象の変数に追加登録する。
（Ｓ２０）非決定性検出部１２５は、ステップＳ１５でＳＳＡソースコードの先頭行まで読んだか判断する。ＳＳＡソースコードの先頭行まで読んだ場合、非決定性検出部１２５は、ブロックチェーンの書き込み操作が非決定的動作ではないと判定する。そして、プログラム検証が終了する。このとき、結果表示部１２６は、非決定的動作が検出されなかった旨のメッセージをディスプレイ１１１に表示してもよい。一方、ＳＳＡソースコードの先頭行に到達していない場合、ステップＳ１５に進む。
【００９６】
（Ｓ２１）非決定性検出部１２５は、ブロックチェーンの書き込み操作が非決定的動作であると判定する。非決定性検出部１２５は、ステップＳ１５で読んだ行について位置と非決定的操作とカテゴリを判定して検出結果テーブル１３３を生成する。そして、プログラム検証が終了する。このとき、結果表示部１２６は、非決定的動作が検出された旨のメッセージをディスプレイ１１１に表示してもよく、非決定的動作の原因として検出結果テーブル１３３の情報をディスプレイ１１１に表示してもよい。
【００９７】
上記では、非決定的動作として、乱数やタイムスタンプなど非決定的操作によって取得した値からブロックチェーンに書き込む値を算出する例について説明した。これに対し、非決定的操作によって取得した値を条件分岐などのフロー制御に用いることで、ブロックチェーンへの書き込み方法が切り替わって非決定的動作となることがある。開発装置１００は、このようなフロー制御に起因する非決定的動作についても検出することができる。
【００９８】
例えば、非決定性検出部１２５は、図１３のフローチャートにおいて、ＳＳＡソースコードから１つ前の行を読み、読んだ行が登録された変数の代入文でない場合、読んだ行が何らかの変数の値に依存する条件分岐文であるか判断するようにする。何らかの変数の値に依存する条件分岐文である場合、非決定性検出部１２５は、条件分岐文に含まれる変数を検索対象として追加登録する。これにより、ある書き込み操作が実行されるか否かが乱数やタイムスタンプに依存するような非決定的動作を検出することができる。
【００９９】
図１４は、スマートコントラクトとＳＳＡソースコードの他の例を示す図である。
スマートコントラクト５４は、関数ｍａｉｎを含む。関数ｍａｉｎは、浮動小数点実数の乱数を変数Ａに代入する。関数ｍａｉｎは、変数Ａの値と実数「０．５」とを比較する。変数Ａの値が０．５より大きい場合、関数ｍａｉｎは、文字列「Ｓｕｃｃｅｓｓ」と真偽値「Ｔｒｕｅ」を引数として関数ＰｕｔＳｔａｔｅを呼び出す。一方、変数Ａの値が０．５以下である場合、関数ｍａｉｎは、文字列「Ｓｕｃｃｅｓｓ」と真偽値「Ｆａｌｓｅ」を引数として関数ＰｕｔＳｔａｔｅを呼び出す。ブロックチェーンに書き込まれる真偽値が「Ｔｒｕｅ」になるか「Ｆａｌｓｅ」になるかは乱数に依存する。
【０１００】
開発装置１００は、スマートコントラクト５４をＳＳＡソースコード７３に変換する。ＳＳＡソースコード７３は、浮動小数点実数の乱数を変数ｔ０に代入し、変数ｔ０の値が０．５より大きいか否かを示す真偽値を変数ｔ１に代入する。ＳＳＡソースコード７３は、変数ｔ１が真を示しているときは第１番地にジャンプし、変数ｔ１が偽を示しているときは第３番地にジャンプする。第１番地では、ＳＳＡソースコード７３は、所定の文字列を変数ｔ５に代入し、変数ｔ５を引数に含めて関数ＰｕｔＳｔａｔｅを呼び出し、関数ＰｕｔＳｔａｔｅの戻り値を変数ｔ６に代入する。第３番地では、ＳＳＡソースコード７３は、所定の文字列を変数ｔ１０に代入し、変数ｔ１０を引数に含めて関数ＰｕｔＳｔａｔｅを呼び出し、関数ＰｕｔＳｔａｔｅの戻り値を変数ｔ１１に代入する。
【０１０１】
ここで、関数ＰｕｔＳｔａｔｅの引数として使用される変数ｔ５，ｔ１０などの変数と、条件分岐文に使用される変数ｔ１とは、ＳＳＡソースコード７３上で代入関係をもたない。しかし、開発装置１００は、条件分岐文に使用される変数ｔ１も追跡することで、制御フローに起因する非決定的動作をＳＳＡソースコード７３から検出できる。
【０１０２】
第２の実施の形態の情報処理システムによれば、スマートコントラクトがＳＳＡソースコードに変換され、ＳＳＡソースコード上で所定の書き込み操作が検出され、ＳＳＡソースコードを逆順に走査して書き込み値に影響を与える非決定的操作が検出される。
【０１０３】
これにより、ブロックチェーンに書き込む値が入力情報および書き込み前のブロックチェーンの内容以外の外部状態に依存して変化するという不具合を検出することが可能となる。よって、複数のサーバ装置の間でブロックチェーンの整合性が失われることを防ぐことができる。また、ＳＳＡソースコードを利用することで、ブロックチェーンに書き込む値に関連する代入操作を少ない走査回数で高速に検索することができ、スマートコントラクトの非決定的動作の検証を短時間で実行することができる。
【符号の説明】
【０１０４】
１０  プログラム検証装置
１１  記憶部
１２  処理部
１３，１４  ソースコード
１５，１６  命令
【図１】
2020038482.tif 000003
【図２】
2020038482.tif 000004
【図３】
2020038482.tif 000005
【図４】
2020038482.tif 000006
【図５】
2020038482.tif 000007
【図６】
2020038482.tif 000008
【図７】
2020038482.tif 000009
【図８】
2020038482.tif 000010
【図９】
2020038482.tif 000011
【図１０】
2020038482.tif 000012
【図１１】
2020038482.tif 000013
【図１２】
2020038482.tif 000014
【図１３】
2020038482.tif 000015
【図１４】
2020038482.tif 000016