반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
pragma solidity ^0.4.19;
 
contract Owned{
    address public owner;
    
    event TransferOwnership(address oldaddr, address newaddr);
    
    modifier onlyOwner(){
        require(msg.sender == owner);
        _;
    }
    
    function Owned(){
        owner = msg.sender;
    }
    
    function transferOwnership(address _new) onlyOwner{
        address oldaddr = owner;
        owner = _new;
        TransferOwnership(oldaddr, owner);
    }
}
 
contract Member is Owned{
    address public coin;
    MemberStatus[] public status;
    
    mapping(address => History) public tradingHistory;
    
    struct MemberStatus{
        string name;
        uint times;
        uint sum;
        int8 rate;
    }
    
    struct History{
        uint times;
        uint sum;
        uint statusIndex;
    }
    
    modifier onlyCoin(){
        require(msg.sender == coin);
        _;
    }
    
    function setCoin(address _addr) onlyOwner{
        coin = _addr;
    }
    
    function pushStatus(string _name, uint _times, uint _sum, int8 _rate) onlyOwner{
        status.push(
            MemberStatus({
            name: _name,
            times: _times,
            sum: _sum,
            rate: _rate 
            })
        );
    }
    
    function editStatus(uint _index, string _name, uint _times, uint _sum, int8 _rate) onlyOwner{
        if(_index < status.length){
            status[_index].name = _name;
            status[_index].times = _times;
            status[_index].sum = _sum;
            status[_index].rate = _rate;
        }
    }
    
    function updateHistory(address _member, uint _value) onlyCoin{
        tradingHistory[_member].times += 1;
        tradingHistory[_member].sum += _value;
        
        uint index;
        for(uint i = 0; i < status.length; i++){
            if(tradingHistory[_member].times >= status[i].times && 
            tradingHistory[_member].sum >= status[i].sum){
                index = i;
            }
        }
        tradingHistory[_member].statusIndex = index;
    }
    
    function getCashackRate(address _member) constant returns(int8 rate){
        rate = status[tradingHistory[_member].statusIndex].rate;
    }
}
 
