Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

Organization

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

前回はオプション取引の実装方法をご紹介しました。今回は同じ要領でスワップ取引を実装しましょう。

コントラクト概要

今回は金利スワップを実装します。金利スワップとは同一通貨間で異なる種類の金利を交換する取引のことです。最も多い取引は固定金利と変動金利の交換です。
例えば円の金利スワップでは、固定金利と6ヵ月TIBORとを半年毎に交換する取引などがあります。

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

基本情報

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に興味を持ってくだされば幸いです。また何かあればいつでもご質問・ご連絡ください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
6
Help us understand the problem. What are the problem?