-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinheritance.cpp
193 lines (146 loc) · 5.83 KB
/
inheritance.cpp
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <eosiolib/eosio.hpp>
#include <eosiolib/multi_index.hpp>
using namespace eosio;
struct heir_rec {
uint64_t pkey;
// heir's name
account_name name;
// testator's name
account_name testator;
// heir's share in inheritance (percent, int from 0 to 100)
uint8_t share;
bool is_testator_dead;
uint64_t primary_key()const { return pkey; }
account_name get_testator()const { return testator; }
uint8_t get_share()const {return share; }
EOSLIB_SERIALIZE( heir_rec, (pkey)(name)(testator) )
};
struct authority_rec {
// authoritie's name
account_name name;
// reputation of authority (grows with quantity of approved deaths)
uint64_t reputation;
uint64_t pledge;
account_name primary_key()const { return name; }
EOSLIB_SERIALIZE( authority_rec, (name)(reputation) )
};
struct testator_rec {
// testator's name
account_name name;
// authority, which approved testator death, 0 if testator is alive
account_name authority;
account_name primary_key()const { return name; }
EOSLIB_SERIALIZE( testator_rec, (name) )
};
typedef multi_index<N(heirs), heir_rec, indexed_by< N(bytestator), const_mem_fun<heir_rec, account_name, &heir_rec::get_testator>>> heir_table_type;
static const account_name code_account = N(inheritance_account);
class inheritance : public contract {
public:
// using contract::contract;
inheritance( account_name self )
:contract(self),authorities_table(_self, _self),testators_table(_self, _self){};
multi_index<N(authorities), authority_rec> authorities_table;
multi_index<N(testators), testator_rec> testators_table;
/*
To check contract
*/
// @abi action
void debugfunc( account_name from, account_name to, uint64_t amount ) {
auto header = "======== debugfunc ========";
print( header, "\n" );
print( eosio::name{_self}, "\n" );
print( "from = ", from, " to = ", to, " amount = ", amount, "\n" );
print( "from = ", eosio::name{from}, " to = ", eosio::name{to}, " amount = ", amount, "\n" );
}
// @abi_action
void addheir(account_name testator, account_name heir) {
auto header = "======== add_heir function ========";
print(header, "\n" );
heir_table_type heir_table( code_account, testator );
eosio_assert(testator == _self, "you can't add heir to another person!");
heir_table.emplace(testator, [&]( auto& h_rec ) {
h_rec.pkey = heir_table.available_primary_key();
h_rec.name = heir;
h_rec.testator = testator;
h_rec.share = 0;
// h_rec.is_testator_dead = false;
});
}
/*
Claim that account_name is dead (run by one of the heirs)
*/
// @abi_action
void claimdead(account_name testator) {
auto header = "======== claim_dead function ========";
bool authorised = false;
print(header, "\n" );
heir_table_type heir_table( code_account, testator );
auto testator_index = heir_table.template get_index<N(bytestator)>();
auto testator_itr = testator_index.find(testator);
eosio_assert(testator_itr == testator_index.end(), "is not registered as testator");
while (testator_itr != testator_index.end() && testator_itr->testator == testator) {
if (_self != testator_itr->name) {
testator_itr++;
}
else {
authorised = true;
}
}
// Nobody but heirs has right to claim that testator is dead!
eosio_assert(authorised == false, "run not by one of the heirs");
heir_table.modify(testator_itr, 0, [&]( auto& h_rec ) {
h_rec.is_testator_dead = true;
});
print(eosio::name{_self}, " claims that ", eosio::name{testator}, " is dead!");
}
/*
Claim that account_name owner is alive (run by account_name owner)
*/
// @abi_action
void claimalive() {
auto header = "======== claim_alive function ========";
print(header, "\n" );
eosio_assert( is_dead(eosio::name{_self}) == false, "the guy is actually alive" );
// todo add check that _self considered dead
print(eosio::name{_self}, " claims that he is alive!");
account_name testator_name = eosio::name{_self};
auto testator_itr = testators_table.find(testator_name);
eosio_assert(testator_itr == testators_table.end(), "testator not found");
auto authority_itr = authorities_table.find(testator_itr->authority);
eosio_assert(authority_itr != authorities_table.end(), "authority not found");
// punishment for authority to claim that alive person is dead.
authorities_table.modify(authority_itr, 0, [&]( auto& a_rec ) {
a_rec.reputation = 0;
});
}
/*
Prove that account_name owner is dead (run by witness/autority with rights to do that)
and send inheritance to testator's heirs.
TODO User permissions on ActiveKey
*/
// @abi_action
void sendinheritance(account_name testator) {
auto header = "======== send_inheritance function ========";
print(header, "\n" );
// todo permissions check
// todo majority check
// ask to permission
// action(
// permission_level{ from, N(active) },
// N(eosio.token), N(transfer),
// std::make_tuple(from, _self, testator.balance, std::string(""))
// ).send();
// autothority reward
authorities_table.modify(authority_itr, 0, [&]( auto& a_rec ) {
a_rec.reputation += 1;
});
}
private:
bool is_dead(account_name testator) {
heir_table_type heir_table( current_receiver(), testator );
auto testator_index = heir_table.template get_index<N(bytestator)>();
auto testator_itr = testator_index.find(testator);
eosio_assert(testator_itr != testator_index.end(), "is not registered as testator");
}
};
EOSIO_ABI( inheritance, (debugfunc)(claimdead) )