Solidityによるコントラクトの作成(3) - スワップ取引

[前回](http://qiita.com/toshikase/items/467f8998506a2f0cf258)はオプション取引の実装方法をご紹介しました。今回は同じ要領でスワップ取引を実装しましょう。

##コントラクト概要
今回は金利スワップを実装します。金利スワップとは同一通貨間で異なる種類の金利を交換する取引のことです。最も多い取引は固定金利と変動金利の交換です。
例えば円の金利スワップでは、固定金利と6ヵ月[TIBOR](http://www.ifinance.ne.jp/glossary/market/mar006.html)とを半年毎に交換する取引などがあります。

今回実装する取引の設定は以下の通りです。

**基本情報**

| key | value | 
|:----------|:-----------|
| 通貨 | ether(≒¥1,000) |
| 想定元本 | 1,000 | 
| デポジット |100 | 
| 満期日 | 契約日から2年後 |
| 受渡サイクル | 1ヶ月 | 
| 変動金利(支払) |  0xc12b4d335ce5f0cf48001c8b06e1f941edb68e9d | 
| 固定金利(支払) | 0xbc2ee815f7115c3d7cd1bc389fcb9b4f93c52830 |  
 
**変動金利**

| key | value | 
|:----------|:-----------|
| 基準金利 | 1% |
| スプレッド | 2% |

**固定金利**

| key | value | 
|:----------|:-----------|
| 基準金利 | -- |
| スプレッド | 4% |

以下が完成形のコードです

```swap_trade.sol
contract SwapTrade{
    address public fixed_side;
    address public floated_side;
    uint public capital;
    uint public fixed_rate;
    uint public spread;
    function SwapTrade(
      address _fixed_side,
      address _floated_side,
      uint _capital,
      uint _fixed_rate,
      uint _spread
      ){
      fixed_side = _fixed_side;
      floated_side = _floated_side;
      capital = _capital;
      fixed_rate = _fixed_rate;
      spread = _spread;
    }
    function Execution(uint floating_rate){
      floated_side.send(capital*fixed_rate);
      fixed_side.send(capital*(floating_rate+spread));
    }
    function () {
      throw;
    }
}
```

- SwapTrade：初期化
- Execution：利息支払実行

##コントラクト登録

まずコードをコンパイルします。

```
> var source = "contract SwapTrade{    address public fixed_side;    address public floated_side;    uint public capital;    uint public fixed_rate;    uint public spread;    function SwapTrade(      address _fixed_side,      address _floated_side,      uint _capital,      uint _fixed_rate,      uint _spread      ){      fixed_side = _fixed_side;      floated_side = _floated_side;      capital = _capital;      fixed_rate = _fixed_rate;      spread = _spread;    }    function Execution(uint floating_rate){      floated_side.send(capital*fixed_rate);      fixed_side.send(capital*(floating_rate+spread));    }    function () {      throw;    }}"
> var compiledSource = eth.compile.solidity(source)
```

続いて、コントラクトをEthereumのネットワークに送信します。

```
> var abiDefinition = compiledSource.SwapTrade.info.abiDefinition
> var compiledContract = eth.contract(abiDefinition)
> var fixedSide = "0xc12b4d335ce5f0cf48001c8b06e1f941edb68e9d"
> var floatedSide = "0xbc2ee815f7115c3d7cd1bc389fcb9b4f93c52830"
> var contract = compiledContract.new(fixedSide, floatedSide, 10*1.0e+18, 4, 2, {from: fixedSide, data: compiledSource.SwapTrade.code, gas:1000000, value: web3.toWei(100,"ether")})
```
ここで、`fixedSide`は変動金利を支払うアドレス、`floatedSide`は固定金利を支払うアドレスです。
`10*1.0e+18`,`4`,`2`はそれぞれ想定元本、固定金利、スプレッドを表しています。solidityでは浮動小数点は扱えないので、想定元本を1/100しています。(その後、単位をweiからetherに変更するため、10e+18倍しています。) 固定金利とスプレッドは100倍しています。
また `value: web3.toWei(100,"ether")` でfixedSideからこのアカウントに100etherデポジットしています。

以下のようにコントラクトが送信されました。

```
> contract
{
  address: undefined,
  transactionHash: "0x3b0a5a32f549bec31bcf173274a344add2f319b9de0367071392e3fd9717ce07"
}
> web3.fromWei(eth.getBalance("0x4934f96cbb5f82ead8d56f96ec11f98c826cc926"),"ether")
0
> web3.fromWei(eth.getBalance(fixesSide),"ether")
959.972328980000000030
```

この状態ではコントラクトの残高は0です。

続いてマイニングを行います。マイニングが完了すると以下のようになります。アドレスが付与されるているのがわかります。

```
> contract
{
  address: "0x4934f96cbb5f82ead8d56f96ec11f98c826cc926",
  transactionHash: "0x3b0a5a32f549bec31bcf173274a344add2f319b9de0367071392e3fd9717ce07",
  Execution: function(),
  allEvents: function(),
  capital: function(),
  fixed_rate: function(),
  fixed_side: function(),
  floated_side: function(),
  spread: function()
}
```

またコントラクトの残高がデポジット分変化しているのがわかります。

```
> web3.fromWei(eth.getBalance("0x4934f96cbb5f82ead8d56f96ec11f98c826cc926"),"ether")
100
> web3.fromWei(eth.getBalance(fixesSide),"ether")
859.96823490000000003
```

(本来であれば、この後floatedSideからも100etherデポジットする必要があるのですが、今回はその手続は省いて先に進みます。)

##Executionメソッド
初期化が完了しました。続いて1ヶ月がたった前提でExecutionメソッドを実行しましょう。
これは支払日に利息の支払いを実効するメソッドです。

```
function Execution(uint floating_rate){
     floated_side.send(capital*fixed_rate);
     fixed_side.send(capital*(floating_rate+spread));
}
```

メソッドを呼び出しましょう。

```
> contract.Execution.sendTransaction(1, {from: fixedSide, gas:1000000})
```

マイニング前の両者のether残高です。

```
> web3.fromWei(eth.getBalance(fixedSide),"ether")
859.96823490000000003
> web3.fromWei(eth.getBalance(floatedSide),"ether")
1439.96000000000000004
```

マイニング完了後は以下のように残高が変化します。利息分だけ両者の残高が増えているのがわかります。

fixedSideは変動金利を受け取るので30ether増えます。
変動金利：1000×(0.01+0.02) = 30

floatedSideは固定金利を受け取るので40ether増えます。
固定金利：1000×0.04 = 40

```
> web3.fromWei(eth.getBalance(fixedSide),"ether")
889.96752358000000003
> web3.fromWei(eth.getBalance(floatedSide),"ether")
1479.96000000000000004
```
実際に増えていますね。

##まとめ
今回まで3回に渡りSolidityを用いたコントラクトの開発方法について綴ってきました。
これを機に皆様がEthereumに興味を持ってくだされば幸いです。また何かあればいつでもご質問・ご連絡ください。