Ethereum(38) - Transaction-Ordering Dependence①(実装編)

トランザクションがブロックに取り込まれる順番はマイナーに依存するため、意図した順番でトランザクションが実行されないことがあります。

この問題はTransaction-Ordering Dependenceと呼ばれています。

サンプルコードを作成し、この問題を検証していきます、

実装

Transaction-Ordering Dependence問題を確認するための、サンプルコードは下記の通りです。

マーケットプレイスを表現したスマートコントラクトになります。

[ソースコード]

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
32
33
34
35
36
37
38
39
40
41
42
43
44
pragma solidity ^0.4.11;

contract MarketPlaceTOD {
address public owner;
uint public price; // 1個あたりの金額
uint public stockQuantity; // 在庫数

modifier onlyOwner() {
require(msg.sender == owner);
_;
}

event UpdatePrice(uint _price);
event Buy(uint _price, uint _quantity, uint _value, uint _change);

/// コンストラクタ
function MarketPlaceTOD() {
owner = msg.sender;
price = 10;
stockQuantity = 100;
}

/// 1個あたりの金額を更新
function updatePrice(uint _price) public onlyOwner {
price = _price;
UpdatePrice(price);
}

/// 購入処理
function buy(uint _quantity) public payable {
// 購入金額と在庫数を確認
if (msg.value < _quantity * price || _quantity > stockQuantity) {
throw;
}

// お釣りを返す
if(!msg.sender.send(msg.value - _quantity * price)) {
throw;
}

stockQuantity -= _quantity; // 在庫を減らす
Buy(price, _quantity, msg.value, msg.value - _quantity * price);
}
}

このコードのポイントは次の通りです。

  • 売り手がコントラクトを生成します。
  • 買い手がコントラクトにトランザクションを発行することで購入が成立します。
  • コントラクトは1個あたりの値段在庫数をステートに保持しています。
  • 値段はupdatePrice関数を実行することで、売り手が更新します。
  • 買い手はbuy関数をetherの送金を伴う形で呼び出すことで購入可能です。
  • 送金額がbuy関数の引数の購入数1個あたりの値段をかけた値以上で、在庫がある場合に購入できます。

次回は、このスマートコントラクトをデプロイし、geth上で動作確認できるようにコントラクト変数を定義します。