2024.11.14
いまさらNode.jsを知ろう~環境構築も~
2017.08.24
プログラミングEthereumとスマートコントラクトとマネーロンダリング
坂東です。
これの続きです。
Ethereumとトランザクションとマネーロンダリング
通常の仮想通貨のやりとりではトランザクションが残りますが、スマートコントラクト経由での送金はどうなるのか。
トークンを買って払い戻しするだけのスマートコントラクト作って試します。
pragma solidity ^0.4.0; //カウンター管理用Contract contract Laundering { mapping(address => uint256) coin; mapping(address => uint256) token; // トークン購入 function () payable { uint amount = msg.value; coin[msg.sender] += amount; // 入金額を記録 token[msg.sender] += amount; // トークンあげる } // トークンの残高確認 function balanceOf(address _owner) constant returns (uint256 balance) { return token[_owner]; } // 払い戻し function withdraw() { uint amount = coin[msg.sender]; msg.sender.transfer(amount); // 入金額を返金 token[msg.sender] -= amount; // トークンを消す coin[msg.sender] -= amount; // 入金額を消す } }
アカウント0番からコントラクトに送金します。
eth.getBalance(eth.accounts[0]) 2000000000000000000 eth.sendTransaction({ from:eth.accounts[0], to:コントラクトアドレス, value:web3.toWei(1, "ether"), gas:100000 })
0番のお金が減って
eth.getBalance(eth.accounts[0]) 998889490000000000 // gasが引かれるので中途半端
トークンが増えました。
balanceOf(eth.accounts[0]) uint256 balance: 1000000000000000000
トランザクションは0番からコントラクトに送金したのが残っています。
eth.getTransactionFromBlock(84) from: eth.accounts[0], to: コントラクトのアドレス, value: 1000000000000000000
次に、払い戻ししてみましょう。
functionを実行。
withdraw()
0番のお金が増えました。
eth.getBalance(eth.accounts[0]) 1998530912000000000
代わりにトークンがなくなりました。
balanceOf(eth.accounts[0]) uint256 balance: 0
トランザクションはコントラクトに払い戻しを命令したのが残っています。
eth.getTransactionFromBlock(97) from: eth.accounts[0], to: コントラクトのアドレス, value: 0
で、コントラクトから0番に送金されたトランザクションは…見当たらない。
eth.getTransactionFromBlock(98) null eth.getTransactionFromBlock(99) null eth.getTransactionFromBlock(100) null
トランザクションってお金の流れが全て記録されてると思ったけど、そうじゃないんですね。
じゃあコントラクト経由ならロンダリングしやすいんじゃねえと。
で、コントラクトに第三者に送金するfunctionを追加。
function transfer(address _dashiko) { uint amount = coin[msg.sender]; // 俺の金を _dashiko.transfer(amount); // 出し子に送金 token[msg.sender] -= amount; // 俺のトークンを消す coin[msg.sender] -= amount; // 俺の入金額を消す }
0番が1番に送金を実行。
transfer(eth.accounts[1])
1番にお金が届いた。
eth.getBalance(eth.accounts[1]) 2000000000000000000
0番がコントラクトを実行したトランザクションを見ると、input値が長くなっている。
eth.getTransactionFromBlock(134) from: eth.accounts[0], to: コントラクトのアドレス, input: "0x3331961a000000000000000000000000ae1d53ee575bffc939968c6242c9b8e728cd1de2", value: 0
inputにはどのようなfunctionを叩いたかが記録されており、デコードも出来るようです。
https://ethereum.stackexchange.com/questions/11144/how-to-decode-input-data-from-a-transaction
デコード方法は分かりませんでしたがinputの「ae1d53ee575bffc939968c6242c9b8e728cd1de2」の部分が1番のアカウントのハッシュ値と一致。
fromとtoじゃなくても、これで辿れますね。
じゃあコントラクト内に送金先をハードコートすればいいじゃん。
コントラクトにこのfunctionを追加して、
function transferDashiko() { address _dashiko = 0x00AE…; // 出し子のアカウント uint amount = coin[msg.sender]; // 俺の金を _dashiko.transfer(amount); // 出し子に送金 token[msg.sender] -= amount; // 俺のトークンを消す coin[msg.sender] -= amount; // 俺の入金額を消す }
送金を実行。
transferDashiko()
トランザクションに1番と関連付ける痕跡はありません。
eth.getTransactionFromBlock(214) from: eth.account[0], input: "0x8a4068dd", // たぶん transferDashiko() to: コントラクトのアドレス, value: 0
今度こそ取引履歴を残さずにお金を移動することができました。
トランザクションも無く、1番にはいきなりお金が湧いて出る。
マネーロンダリング完了。
というわけでもなく、スマートコントラクトってリバースエンジニアリングできるんですね。
getCodeでコントラクトのバイトコードを取って、
web3.eth.getCode(コントラクトのアドレス)
デコンパイラーを通せば可読化出来るらしい。(まだ試してない
https://github.com/comaeio/porosity
ただここまでやると、取引所で換金した側から大元まで辿るのは難しそう。
いきなりお金が湧いて出て怪しい奴が居る。
追求しても「知らねーよ、Ethereumのバグじゃねーの!」ってしらばっくれられる。
でもAPI全部理解したわけじゃないから何か方法あるのかも。
わたしはエンジニアで法律や金融はわかんないし、犯罪知識もギャングース読んだくらいで、マネーロンダリングへの理解も間違っているかもですが。
海外のico-listに明らかに不成立だろうってプロダクトが多くて、なぜか大金が投資されてるのは、スマートコントラクトを悪用してマネーロンダリングとか怪しいことしてるんじゃないかなと空想します。
日本のICOは免許を持った取引所が審査して独自のブロックチェーンと通貨で売買する中央集権型で別世界なので大丈夫だと思います。
おわり。
【記事への感想募集中!】
記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!【テクノデジタルではエンジニア/デザイナーを積極採用中です!】
下記項目に1つでも当てはまる方は是非、詳細ページへ!Qangaroo(カンガルー)
【テクノデジタルのインフラサービス】
当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。
最近の記事
タグ検索