學習solidity的一個簡單智慧合約(2)——對衝

NO IMAGE

在白皮書中看到,以太坊之上有三種應用。第一類是金融應用,為使用者提供更強大的用他們的錢管理和參與合約的方法。包括子貨幣,金融衍生品,對衝合約,儲蓄錢包,遺囑,甚至一些種類的全面的僱傭合約。第二類是半金融應用,這裡有錢的存在但也有很重的非金錢的方面,一個完美的例子是為解決計算問題而設的自我強制懸賞。最後,還有線上投票和去中心化治理這樣的完全的非金融應用。

於是根據白皮書上的一個例子——對衝合約,即一種金融衍生品——進行了編寫(僅僅是模擬,還不知道怎麼加入區塊鏈),用智慧合約進行編寫的原因是因為在這一方面的特別的方便

以下是白皮書上舉一個例子:

當這些關鍵要素都齊備,對衝合約看起來會是下面的樣子:

等待A輸入1000以太幣。.

等待B 輸入1000以太幣。

通過查詢資料提供合約,將1000以太幣的美元價值,例如,x美元,記錄至儲存器。

30天后,允許A或B“重新啟用“合約以傳送價值x美元的以太幣(重新查詢資料提供合約,以獲取新價格並計算)給A並將剩餘的以太幣傳送給B。

pragma solidity ^0.4.0;
//完成金融衍生品對衝合約
/*等待A輸入1000以太幣。.
等待B 輸入1000以太幣。
通過查詢資料提供合約,將1000以太幣的美元價值,例如,x美元,記錄至儲存器。
30天后,允許A或B“重新啟用“合約以傳送價值x美元的以太幣
(重新查詢資料提供合約,以獲取新價格並計算)給A並將剩餘的以太幣傳送給B。*/

描述在註釋中對衝智慧合約;

contract hedge{
struct giver{
address gaddr;//A方人地址
bool yn;//是否投票
uint amount;//金額
}
struct reciever{
address raddr;//B方人地址
bool yn;//是否投票        
uint amount;//金額
}
address p1;
address p2;
mapping(address => giver) givers;
mapping(address => reciever) recievers;
function initializeA(address giverA){
// A方人初始化
givers[giverA].amount = 1000 ether;
givers[giverA].yn = true;
p1 = giverA;
givers[giverA].amount = 0 ether;
}
function initializeB(address recieverB){
// B方人初始化
recievers[recieverB].amount = 1000 ether;
recievers[recieverB].yn = true;
p2 = recieverB;
recievers[recieverB].amount = 0 ether;
}

uint  hedgevalue;
function hedging1(uint exchangerate) returns (uint){
hedgevalue = 1000 ether /exchangerate ;
return  hedgevalue;
}

bool success; function hedging2(uint exchangerate , uint time) returns(bool success){ if(time != 30) return false ; if(givers[p1].yn == false) return false; if(recievers[p2].yn == false) return false; givers[p1].amount = hedgevalue * exchangerate; recievers[p2].amount
= 2000 ether – hedgevalue * exchangerate; return true ; } function checkA(address giverA)returns(uint){ if(success) givers[giverA].amount = givers[p1].amount ; else givers[giverA].amount = 1000 ether; return givers[giverA].amount; } function checkB(address
recieverB)returns(uint){ if(success) recievers[recieverB].amount = recievers[p2].amount; else recievers[recieverB].amount = 1000 ether; return recievers[p2].amount; }}

以上是全部程式碼,接下來將慢慢分析;

struct giver{
address gaddr;//A方人地址
bool yn;//是否投票
uint amount;//金額
}
struct reciever{
address raddr;//B方人地址
bool yn;//是否投票
uint amount;//金額
}

首先是確定進行交易的雙方(包含地址,是否投票(預設為否),金額)

function initializeA(address giverA){
// A方人初始化
givers[giverA].amount = 1000 ether;
givers[giverA].yn = true;
p1 = giverA;
givers[giverA].amount = 0 ether;
}
function initializeB(address recieverB){
// B方人初始化
recievers[recieverB].amount = 1000 ether;
recievers[recieverB].yn = true;
p2 = recieverB;
recievers[recieverB].amount = 0 ether;
}

然後對雙方進行初始化,每個賬戶打入1000ether;然後確認交易後,bool改為true;第三部是將地址用一個storage儲存起來方便以後呼叫,如果沒有amount而使用balance,第四部轉賬可以只用msg.sender(準備下次實現),目前只有將amount變為0來表示將1000ether轉入對衝基金(在現實生活中則有很高的風險,是明顯不可取的)。

uint  hedgevalue;
function hedging1(uint exchangerate) returns (uint){
hedgevalue = 1000 ether /exchangerate ;
return  hedgevalue;
}

這一段是對衝的第一部,將1000ether根據匯率轉換成其他貨幣;

 bool success;
function hedging2(uint exchangerate , uint time) returns(bool success){
if(time != 30) return false ;
if(givers[p1].yn == false) return false;
if(recievers[p2].yn == false) return false;
givers[p1].amount = hedgevalue * exchangerate;
recievers[p2].amount = 2000 ether - hedgevalue * exchangerate;
return true ;
}

接著便是對衝的第二部,30 天后再次轉化回以太幣;值得注意的是使用了bool以防交易失敗;

最後兩部則是確定雙方交易後的金額;

值得提醒的是,在轉換匯率的時候,我用的整型,這在現實中也是不可能的額

程式在可以在Remix上完成除錯。