This repository has been archived by the owner on Apr 15, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 68
/
IdentityManager.sol
151 lines (119 loc) · 5.01 KB
/
IdentityManager.sol
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
pragma solidity ^0.4.8;
import "./Proxy.sol";
contract IdentityManager {
event IdentityCreated(
address indexed identity,
address indexed creator,
address owner,
address indexed recoveryKey);
event OwnerAdded(
address indexed identity,
address indexed owner,
address instigator);
event OwnerRemoved(
address indexed identity,
address indexed owner,
address instigator);
event RecoveryChanged(
address indexed identity,
address indexed recoveryKey,
address instigator);
mapping(address => mapping(address => uint)) owners;
mapping(address => address) recoveryKeys;
mapping(address => uint) nonces;
modifier onlyOwner(address identity) {
if (owners[identity][msg.sender] > 0 && (owners[identity][msg.sender] + 1 hours) <= now ) _ ;
else throw;
}
modifier onlyOlderOwner(address identity) {
if (owners[identity][msg.sender] > 0 && (owners[identity][msg.sender] + 1 days) <= now) _ ;
else throw;
}
modifier onlyRecovery(address identity) {
if (recoveryKeys[identity] == msg.sender) _ ;
else throw;
}
// Factory function
// gas 289,311
function CreateIdentity(address owner, address recoveryKey) {
Proxy identity = new Proxy();
owners[identity][owner] = now - 1 days; // This is to ensure original owner has full power from day one
recoveryKeys[identity] = recoveryKey;
IdentityCreated(identity, msg.sender, owner, recoveryKey);
}
function forwardTo(Proxy identity, address destination, uint value, bytes data) onlyOwner(identity) {
identity.forward(destination, value, data);
}
function metaTxForwardTo(uint8 sigV, bytes32 sigR, bytes32 sigS, Proxy identity, address destination, uint value, bytes data) {
uint nonce = nonces[identity];
bytes32 h = sha3(this, 'forwardTo', nonce, identity, destination, value, data);
address addressFromSig = ecrecover(h,sigV,sigR,sigS);
if (owners[identity][addressFromSig] > 0) {
nonces[identity]++;
identity.forward(destination, value, data);
}
}
// an owner can add a new device instantly
function addOwner(Proxy identity, address newOwner) onlyOlderOwner(identity) {
owners[identity][newOwner] = now;
OwnerAdded(identity, newOwner, msg.sender);
}
// an owner can add a new device instantly
function metaTxAddOwner(uint8 sigV, bytes32 sigR, bytes32 sigS, Proxy identity, address newOwner) {
uint nonce = nonces[identity];
bytes32 h = sha3(this, 'addOwner', nonce, identity, newOwner);
address addressFromSig = ecrecover(h,sigV,sigR,sigS);
if (owners[identity][addressFromSig] > 0 && (owners[identity][addressFromSig] + 1 days) <= now) {
nonces[identity]++;
owners[identity][newOwner] = now;
OwnerAdded(identity, newOwner, addressFromSig);
}
}
// a recovery key owner can add a new device with 1 days wait time
function addOwnerForRecovery(Proxy identity, address newOwner) onlyRecovery(identity) {
if (owners[identity][newOwner] > 0) throw;
owners[identity][newOwner] = now + 1 days;
OwnerAdded(identity, newOwner, msg.sender);
}
function metaTxAddOwnerForRecovery(uint8 sigV, bytes32 sigR, bytes32 sigS, Proxy identity, address newOwner) {
uint nonce = nonces[identity];
bytes32 h = sha3(this, 'addOwnerForRecovery', nonce, identity, newOwner);
address addressFromSig = ecrecover(h,sigV,sigR,sigS);
if (owners[identity][newOwner] > 0) throw;
if (recoveryKeys[identity] == addressFromSig) {
nonces[identity]++;
owners[identity][newOwner] = now + 1 days;
OwnerAdded(identity, newOwner, addressFromSig);
}
}
// an owner can remove another owner instantly
function removeOwner(Proxy identity, address owner) onlyOlderOwner(identity) {
owners[identity][owner] = 0;
OwnerRemoved(identity, owner, msg.sender);
}
function metaTxRemoveOwner(uint8 sigV, bytes32 sigR, bytes32 sigS, Proxy identity, address owner) {
uint nonce = nonces[identity];
bytes32 h = sha3(this, 'removeOwner', nonce, identity, owner);
address addressFromSig = ecrecover(h,sigV,sigR,sigS);
if (owners[identity][addressFromSig] > 0 && (owners[identity][addressFromSig] + 1 days) <= now) {
nonces[identity]++;
owners[identity][owner] = 0;
OwnerRemoved(identity, owner, msg.sender);
}
}
// an owner can add change the recoverykey whenever they want to
function changeRecovery(Proxy identity, address recoveryKey) onlyOlderOwner(identity) {
recoveryKeys[identity] = recoveryKey;
RecoveryChanged(identity, recoveryKey, msg.sender);
}
function metaTxChangeRecovery(uint8 sigV, bytes32 sigR, bytes32 sigS, Proxy identity, address recoveryKey) {
uint nonce = nonces[identity];
bytes32 h = sha3(this, 'changeRecovery', nonce, recoveryKey);
address addressFromSig = ecrecover(h,sigV,sigR,sigS);
if (owners[identity][msg.sender] > 0 && (owners[identity][msg.sender] + 1 days) <= now) {
nonces[identity]++;
recoveryKeys[identity] = recoveryKey;
RecoveryChanged(identity, recoveryKey, msg.sender);
}
}
}