Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio.token.cpp
Go to the documentation of this file.
2
3namespace sysio {
4
5void token::create( const name& issuer,
6 const asset& maximum_supply )
7{
8 require_auth( get_self() );
9
10 auto sym = maximum_supply.symbol;
11 check( maximum_supply.is_valid(), "invalid supply");
12 check( maximum_supply.amount > 0, "max-supply must be positive");
13
14 stats statstable( get_self(), sym.code().raw() );
15 auto existing = statstable.find( sym.code().raw() );
16 check( existing == statstable.end(), "token with symbol already exists" );
17
18 statstable.emplace( get_self(), [&]( auto& s ) {
19 s.supply.symbol = maximum_supply.symbol;
20 s.max_supply = maximum_supply;
21 s.issuer = issuer;
22 });
23}
24
25
26void token::issue( const name& to, const asset& quantity, const string& memo )
27{
28 auto sym = quantity.symbol;
29 check( sym.is_valid(), "invalid symbol name" );
30 check( memo.size() <= 256, "memo has more than 256 bytes" );
31
32 stats statstable( get_self(), sym.code().raw() );
33 auto existing = statstable.find( sym.code().raw() );
34 check( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
35 const auto& st = *existing;
36 check( to == st.issuer, "tokens can only be issued to issuer account" );
37
38 require_auth( st.issuer );
39 check( quantity.is_valid(), "invalid quantity" );
40 check( quantity.amount > 0, "must issue positive quantity" );
41
42 check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
43 check( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");
44
45 statstable.modify( st, same_payer, [&]( auto& s ) {
46 s.supply += quantity;
47 });
48
49 add_balance( st.issuer, quantity, st.issuer );
50}
51
52void token::retire( const asset& quantity, const string& memo )
53{
54 auto sym = quantity.symbol;
55 check( sym.is_valid(), "invalid symbol name" );
56 check( memo.size() <= 256, "memo has more than 256 bytes" );
57
58 stats statstable( get_self(), sym.code().raw() );
59 auto existing = statstable.find( sym.code().raw() );
60 check( existing != statstable.end(), "token with symbol does not exist" );
61 const auto& st = *existing;
62
63 require_auth( st.issuer );
64 check( quantity.is_valid(), "invalid quantity" );
65 check( quantity.amount > 0, "must retire positive quantity" );
66
67 check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
68
69 statstable.modify( st, same_payer, [&]( auto& s ) {
70 s.supply -= quantity;
71 });
72
73 sub_balance( st.issuer, quantity );
74}
75
76void token::transfer( const name& from,
77 const name& to,
78 const asset& quantity,
79 const string& memo )
80{
81 check( from != to, "cannot transfer to self" );
82 require_auth( from );
83 check( is_account( to ), "to account does not exist");
84 auto sym = quantity.symbol.code();
85 stats statstable( get_self(), sym.raw() );
86 const auto& st = statstable.get( sym.raw() );
87
88 require_recipient( from );
89 require_recipient( to );
90
91 check( quantity.is_valid(), "invalid quantity" );
92 check( quantity.amount > 0, "must transfer positive quantity" );
93 check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
94 check( memo.size() <= 256, "memo has more than 256 bytes" );
95
96 auto payer = has_auth( to ) ? to : from;
97
98 sub_balance( from, quantity );
99 add_balance( to, quantity, payer );
100}
101
102void token::sub_balance( const name& owner, const asset& value ) {
103 accounts from_acnts( get_self(), owner.value );
104
105 const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" );
106 check( from.balance.amount >= value.amount, "overdrawn balance" );
107
108 from_acnts.modify( from, owner, [&]( auto& a ) {
109 a.balance -= value;
110 });
111}
112
113void token::add_balance( const name& owner, const asset& value, const name& ram_payer )
114{
115 accounts to_acnts( get_self(), owner.value );
116 auto to = to_acnts.find( value.symbol.code().raw() );
117 if( to == to_acnts.end() ) {
118 to_acnts.emplace( ram_payer, [&]( auto& a ){
119 a.balance = value;
120 });
121 } else {
122 to_acnts.modify( to, same_payer, [&]( auto& a ) {
123 a.balance += value;
124 });
125 }
126}
127
128void token::open( const name& owner, const symbol& symbol, const name& ram_payer )
129{
130 require_auth( ram_payer );
131
132 check( is_account( owner ), "owner account does not exist" );
133
134 auto sym_code_raw = symbol.code().raw();
135 stats statstable( get_self(), sym_code_raw );
136 const auto& st = statstable.get( sym_code_raw, "symbol does not exist" );
137 check( st.supply.symbol == symbol, "symbol precision mismatch" );
138
139 accounts acnts( get_self(), owner.value );
140 auto it = acnts.find( sym_code_raw );
141 if( it == acnts.end() ) {
142 acnts.emplace( ram_payer, [&]( auto& a ){
143 a.balance = asset{0, symbol};
144 });
145 }
146}
147
148void token::close( const name& owner, const symbol& symbol )
149{
150 require_auth( owner );
151 accounts acnts( get_self(), owner.value );
152 auto it = acnts.find( symbol.code().raw() );
153 check( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." );
154 check( it->balance.amount == 0, "Cannot close because the balance is not zero." );
155 acnts.erase( it );
156}
157
158}
std::string name
void close(const name &owner, const symbol &symbol)
void create(const name &issuer, const asset &maximum_supply)
void issue(const name &to, const asset &quantity, const string &memo)
void retire(const asset &quantity, const string &memo)
void transfer(const name &from, const name &to, const asset &quantity, const string &memo)
void open(const name &owner, const symbol &symbol, const name &ram_payer)
#define value
Definition pkcs11.h:157
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
bool is_valid() const
Definition asset.hpp:27
Immutable except for fc::from_variant.
Definition name.hpp:43
char * s