今回は、攻撃を回避するオークション用スマートコントラクトを実行していきます。
アカウントごとの役割
アカウントの役割は次の通りです。
- MAIN ACCOUNT (eth.accounts[0]) “0xec3b01f36b44182746ca109230567c4915512e35”
オークションの オーナー。 - ACCOUNT1 (eth.accounts[1]) “0x63f25b9bbd974fdfa07477cb99c60d2073cfe560”
Bidder1(入札者1)。アカウント1。
最初の入札を行う。 - ACCOUNT2 (eth.accounts[2]) “0xd5adf1e9fbc1ed869ed4c7372961238fddc760a5”
Bidder2(入札者2)。アカウント2。⇒悪意のあるコンストラクトから攻撃を行う。
2回目の入札を行う。 - ACCOUNT3 (eth.accounts[3]) “0xe62be181791eb0add680739299165ec444e2eb73”
Bidder3(入札者3)。アカウント3。
3回目の入札を行う。 - ACCOUNT4 (eth.accounts[4])
マイナー。
デプロイ
まずはデプロイを行います。デプロイアカウントはMAIN ACCOUNTです。
[デプロイ時のイメージ]
1回目の入札(アカウント1)
アカウント1から10 etherを入札します。
[1回目の入札]
入札後のコントラクトの状態は下記のとおりです。
[コントラクトの状態]
最高額提示者がアカウント1で、最高掲示額が10 ehterになっていることが確認できます。
入札を行ったアカウント1の残高を確認します。
[アカウント1の残高]
10 ether減っていることが分かります。
2回目の入札(アカウント2・悪意のあるコントラクト)
悪意のあるコントラクトから20 etherを送金します。アカウント2を使用します。
to - addressには、送金先のオークション用コントラクトのアドレスを設定します。
[2回目の入札(悪意のあるコントラクトから)]
送金後のコントラクトの状態は下記のとおりです。
[コントラクトの状態]
最高額提示者がEvil Bidder(悪意のあるコントラクト)で、最高掲示額が20 ehterになっていることが確認できます。
送金を行ったアカウント2の残高を確認します。
[アカウント2の残高]
20 ether減っていること分かります。
3回目の入札(アカウント3)
アカウント3から30 etherを入札します。
改善前のオークション用コントラクトでは、悪意のあるコントラクトから送金後、一切入札ができなくなってしまったのでここで入札できれば問題が解消されているということになります。
[3回目の入札]
入札後のコントラクトの状態は下記のとおりです。
[コントラクトの状態]
最高額提示者がアカウント3で、最高掲示額が30 ehterになっていることが確認できます。
入札できなくなるという問題が解消されています。
入札を行ったアカウント3の残高を確認します。
[アカウント3の残高]
30 ether減っていることが分かります。
アカウント1の返金
返金処理を確認します。
アカウント1から返金の操作を行います。
[アカウント1の返金]
返金処理後のコントラクトの状態を確認します。
[コントラクトの状態]
60 etherから50 etherに減っていることが確認できます。
アカウント1の残高も確認しておきます。
[アカウント1の残高]
問題なく10 ether返金されています。
アカウント2の返金
悪意のあるコントラクトに返金リクエスト用の関数を定義していないので省略します。
アカウント3の返金
アカウント3は最高金額提示者なので返金できないのですが、一応返金されないことを確認します。
[アカウント3の返金]
返金処理後のコントラクトの状態を確認します。
[コントラクトの状態]
50 etherのまま変わっていませんので、返金されなかったということになります。
念のため、アカウント3の残高を確認します。
[アカウント3の残高]
やはり残高の増減はありません。
参考までに処理が実行されなかったことは、トランザクションのGasがすべて消費されていることでも確認できます。
アカウント3の返金処理では5000000weiを最大手数料(Provide maximum fee)として設定していました。
返金処理のトランザクション実行結果を確認します。
[トランザクションの実行結果]
Gas usedが5,000,000となっていて、指定した最大手数料が消費されているので処理が失敗しているということになります。
以上で、攻撃を回避するオークション用コントラクトの動作確認は完了となります。