//A basic learning-by-doing insurance contract in Solidity
//Author Davide "dada" Carboni
//Licensed under MIT
pragma solidity ^0.4.2;
contract Insurance {
//premium is what you pay to subscribe the policy
//premium是您付费订阅该政策 保费
// uint public premium;
//oracle is the 3rp party in charge of stating if a claim is legit
//oracle是第三方,负责说明如果索赔是合法的 第三方
address public oracle;
//protection is the financial protection provided by the contract
//protection是合同规定的财务保护
// uint public protection;
//insurer is the one who locks his money to fund the protection
//保险公司
address public insurer;
//subscriber is who wants the insurance protection
//投保人
// address public subscriber;
//银行
address public bank;
struct userInsurance{
uint state;
uint premium;
uint protection;
uint duration;
}
struct User{
//投保的状态
address userAddress;
string username;
//address oracle;
//uint premium;
//uint prot;
//uint duration;
//uint state;
uint numInsurances;
mapping(uint=>userInsurance) insurances;
}
uint public numUsers;
uint public numInsurances;
mapping(uint=>User) public users;
mapping (address => uint) public balances;
//给一个用户的地址,新增一个用户
function newUser(address userAddress,string username) returns (uint userID) {
userID = numUsers++;
users[userID]=User(userAddress,username,0);
newUsered(msg.sender,numUsers);
}
function newInsurance(uint userID,uint premium,uint prot,uint duration)payable{
User u=users[userID];
u.insurances[u.numInsurances++]=userInsurance(0,premium,prot,duration);
NewInsuranced(msg.sender,u.numInsurances);
}
//得到投保人的姓名和投保的状态
function getUser(uint userID,uint numInsurances)constant returns(address,string,uint)
{
User u=users[userID];
return (u.userAddress,
u.username,
u.numInsurances
//u.insurances[numInsurances].state,
//u.insurances[numInsurances].premium,
//u.insurances[numInsurances].protection,
//u.insurances[numInsurances].duration
);
}
function getInsurance(uint userID,uint numInsurances)constant returns(uint,uint,uint,uint)
{
User u=users[userID];
return(
u.insurances[numInsurances].state,
u.insurances[numInsurances].premium,
u.insurances[numInsurances].protection,
u.insurances[numInsurances].duration
);
}
function getNumUsers() constant returns (uint) {
return numUsers;
}
function getNumInsurances()constant returns(uint){
return numInsurances;
}
//银行给用户转账
function sendMoney(address receiver, uint amount) payable{
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
SentMoney(msg.sender, receiver, amount);
}
//银行创造钱
function mint(address receiver, uint amount) {
if (msg.sender != bank) return;
balances[receiver] += amount;
Minted(msg.sender,receiver,amount);
}
function setOracle(address orac)returns(address oracle){
oracle=orac;
//return oracle;
SetOracled(msg.sender,orac);
}
//contractCreator is who deploys the contract for profit
// 为了利润部署了合同
address public contractCreator;
//the contract goes through many states
//状态
//uint public state;
uint CREATED=0;
uint VALID=1;//有效
uint SUBSCRIBED=2;//订阅
uint ACTIVE=3;//激活
uint CLAIMED=4;//索赔登记
uint EXPIRED=5;//过期
uint PAID=6;//支付
uint REJECTED=7;//拒绝
//let's assign a fixed profit to who created the contract
//让我们为创建合同的人分配固定利润
uint constant profit = 200 finney;
//duration, a contract cannot last for ever
//持续时间
//uint duration;
//expireTime is when the contract expires
//expireTime是合同到期的时间
uint expireTime;
event Inited(uint _state);
event subscribed(address _from,uint _state);
event backed(address _from ,uint _state);
event claimed(address _from,uint _state);
event oracleDeclareClaimed(address _from ,uint _state);
event newUsered(address _from,uint _numUsers);
event SentMoney(address from, address to, uint amount);
event Minted(address from,address to,uint amount);
event SetOracled(address _from,address _to);
event NewInsuranced(address _from,uint _numInsurances);
function Insurance(){
// this function use no args because of Truffle limitation
contractCreator = msg.sender;//当前函数的外部调用者就是contractCreator
bank=msg.sender;
// state = CREATED;
}
function init(uint userID,uint numInsurances) {
User u= users[userID];
userInsurance ui=u.insurances[numInsurances];
if(ui.state!=CREATED) throw;//`throw`会终止和撤销所有的状态和以太改变。
//如果函数调用无效,这通常是一个好的选择。
//但是需要注意,这会消耗提供的所有gas。
// u.oracle = anOracle;
//u.premium = aPremium * 1 ether;
ui.premium = ui.premium * 1 ether;
//u.prot = prot * 1 ether;
ui. protection = ui. protection * 1 ether;
//u.duration = ttl;
bool valid;//有效
//let's check all the var are set
valid = ui.premium !=0 && ui.protection!=0 && ui.duration!=0;
if (!valid) throw;
ui.state = VALID;
Inited(ui.state);
}
//投保
function subscribe(uint userID,uint numInsurances) payable {
User u= users[userID];
userInsurance ui=u.insurances[numInsurances];
//is in the proper state?
//是否处于正常状态?
if(ui.state != VALID) throw;
//can't be both subscriber and oracle
//不能既是投保人又是oracle第三方
if(msg.sender == oracle) throw;
//must pay the exact sum
//必须支付确切的金额
if(balances[u.userAddress]==ui.premium){
//users=msg.sender;
ui.state = SUBSCRIBED;
//the contract creator grabs his money
//合同创造者抓住他的钱
//if(!contractCreator.send(profit)) throw;
subscribed(msg.sender,ui.state);
}
else throw;
}
//赚钱
function back(uint userID,uint numInsurances) payable{
User u= users[userID];
userInsurance ui=u.insurances[numInsurances];
//check proper state
//检查正确的状态
if(ui.state != SUBSCRIBED) throw;//已经投保
//can't be both backer and oracle
//不能既是受益人又是oracle
if(msg.sender == oracle) throw;
//must lock the exact sum for protection
//赔偿金额
if(balances[msg.sender]>ui.protection){
insurer=msg.sender;
ui.state = ACTIVE;
//insurer gets his net gain
//保险公司获得净收益
//if(!insurer.send(u.premium - profit)) throw; //this prevents re-entrant code
//这防止了重入代码
sendMoney(insurer,ui.premium);
expireTime = now + ui.duration;
backed(msg.sender,ui.state);
}
else throw;
}
function claim(uint userID,uint numInsurances)payable{
User u= users[userID];
userInsurance ui=u.insurances[numInsurances];
//if expired unlock sum to insurer and destroy contract
//如果到期解锁金额给保险公司并销毁合同
if(now > expireTime){
ui.state = EXPIRED;
//if(!insurer.send(u.prot))throw;//解冻保险公司押金,退回保险公司
//selfdestruct(contractCreator);
sendMoney(insurer,ui.protection);
claimed(msg.sender,ui.state);
}
//check if state is ACTIVE
if(ui.state!=ACTIVE)throw;
//are you the subscriber?
//if(msg.sender != u.userAddress)throw;
//ok, claim registered
//确定,索赔登记
ui.state=CLAIMED;
claimed(msg.sender,ui.state);
}
function oracleDeclareClaim (bool isTrue,uint userID,uint numInsurances)payable{
User u= users[userID];
userInsurance ui=u.insurances[numInsurances];
//is claimed?
if(ui.state != CLAIMED)throw;
//are you the oracle?
if(msg.sender!=oracle)throw;
//if claim is legit then send money to subscriber
if(isTrue){
ui.state = PAID;
//if(!u.userAddress.send(u.prot))throw;
sendMoney(u.userAddress,ui.protection);
}else{
ui.state = REJECTED;
//if(!insurer.send(u.prot))throw;
sendMoney(insurer,ui.protection);
oracleDeclareClaimed(msg.sender,ui.state);
}
//in any case destroy the contract and change is back to creator
//在任何情况下破坏合同和变化回到创造者
//selfdestruct(contractCreator);
}
}