Last active
July 7, 2018 05:02
-
-
Save yunho0130/48917f674f5c8780c31b92237a7b372a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.18; | |
| // Import OpenZeppelin's SafeMath contract to prevent overflow/underflow security issues | |
| // import "./SafeMath.sol"; | |
| // Import the custom token contract you just wrote. | |
| import "./HachToken.sol"; | |
| // Set up your contract. | |
| contract HachTokenLoan { | |
| // Attach SafeMath library functions to the uint256 type. | |
| using SafeMath for uint256; | |
| // 2018 MaengDev | |
| // Q. What is different point between inheritence and import | |
| //////////////////////////////////////// | |
| // 1. Set structs | |
| // structs: custom type, groups variables | |
| struct Creditor { | |
| address credWallet; | |
| uint256 credAmount; | |
| uint256 credEtherBalence; | |
| } | |
| struct Debtor { | |
| address debtWallet; | |
| uint256 debtAmount; | |
| uint256 debtEtherBalence; | |
| } | |
| struct P2PDeal { | |
| string dealName; | |
| address debtor; | |
| uint256 interestRate; | |
| uint256 etherAmount; | |
| uint256 dealPeriod; | |
| uint256 dueDate; | |
| bool dealStatus; | |
| bool dealClosing; | |
| } | |
| //////////////////////////////////////// | |
| // 2. Check creditor | |
| // modifiers: semantic helper functions | |
| modifier onlyCreditor { | |
| require(msg.sender == creditOwner); // conditional requirement check | |
| _; // function gets amended here | |
| } | |
| address public creditOwner; | |
| // constructor: optional function, executed on contract creation | |
| constructor() public { | |
| creditOwner = msg.sender; | |
| } | |
| //////////////////////////////////////// | |
| // 3. Set Hashtable | |
| // mappings: kind of like a hash table, with keys and values | |
| mapping (address => Creditor) public Creditors; // `public` automatically creates a getter function | |
| mapping (address => Debtor) public Debtors; // `public` automatically creates a getter function | |
| mapping (address => P2PDeal) public Deals; // `public` automatically creates a getter function | |
| // mapping (address => P2PLoan) public Loans; // `public` automatically creates a getter function | |
| // events: interface for EVM logs (historical record) | |
| event CreateDeal(address dealAddress, string dealName, address debtor, uint256 interestRate, uint256 etherAmount, uint256 dealPeriod, bool dealStatus, bool dealClosing); | |
| event NewLoan(uint256 loanDuedate, address dealAddress, address fromCreditor, address toDebtor, uint256 value); | |
| event NewCreditor(address credtorAddress , address credWallet, uint256 credAmount, uint256 credEtherBalence); | |
| event NewDebtor(address debtorAddress , address debtWallet, uint256 debtAmount, uint256 debtEtherBalence); | |
| //////////////////////////////////////// | |
| // 4. Set Deals | |
| function setDeal(string _dealName, address _debtor, uint256 _interestRate, uint256 _etherAmount, uint256 _dealPeriod) public { | |
| // Set conditions with require statements to make sure the rate is a positive number and the addresses are non-zero. | |
| _preValidateDeal(_debtor, _interestRate, _etherAmount, _dealPeriod); | |
| address _address = msg.sender; | |
| // Set deal information | |
| // Q. how to get the transaction/contract _address? | |
| P2PDeal storage deal = Deals[_address]; | |
| deal.dealName = _dealName; | |
| deal.debtor = _debtor; | |
| // Please keep in mind you have to use div(100) for checking | |
| deal.interestRate = _interestRate; | |
| // 1Ether = wei^18 = gwei^9 | |
| deal.etherAmount = _etherAmount; | |
| // To implement timestamp? block.timestamp & now, seconds UTC | |
| // 1 day = 86400 sec | |
| deal.dealPeriod = _dealPeriod; | |
| deal.dueDate = block.timestamp.add(_dealPeriod.mul(86400)); | |
| deal.dealStatus = true; | |
| deal.dealClosing = false; | |
| bool _dealStatus; | |
| bool _dealClosing; | |
| _dealStatus = deal.dealStatus; | |
| _dealClosing = deal.dealClosing; | |
| // emit an Event, which stores the values in EVM logs | |
| emit CreateDeal(_address , _dealName, _debtor, _interestRate, _etherAmount, _dealPeriod, _dealStatus, _dealClosing); | |
| } | |
| //////////////////////////////////////// | |
| // Set creditor and debtor | |
| function setCreditor (address _credWallet, uint256 _credAmount, uint256 _credEtherBalence) public { | |
| address _address = msg.sender; | |
| Creditor storage creditor = Creditors[_address]; | |
| creditor.credWallet = _credWallet; | |
| creditor.credAmount = _credAmount; | |
| creditor.credEtherBalence = _credEtherBalence; | |
| emit NewCreditor(_address , _credWallet, _credAmount, _credEtherBalence); | |
| } | |
| function setDebtor (address _debtWallet, uint256 _debtAmount, uint256 _debtEtherBalence) public { | |
| address _address = msg.sender; | |
| Debtor storage debtor = Debtors[_address]; | |
| debtor.debtWallet = _debtWallet; | |
| debtor.debtAmount = _debtAmount; | |
| debtor.debtEtherBalence = _debtEtherBalence; | |
| emit NewDebtor(_address , _debtWallet, _debtAmount, _debtEtherBalence); | |
| } | |
| //////////////////////////////////////// | |
| // 5. Loan | |
| // ! Future Plan: enrollWhitelist | |
| // Define 4 publicly accessible state variables. | |
| // Your custom token being sold. | |
| HachToken public token; | |
| // Wallet address where fees are collected. | |
| address public wallet; | |
| // Rate of how many token units a buyer gets per wei. Note that wei*10^-18 converts to ether. | |
| uint256 public rate; | |
| // Amount of wei raised. | |
| uint256 public weiRaised; | |
| // raise event | |
| event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); | |
| // Q. How to input the struct as a parameter | |
| function excutionLoan(address _dealAddress, address _fromCreditor, address _toDebtor, uint256 _value) onlyCreditor public payable { | |
| // Check the dael status | |
| require(Deals[_dealAddress].dealStatus == true); | |
| // ! many 'require' are needed | |
| // Q. How to make these function call as a transaction (All or Nothing) | |
| // Transfer Loan | |
| token.approve(_toDebtor, _value); | |
| token.transferFrom(_fromCreditor, _toDebtor, _value); | |
| // cred & debtAmount change | |
| Creditors[_fromCreditor].credAmount.add(_value); | |
| Debtors[_toDebtor].debtAmount.add(_value); | |
| // Set loanDuedate | |
| uint256 loanDuedate = block.timestamp.add(Deals[_dealAddress].dealPeriod); | |
| // emit an Event, which stores the values in EVM logs | |
| emit NewLoan(loanDuedate, _dealAddress, _fromCreditor, _toDebtor, _value); | |
| // Change deal status | |
| Deals[_dealAddress].dealStatus == false; | |
| } | |
| // | |
| //////////////////////////////////////// | |
| // 6. reimburse: pay for debt | |
| function reimburse(address _dealAddress, address _fromDebtor, address _toCreditor, uint256 _reimburseValue) public payable { | |
| // Check the dael status | |
| require(Deals[_dealAddress].dealClosing == false); | |
| // Check msg.sender | |
| require(msg.sender == Deals[_dealAddress].debtor); | |
| // Check the debt size | |
| require(_reimburseValue == Debtors[_fromDebtor].debtAmount.mul(Deals[_dealAddress].interestRate)); | |
| // ! Validate balance, debt, etc... | |
| // Reimburse Value | |
| token.approve(_toCreditor, _reimburseValue); | |
| token.transferFrom(_fromDebtor, _toCreditor, _reimburseValue); | |
| // cred & debtAmount change | |
| Creditors[_toCreditor].credAmount.sub(_reimburseValue); | |
| Debtors[_fromDebtor].debtAmount.sub(_reimburseValue); | |
| // Closing deal | |
| Deals[_dealAddress].dealClosing == true; | |
| } | |
| //////////////////////////////////////// | |
| // . exchangeToken | |
| function exchangeToken() public payable { | |
| chargeFee(); | |
| } | |
| //////////////////////////////////////// | |
| // . chargeFee | |
| function chargeFee() public payable { | |
| } | |
| //////////////////////////////////////// | |
| // . dealPeriodChecker | |
| function dealPeriodChecker() public { | |
| } | |
| //////////////////////////////////////// | |
| // . timeLock and PoS reward | |
| function timeLock() internal{ | |
| } | |
| function posReward() public payable { | |
| } | |
| // THIS PORTION IS FOR THE CONTRACT'S EXTERNAL INTERFACE. | |
| // We suggest skipping down to fill out the internal interface before coming back to complete the external interface. | |
| // Create the fallback function that is called whenever anyone sends funds to this contract. | |
| // Fallback functions are functions without a name that serve as a default function. | |
| // Functions dealing with funds have a special modifier. | |
| function () external payable { | |
| // Call buyTokens function with the address defaulting to the address the message originates from. | |
| buyTokens(msg.sender); | |
| } | |
| // Create the function used for token purchase with one parameter for the address performing the token purchase. | |
| function buyTokens(address _beneficiary) public payable { | |
| // Define a uint256 variable that is equal to the number of wei sent with the message. | |
| uint256 weiAmount = msg.value; | |
| // Call function that validates an incoming purchase. | |
| _preValidatePurchase(_beneficiary, weiAmount); | |
| // Calculate token amount to be created and define it as type uint256. | |
| uint256 tokens = _getTokenAmount(weiAmount); | |
| // Update amount of funds raised. | |
| weiRaised = weiRaised.add(weiAmount); | |
| // Call function that processes a purchase. | |
| _processPurchase(_beneficiary, tokens); | |
| // Raise the event associated with a token purchase. | |
| TokenPurchase(msg.sender, _beneficiary, weiAmount, tokens); | |
| // Call function that stores ETH from purchases into a wallet address. | |
| _forwardFunds(); | |
| } | |
| //////////////////////////////////////// | |
| // THIS PORTION IS FOR THE CONTRACT'S INTERNAL INTERFACE. | |
| // Remember, the following functions are for the contract's internal interface. | |
| // . For Set Deal | |
| function _preValidateDeal(address _debtor, uint256 _interestRate, uint256 _etherAmount, uint256 _dealPeriod) internal { | |
| // require(_dealName != ''); // default value is 0 if it is existance. | |
| require(_interestRate > 0); | |
| require(_etherAmount > 0); | |
| require(_debtor != address(0)); | |
| require(_dealPeriod > 0); | |
| } | |
| //////////////////////////////////////// | |
| // . CrowdSale | |
| // Create function that validates an incoming purchase with two parameters: beneficiary's address and value of wei. | |
| function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { | |
| // Set conditions to make sure the beneficiary's address and the value of wei involved in purchase are non-zero. | |
| require(_beneficiary != address(0)); | |
| require(_weiAmount != 0); | |
| } | |
| // Create function that delivers the purchased tokens with two parameters: beneficiary's address and number of tokens. | |
| function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { | |
| // Set condition that requires contract to mint your custom token with the mint method inherited from your MintableToken contract. | |
| require(HachToken(token).mint(_beneficiary, _tokenAmount)); | |
| } | |
| // Create function that executes the deliver function when a purchase has been processed with two parameters: beneficiary's address and number of tokens. | |
| function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal { | |
| _deliverTokens(_beneficiary, _tokenAmount); | |
| } | |
| // Create function to convert purchase value in wei into tokens with one parameter: value in wei. | |
| // Write the function so that it returns the number of tokens (value in wei multiplied by defined rate). | |
| // Multiplication can be done as a method. | |
| function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) { | |
| return _weiAmount.mul(rate); | |
| } | |
| // Create function to store ETH from purchases into a wallet address. | |
| function _forwardFunds() internal { | |
| wallet.transfer(msg.value); | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment