-
Notifications
You must be signed in to change notification settings - Fork 0
/
thanostoken.py
146 lines (120 loc) · 6.18 KB
/
thanostoken.py
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
import smartpy as sp
class ALAToken(sp.Contract):
def __init__(self, admin):
self.init(paused = False, ledger = sp.big_map(tvalue = sp.TRecord(approvals = sp.TMap(sp.TAddress, sp.TNat), balance = sp.TNat)), administrator = admin, totalSupply = 0
,contract= sp.set([admin]))
@sp.entry_point
def transfer(self, params):
sp.set_type(params, sp.TRecord(from_ = sp.TAddress, to_ = sp.TAddress, value = sp.TNat).layout(("from_ as from", ("to_ as to", "value"))))
sp.verify((sp.sender == self.data.administrator) |
(~self.data.paused &
((params.from_ == sp.sender) |
(self.data.ledger[params.from_].approvals[sp.sender] >= params.value))))
self.addAddressIfNecessary(params.to_)
sp.verify(self.data.ledger[params.from_].balance >= params.value)
self.data.ledger[params.from_].balance = sp.as_nat(self.data.ledger[params.from_].balance - params.value)
self.data.ledger[params.to_].balance += params.value
sp.if (params.from_ != sp.sender) & (self.data.administrator != sp.sender):
self.data.ledger[params.from_].approvals[sp.sender] = sp.as_nat(self.data.ledger[params.from_].approvals[sp.sender] - params.value)
@sp.entry_point
def approve(self, params):
sp.set_type(params, sp.TRecord(spender = sp.TAddress, value = sp.TNat).layout(("spender", "value")))
sp.verify(~self.data.paused)
alreadyApproved = self.data.ledger[sp.sender].approvals.get(params.spender, 0)
sp.verify((alreadyApproved == 0) | (params.value == 0), "UnsafeAllowanceChange")
self.data.ledger[sp.sender].approvals[params.spender] = params.value
@sp.entry_point
def setPause(self, params):
sp.set_type(params, sp.TBool)
sp.verify(sp.sender == self.data.administrator)
self.data.paused = params
@sp.entry_point
def setAdministrator(self, params):
sp.set_type(params, sp.TAddress)
sp.verify(sp.sender == self.data.administrator)
self.data.administrator = params
@sp.entry_point
def mint(self, params):
sp.verify(params.value>0)
tezValue=sp.tez(sp.as_nat(params.value))
sp.verify(sp.amount == tezValue)
self.addAddressIfNecessary(params.address)
self.data.ledger[params.address].balance += abs(params.value*10000)
self.data.totalSupply += abs(params.value*10000)
@sp.entry_point
def burn(self, params):
sp.set_type(params, sp.TRecord(address = sp.TAddress, value = sp.TNat))
sp.verify(sp.sender == self.data.administrator)
sp.verify(self.data.ledger[params.address].balance >= params.value)
self.data.ledger[params.address].balance = sp.as_nat(self.data.ledger[params.address].balance - params.value)
self.data.totalSupply = sp.as_nat(self.data.totalSupply - params.value)
def addAddressIfNecessary(self, address):
sp.if ~ self.data.ledger.contains(address):
self.data.ledger[address] = sp.record(balance = 0, approvals = {})
@sp.entry_point
def AddContract(self,params):
sp.verify(sp.sender == self.data.administrator)
self.data.contract.add(params)
@sp.entry_point
def LockToken(self,params):
sp.verify(self.data.contract.contains(sp.sender))
sp.verify(self.data.ledger.contains(params.address))
sp.verify(self.data.ledger[params.address].balance >= params.amount)
self.data.ledger[params.address].balance = abs(self.data.ledger[params.address].balance - params.amount)
@sp.entry_point
def UnlockToken(self,params):
sp.verify(self.data.contract.contains(sp.sender))
sp.verify(self.data.ledger.contains(params.address))
self.data.ledger[params.address].balance += params.amount
@sp.entry_point
def withdrawToken(self,params):
sp.verify(params.amount > 0)
sp.verify(self.data.ledger.contains(sp.sender))
sp.verify(self.data.ledger[sp.sender].balance >= params.amount)
self.data.ledger[sp.sender].balance = sp.as_nat(self.data.ledger[sp.sender].balance - params.amount)
self.data.totalSupply = sp.as_nat(self.data.totalSupply - params.amount)
sp.send(sp.sender,sp.mutez(params.amount*100))
@sp.view(sp.TNat)
def getBalance(self, params):
sp.result(self.data.ledger[params].balance)
@sp.view(sp.TNat)
def getAllowance(self, params):
sp.result(self.data.ledger[params.owner].approvals[params.spender])
@sp.view(sp.TNat)
def getTotalSupply(self, params):
sp.set_type(params, sp.TUnit)
sp.result(self.data.totalSupply)
@sp.view(sp.TAddress)
def getAdministrator(self, params):
sp.set_type(params, sp.TUnit)
sp.result(self.data.administrator)
class Viewer(sp.Contract):
def __init__(self, t):
self.init(last = sp.none)
self.init_type(sp.TRecord(last = sp.TOption(t)))
@sp.entry_point
def target(self, params):
self.data.last = sp.some(params)
if "templates" not in __name__:
@sp.add_test(name = "ALA Token")
def test():
scenario = sp.test_scenario()
scenario.h1("FA1.2 template - Fungible assets")
# sp.test_account generates ED25519 key-pairs deterministically:
admin = sp.address("tz1LAWQmxJcnK43vR9G8jsNTzR6b2unZ58NX")
alice = sp.test_account("Alice")
bob = sp.test_account("Robert")
# Let's display the accounts:
scenario.h1("Accounts")
scenario.h1("Contract")
c1 = ALAToken(admin)
scenario.h1("Entry points")
scenario += c1
scenario.h2("Admin mints a few coins")
scenario += c1.mint(address = alice.address, value = 12).run(sender = alice,amount = sp.tez(12))
scenario += c1.mint(address = bob.address, value = 3).run(sender = admin,amount=sp.tez(3))
# scenario += c1.mint(address = alice.address, value = 3).run(sender = admin)
scenario += c1.AddContract(alice.address).run(sender=admin)
scenario += c1.UnlockToken(address=bob.address,amount=100).run(sender=alice)
scenario += c1.LockToken(address=bob.address,amount=100).run(sender=alice)
scenario += c1.withdrawToken(amount=120000).run(sender=alice)