contract CrocusCoin is Owned{
    string public name;
    string public symbol;
    uint8 public decimals;
    uint public totalSupply;
    
    mapping(address => uintpublic balanceOf;
    mapping(address => int8) public blackList;
    mapping(address => Member) public members;
    
    event Transfer(address indexed from, address indexed to, uint value);
    event Blacklisted(address indexed target);
    event DeleteFromBlacklist(address indexed target);
    event RejectedPaymentToBlacklistedAddr(address indexed from, address indexed to, uint value);
    event RejectedPaymentFromBlacklistedAddr(address indexed from, address indexed to, uint value);
    event SetCashback(address indexed addr, int8 rate);
    event Cashback(address indexed from, address indexed to, uint value);
    
    function CrocusCoin(uint _supply, string _name, string _symbol, uint8 _decimals){
        balanceOf[msg.sender= _supply;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _supply;
        owner = msg.sender;
    }
    
    function blacklisting(address _addr) onlyOwner{
        blackList[_addr] = 1;
        Blacklisted(_addr);
    }
    
    function deleteFromBlacklist(address _addr) onlyOwner{
        blackList[_addr] = 0;
        DeleteFromBlacklist(_addr);
    }
    
    function setMembers(Member _members){
        members[msg.sender= Member(_members);
   }
    
    function transfer(address _to, uint _value){
        require(balanceOf[msg.sender>= _value);
        require(balanceOf[_to] + _value >= balanceOf[_to]);
    
        if(blackList[msg.sender> 0){
            RejectedPaymentFromBlacklistedAddr(msg.sender, _to, _value);
        }
        else if(blackList[_to] > 0){
            RejectedPaymentToBlacklistedAddr(msg.sender, _to, _value);
        }
        else{
            uint cashback = 0;
            if(members[_to] > address(0)){
                cashback = _value / 100 * uint(members[_to].getCashackRate(msg.sender));
                members[_to].updateHistory(msg.sender, _value);
            }
        }
        
        balanceOf[msg.sender-= (_value - cashback);
        balanceOf[_to] += (_value - cashback);
        
        Transfer(msg.sender, _to, _value);
        Cashback(_to, msg.sender, cashback);
    }
}
 
cs



contract Owned{

    address public owner;
    
    event TransferOwnership(address oldaddr, address newaddr);
    
    modifier onlyOwner(){
        require(msg.sender == owner);
        _;
    }
    
    function Owned(){
        owner = msg.sender;
    }
    
    function transferOwnership(address _new) onlyOwner{
        address oldaddr = owner;
        owner = _new;
        TransferOwnership(oldaddr, owner);
    }
}


Owned는 소유자 관리용 계약을 의미한다.


onlyOwner 함수 제어자는 컨트랙트 소유자를 확인하는 용도이다.


Owned 생성자는 owner가 msg.sender 즉, 최초 컨트랙트 생성자가 owner이 된다.


transferOwnership로 인해 소유자만이 새로운 사람으로 소유자 변경이 가능하게 된다.



contract Member is Owned{
    address public coin;
    MemberStatus[] public status;
    
    mapping(address => History) public tradingHistory;
    
    struct MemberStatus{
        string name;
        uint times;
        uint sum;
        int8 rate;
    }
    
    struct History{
        uint times;
        uint sum;
        uint statusIndex;
    }
    
    modifier onlyCoin(){
        require(msg.sender == coin);
        _;
    }
    
    function setCoin(address _addr) onlyOwner{
        coin = _addr;
    }
    
    function pushStatus(string _name, uint _times, uint _sum, int8 _rate) onlyOwner{
        status.push(
            MemberStatus({
            name: _name,
            times: _times,
            sum: _sum,
            rate: _rate 
            })
        );
    }
    
    function editStatus(uint _index, string _name, uint _times, uint _sum, int8 _rate) onlyOwner{
        if(_index < status.length){
            status[_index].name = _name;
            status[_index].times = _times;
            status[_index].sum = _sum;
            status[_index].rate = _rate;
        }
    }
    
    function updateHistory(address _member, uint _value) onlyCoin{
        tradingHistory[_member].times += 1;
        tradingHistory[_member].sum += _value;
        
        uint index;
        for(uint i = 0; i < status.length; i++){
            if(tradingHistory[_member].times >= status[i].times && 
            tradingHistory[_member].sum >= status[i].sum){
                index = i;
            }
        }
        tradingHistory[_member].statusIndex = index;
    }
    
    function getCashackRate(address _member) constant returns(int8 rate){
        rate = status[tradingHistory[_member].statusIndex].rate;
    }
}


Member 컨트랙트는 Owned를 상속하고 있다.


    address public coin;
    MemberStatus[] public status;
    
    mapping(address => History) public tradingHistory;
    
    struct MemberStatus{
        string name;
        uint times;
        uint sum;
        int8 rate;
    }
    
    struct History{
        uint times;
        uint sum;
        uint statusIndex;
    }


현재 코인의 주인을 나타내는 coin가 있고,


MemberStatus 구조체는 등급을 나타내는 구조체이다.(브론즈, 실버, 골드 등등)

name는 등급 이름을, times는 등급에 필요한 거래 횟수를, sum은 등급에 필요한 거래 총액을 rate는 캐시백 받을 수 있는 비율이다.


History 구조체에서 times는 거래 횟수를 sum은 거래 금액을 statusIndex는 등급 인덱스를 나타낸다.



    modifier onlyCoin(){
        require(msg.sender == coin);
        _;
    }
    
    function setCoin(address _addr) onlyOwner{
        coin = _addr;
    }
    
    function pushStatus(string _name, uint _times, uint _sum, int8 _rate) onlyOwner{
        status.push(
            MemberStatus({
            name: _name,
            times: _times,
            sum: _sum,
            rate: _rate 
            })
        );
    }


onlyCoin 함수 제어자는 해당하는 코인이 msg.sender것이어야 한다.


setCoin은 토큰 주소를 설정해주는 함수이고


pushStatus는 등급을 나타내는 것들을 추가해주는 함수이다. (즉, 브론즈, 실버, 골드 다음 플레티넘 같은 것들을 추가하는 과정)



    function editStatus(uint _index, string _name, uint _times, uint _sum, int8 _rate) onlyOwner{
        if(_index < status.length){
            status[_index].name = _name;
            status[_index].times = _times;
            status[_index].sum = _sum;
            status[_index].rate = _rate;
        }
    }
    
    function updateHistory(address _member, uint _value) onlyCoin{
        tradingHistory[_member].times += 1;
        tradingHistory[_member].sum += _value;
        
        uint index = tradingHistory[_member].statusIndex;
        for(uint i = 0; i < status.length; i++){
            if(tradingHistory[_member].times >= status[i].times && 
            tradingHistory[_member].sum >= status[i].sum){
                index = i;
            }
        }
        tradingHistory[_member].statusIndex = index;
    }
    
    function getCashbackRate(address _member) constant returns(int8 rate){
        rate = status[tradingHistory[_member].statusIndex].rate;
    }



editStatus는 말그대로 등급의 특정 조건들을 변경시켜준다.


updateHistory는 해당하는 멤버의 거래수를 +1, 거래 금액을 += _value 해준다.


그리고 이제 이 사람의 등급이 바뀌는지 확인하기 위해 아래 for문 과정을 거친다.


i의 인덱스가 처음부터 낮은 등급을 의미하니 해당하는 등급을 찾아줄 수 있게 된다.


마지막으로 tradingHistory[_member].statusIndex = index를 통해 등급을 업데이트 해준다.

 

getCashbackRate는 캐시백 받을 비율을 계산해주는 함수이다.





contract CrocusCoin is Owned{
    string public name;
    string public symbol;
    uint8 public decimals;
    uint public totalSupply;
    
    mapping(address => uintpublic balanceOf;
    mapping(address => int8) public blackList;
    mapping(address => Member) public members;
    
    event Transfer(address indexed from, address indexed to, uint value);
    event Blacklisted(address indexed target);
    event DeleteFromBlacklist(address indexed target);
    event RejectedPaymentToBlacklistedAddr(address indexed from, address indexed to, uint value);
    event RejectedPaymentFromBlacklistedAddr(address indexed from, address indexed to, uint value);
    event SetCashback(address indexed addr, int8 rate);
    event Cashback(address indexed from, address indexed to, uint value);
    
    function CrocusCoin(uint _supply, string _name, string _symbol, uint8 _decimals){
        balanceOf[msg.sender= _supply;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _supply;
        owner = msg.sender;
    }
    
    function blacklisting(address _addr) onlyOwner{
        blackList[_addr] = 1;
        Blacklisted(_addr);
    }
    
    function deleteFromBlacklist(address _addr) onlyOwner{
        blackList[_addr] = 0;
        DeleteFromBlacklist(_addr);
    }
    
    function setMembers(Member _members){
        members[msg.sender= Member(_members);
   }
    
    function transfer(address _to, uint _value){
        require(balanceOf[msg.sender>= _value);
        require(balanceOf[_to] + _value >= balanceOf[_to]);
    
        if(blackList[msg.sender> 0){
            RejectedPaymentFromBlacklistedAddr(msg.sender, _to, _value);
        }
        else if(blackList[_to] > 0){
            RejectedPaymentToBlacklistedAddr(msg.sender, _to, _value);
        }
        else{
            uint cashback = 0;
            if(members[_to] > address(0)){
                cashback = _value / 100 * uint(members[_to].getCashackRate(msg.sender));
                members[_to].updateHistory(msg.sender, _value);
            }
        }
        
        balanceOf[msg.sender-= (_value - cashback);
        balanceOf[_to] += (_value - cashback);
        
        Transfer(msg.sender, _to, _value);
        Cashback(_to, msg.sender, cashback);
    }
}



contract CrocusCoin is Owned{
    string public name;
    string public symbol;
    uint8 public decimals;
    uint public totalSupply;
    
    mapping(address => uintpublic balanceOf;
    mapping(address => int8) public blackList;
    mapping(address => Member) public members;
    
    event Transfer(address indexed from, address indexed to, uint value);
    event Blacklisted(address indexed target);
    event DeleteFromBlacklist(address indexed target);
    event RejectedPaymentToBlacklistedAddr(address indexed from, address indexed to, uint value);
    event RejectedPaymentFromBlacklistedAddr(address indexed from, address indexed to, uint value);
    event SetCashback(address indexed addr, int8 rate);
    event Cashback(address indexed from, address indexed to, uint value);
    
    function CrocusCoin(uint _supply, string _name, string _symbol, uint8 _decimals){
        balanceOf[msg.sender= _supply;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _supply;
        owner = msg.sender;
    }


CrocusCoin은 Owned을 상속하고


name은 토큰 이름, symbol은 토큰 단위, decimals은 소수점 이하 자릿수, totalSupply는 토큰 총 발행량을 의미한다.


그리고 balanceOf는 해당하는 주소의 잔고를 의미하고 blackList는 블랙리스트 주소들을, members는 멤버들을 의미한다.



    function CrocusCoin(uint _supply, string _name, string _symbol, uint8 _decimals){
        balanceOf[msg.sender= _supply;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _supply;
        owner = msg.sender;
    }
    
    function blacklisting(address _addr) onlyOwner{
        blackList[_addr] = 1;
        Blacklisted(_addr);
    }
    
    function deleteFromBlacklist(address _addr) onlyOwner{
        blackList[_addr] = 0;
        DeleteFromBlacklist(_addr);
    }


CrocusCoin 생성자에 의해 각 값들이 대입되고


blacklisting 및 deleteFromBlacklist에 의해 블랙리스트를 설정 및 해제할 수 있다.



    function setMembers(Member _members){
        members[msg.sender= Member(_members);
   }
    
    function transfer(address _to, uint _value){
        require(balanceOf[msg.sender>= _value);
        require(balanceOf[_to] + _value >= balanceOf[_to]);
    
        if(blackList[msg.sender> 0){
            RejectedPaymentFromBlacklistedAddr(msg.sender, _to, _value);
        }
        else if(blackList[_to] > 0){
            RejectedPaymentToBlacklistedAddr(msg.sender, _to, _value);
        }
        else{
            uint cashback = 0;
            if(members[_to] > address(0)){
                cashback = _value / 100 * uint(members[_to].getCashackRate(msg.sender));
                members[_to].updateHistory(msg.sender, _value);
            }
        }
        
        balanceOf[msg.sender-= (_value - cashback);
        balanceOf[_to] += (_value - cashback);
        
        Transfer(msg.sender, _to, _value);
        Cashback(_to, msg.sender, cashback);
    }



setMembers에 의해 멤버를 만들어줄 수 있고


transfer은 두 require에 의해 transfer 조건을 판단하게 된다.


아래 if, else if에 의해 보내는 이, 받는 이 둘중 한명이라도 블랙리스트라면 transfer은 불가능 하다.


else부분에 의해 캐시백을 설정하게 되고


아래에 의해 transfer 절차가 이루어진다.







반응형