Skip to content

Commit 1845220

Browse files
committed
initial move contract
1 parent 4bb768e commit 1845220

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

spring_token.mvir

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
modules:
2+
3+
module SpringTokenRoles {
4+
5+
resource Owner { }
6+
7+
resource T {
8+
minter: bool,
9+
blacklisted: bool,
10+
}
11+
12+
public publish() {
13+
let sender: address;
14+
sender = get_txn_sender();
15+
16+
if (move(sender) == ${SpringToken_address}) {
17+
Self.grant_owner_role();
18+
}
19+
20+
// Publish a new role with no permissions.
21+
move_to_sender<T>(T{ minter: false, blacklisted: false });
22+
23+
return;
24+
}
25+
26+
// Internal function that grants owner role
27+
grant_owner_role() {
28+
move_to_sender<Owner>(Owner {});
29+
return;
30+
}
31+
32+
// Grants minter role to receiver, if sender is owner.
33+
public grant_minter_role(receiver: address, owner_role: &R#Self.Owner) {
34+
let role_ref: &mut R#Self.T;
35+
36+
release(move(owner_role));
37+
38+
role_ref = borrow_global<T>(move(receiver));
39+
*(&mut move(role_ref).minter) = true;
40+
41+
return;
42+
}
43+
44+
// Grants blacklist role to receiver, but can only succeed if sender owns the owner role.
45+
public grant_blacklisted_role(receiver: address, owner_role: &R#Self.Owner) {
46+
let role_ref: &mut R#Self.T;
47+
48+
release(move(owner_role));
49+
50+
role_ref = borrow_global<T>(move(receiver));
51+
*(&mut move(role_ref).blacklisted) = true;
52+
53+
return;
54+
}
55+
56+
// This returns an immutable reference to the owner role if it exists.
57+
// Is used by the owner to show ownership to privileged functions.
58+
// Reverts if owner role does not exist.
59+
public borrow_owner_role(): &R#Self.Owner {
60+
let sender: address;
61+
let owner_role_ref: &mut R#Self.Owner;
62+
let owner_role_immut_ref: &R#Self.Owner;
63+
64+
sender = get_txn_sender();
65+
owner_role_ref = borrow_global<Owner>(move(sender));
66+
owner_role_immut_ref = freeze(move(owner_role_ref));
67+
68+
return move(owner_role_immut_ref);
69+
}
70+
71+
// This returns an immutable reference to the general role if it exists.
72+
// Should be used by every account to prove their roles.
73+
// Reverts if role does not exist.
74+
public borrow_role(): &R#Self.T {
75+
let sender: address;
76+
let role_ref: &mut R#Self.T;
77+
let role_immut_ref: &R#Self.T;
78+
79+
sender = get_txn_sender();
80+
role_ref = borrow_global<T>(move(sender));
81+
role_immut_ref = freeze(move(role_ref));
82+
83+
return move(role_immut_ref);
84+
}
85+
86+
// Return whether the role allows minting.
87+
public is_minter(role: &R#Self.T): bool {
88+
let is_minter: bool;
89+
is_minter = *(&move(role).minter);
90+
return move(is_minter);
91+
}
92+
93+
// Return true the role is not blacklisted.
94+
public is_not_blacklisted(role: &R#Self.T): bool {
95+
let is_blacklisted: bool;
96+
is_blacklisted = *(&move(role).blacklisted);
97+
return !move(is_blacklisted);
98+
}
99+
100+
// Reverts if role does not allow minting
101+
public require_minter(role: &R#Self.T) {
102+
let is_minter: bool;
103+
is_minter = Self.is_minter(move(role));
104+
assert(move(is_minter), 0);
105+
return;
106+
}
107+
108+
// Reverts if role is blacklisted
109+
public require_not_blacklisted(role: &R#Self.T) {
110+
let is_not_blacklisted: bool;
111+
is_not_blacklisted = Self.is_not_blacklisted(move(role));
112+
assert(move(is_not_blacklisted), 0);
113+
return;
114+
}
115+
}
116+
117+
118+
module SpringToken {
119+
// module for SpringToken.
120+
// will import SprinTokenRoles.
121+
122+
import 0x0.LibraAccount;
123+
import 0x0.LibraCoin;
124+
import Transaction.SpringTokenRoles;
125+
126+
// stors an account's total balance.
127+
resource T {
128+
value: u64,
129+
}
130+
131+
// Publishes an initial zero SpringToken to the sender.
132+
// Should be called once before using this module.
133+
public publish() {
134+
move_to_sender<T>(T{ value: 0 });
135+
return;
136+
}
137+
138+
// Mint new SpringTokens.
139+
// Reverts if not a minter role.
140+
public mint(value: u64, role: &R#SpringTokenRoles.T): R#Self.T {
141+
SpringTokenRoles.require_minter(move(role));
142+
return T{value: move(value)};
143+
}
144+
145+
// Returns an account's SpringToken balance.
146+
// Reverts if an initial SpringToken hasn't been published.
147+
public balance(): u64 {
148+
let sender: address;
149+
let token_ref: &mut R#Self.T;
150+
let token_value: u64;
151+
152+
sender = get_txn_sender();
153+
token_ref = borrow_global<T>(move(sender));
154+
token_value = *(&move(token_ref).value);
155+
156+
return move(token_value);
157+
}
158+
159+
// Reverts if user is blacklisted.
160+
public deposit(payee: address, to_deposit: R#Self.T, role: &R#SpringTokenRoles.T) {
161+
let payee_token_ref: &mut R#Self.T;
162+
let payee_token_value: u64;
163+
let to_deposit_value: u64;
164+
165+
SpringTokenRoles.require_not_blacklisted(move(role));
166+
167+
payee_token_ref = borrow_global<T>(move(payee));
168+
payee_token_value = *(&copy(payee_token_ref).value);
169+
170+
// Unpack and destroy to_deposit tokens
171+
T{ value: to_deposit_value } = move(to_deposit);
172+
173+
// Increase the payees balance with the destroyed token amount
174+
*(&mut move(payee_token_ref).value) = move(payee_token_value) + move(to_deposit_value);
175+
176+
return;
177+
}
178+
179+
// Withdraw an amount of tokens of the sender and return it.
180+
public withdraw(amount: u64, role: &R#SpringTokenRoles.T): R#Self.T {
181+
let sender: address;
182+
let sender_token_ref: &mut R#Self.T;
183+
let value: u64;
184+
185+
SpringTokenRoles.require_not_blacklisted(move(role));
186+
187+
sender = get_txn_sender();
188+
sender_token_ref = borrow_global<T>(move(sender));
189+
value = *(&copy(sender_token_ref).value);
190+
191+
assert(copy(value) >= copy(amount), 1);
192+
193+
*(&mut move(sender_token_ref).value) = move(value) - copy(amount);
194+
return T{ value: move(amount) };
195+
}
196+
197+
public pay_from_sender(payee: address, amount: u64) {
198+
let to_pay: R#Self.T;
199+
let role: &R#SpringTokenRoles.T;
200+
201+
role = SpringTokenRoles.borrow_role();
202+
to_pay = Self.withdraw(move(amount), copy(role));
203+
Self.deposit(move(payee), move(to_pay), move(role));
204+
return;
205+
}
206+
207+
208+
}

0 commit comments

Comments
 (0)