-
Notifications
You must be signed in to change notification settings - Fork 0
/
renounce-manager.lua
123 lines (104 loc) · 3.48 KB
/
renounce-manager.lua
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
IsRenounced = IsRenounced or {} -- map process id to boolean
Version = '0.4'
--[[ _OwnershipRenounceManager_ should, by convention, be a simple trusted singleton process on AO.
PREMISE
Its logic is simple and needs to be immutable.
It is deployed with an immediate ownership renouncement (Eval message with "Owner = ''")
=> checking its first message after deployment verifies immutability
=> _OwnershipRenounceManager_ is UNIVERSALLY TRUSTED on AO
FUNCTION
Any process owner that wants to perform a verifiable ownership renouncement on their process
would first set that process' `Owner` to _OwnerhipRenounceManager_ (this),
then send a message ('Action' = 'MakeRenounce') to it.
For the purpose of this scenario, we call the other process _Renouncer_.
_OwnerhipRenounceManager_ would send an `Eval` to install a new handler on _Renouncer_,
which would revoke ownership when triggered.
The installed handler is also marked with a nonce that is partly random, partly specific
to the current time.
=> The nonce cannot be known beforehand by _Renouncer_.
Additionally to ownership renouncement, the installed handler would SEND A MESSAGE WITH THE NONCE
back to the _OwnerhipRenounceManager_, thereby proving that has executed the handler installed
specifically for this purpose.
]]
-- Trustable way to publicly verify that a particular process has had its ownership renounced
-- via this _RenounceManager_
Handlers.add(
'isRenounced',
Handlers.utils.hasMatchingTag('Action', 'IsRenounced'),
function(msg)
ao.send({
Target = msg.From,
IsRenounced = tostring(IsRenounced[msg.Tags.ProcessID] or false)
})
end
)
Nonces = Nonces or {} -- map process id to nonce
local createEvalText = function(nonce)
return [[
Handlers.add(
'renounceOwnership',
Handlers.utils.hasMatchingTag('Action', 'RenounceOwnership'),
function(msg)
Owner = ''
ao.send({
Target = ']] .. ao.id .. [[',
Action = 'Renounced',
Nonce = ']] .. nonce .. [['
})
Handlers.prepend(
'ensureRenounced',
function() return 'continue' end,
function()
assert(Owner == '', 'This contract is supposed to have its ownership renounced')
end
)
end
)
ao.send({
Target = ']] .. ao.id .. [[',
Action = 'Ack',
Nonce = ']] .. nonce .. [['
})
]]
end
-- Sent by any _Renouncer_
Handlers.add(
'makeRenounce',
Handlers.utils.hasMatchingTag('Action', 'MakeRenounce'),
function(msg)
local targetProcess = msg.From
-- this process is the owner of the target process right now
local nonce = tostring(msg.Timestamp) .. '-' .. tostring(math.random(1, 1000000))
Nonces[msg.From] = nonce
ao.send({
Target = targetProcess,
Action = 'Eval',
Data = createEvalText(nonce)
})
end
)
-- _Renouncer_ acknowledges that it has installed the renouncement Handler
Handlers.add(
'ack',
Handlers.utils.hasMatchingTag('Action', 'Ack'),
function(msg)
if msg.Tags.Nonce == Nonces[msg.From] then
ao.send({ Target = msg.From, Action = 'RenounceOwnership' })
end
end
)
-- Persist Renouncement
Handlers.add(
'renounced',
Handlers.utils.hasMatchingTag('Action', 'Renounced'),
function(msg)
if msg.Tags.Nonce == Nonces[msg.From] then
IsRenounced[msg.From] = true
ao.send({
Target = ao.id,
Event = 'RenounceOwnership',
ProcessID = msg.From
})
end
end
)