-
Notifications
You must be signed in to change notification settings - Fork 74
/
Multisig Wallet—TEST
208 lines (169 loc) · 5.35 KB
/
Multisig Wallet—TEST
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
pragma solidity ^0.8.15;
contract MultiSigWallet {
// 存钱 记录
event Deposit(address indexed sender, uint amount, uint balance);
// 提交交易 记录
event SubmitTransaction(
address indexed owner,
uint indexed txIndex,
address indexed to,
uint value,
bytes data
);
// 确认交易 记录
event ConfirmTransaction(address indexed owner, uint indexed txIndex);
// 驳回交易 记录
event RevokeConfirmation(address indexed owner, uint indexed txIndex);
// 执行交易 记录
event ExecuteTransaction(address indexed owner, uint indexed txIndex);
// 多签成员
address[] public owners;
mapping(address => bool) public isOwner;
// 交易多签通过 人数
uint public numConfirmationsRequired;
// 交易数据
struct Transaction {
address to;
uint value;
bytes data;
bool executed;
uint numConfirmations;
}
// mapping from tx index => owner => bool 每个多签者确认情况
mapping(uint => mapping(address => bool)) public isConfirmed;
// 全部交易数据
Transaction[] public transactions;
modifier onlyOwner() {
require(isOwner[msg.sender], "not owner");
_;
}
// 交易存在
modifier txExists(uint _txIndex) {
require(_txIndex < transactions.length, "tx does not exist");
_;
}
// 交易未执行
modifier notExecuted(uint _txIndex) {
require(!transactions[_txIndex].executed, "tx already executed");
_;
}
// 交易未确认
modifier notConfirmed(uint _txIndex) {
require(!isConfirmed[_txIndex][msg.sender], "tx already confirmed");
_;
}
// 初始化, 设置好签名者, 还有签名通过权重
constructor(address[] memory _owners, uint _numConfirmationsRequired) {
require(_owners.length > 0, "owners required");
require(
_numConfirmationsRequired > 0 &&
_numConfirmationsRequired <= _owners.length,
"invalid number of required confirmations"
);
//
for (uint i = 0; i < _owners.length; i++) {
address owner = _owners[i];
require(owner != address(0), "invalid owner");
require(!isOwner[owner], "owner not unique"); // 确保签名者 不重复
isOwner[owner] = true;
owners.push(owner);
}
numConfirmationsRequired = _numConfirmationsRequired;
}
// 实现 receive 函数, 可接受 ETH
receive() external payable {
emit Deposit(msg.sender, msg.value, address(this).balance);
}
// 提交交易
function submitTransaction(
address _to,
uint _value,
bytes memory _data
) public onlyOwner {
uint txIndex = transactions.length;
transactions.push(
Transaction({
to: _to,
value: _value,
data: _data,
executed: false,
numConfirmations: 0
})
);
emit SubmitTransaction(msg.sender, txIndex, _to, _value, _data);
}
// 确认交易
function confirmTransaction(uint _txIndex)
public
onlyOwner
txExists(_txIndex)
notExecuted(_txIndex)
notConfirmed(_txIndex)
{
Transaction storage transaction = transactions[_txIndex];
transaction.numConfirmations += 1;
isConfirmed[_txIndex][msg.sender] = true;
emit ConfirmTransaction(msg.sender, _txIndex);
}
// 执行交易
function executeTransaction(uint _txIndex)
public
onlyOwner
txExists(_txIndex)
notExecuted(_txIndex)
{
Transaction storage transaction = transactions[_txIndex];
require(
transaction.numConfirmations >= numConfirmationsRequired,
"cannot execute tx"
);
transaction.executed = true;
(bool success, ) = transaction.to.call{value: transaction.value}(
transaction.data
);
require(success, "tx failed");
emit ExecuteTransaction(msg.sender, _txIndex);
}
// 驳回交易
function revokeConfirmation(uint _txIndex)
public
onlyOwner
txExists(_txIndex)
notExecuted(_txIndex)
{
Transaction storage transaction = transactions[_txIndex];
require(isConfirmed[_txIndex][msg.sender], "tx not confirmed");
transaction.numConfirmations -= 1;
isConfirmed[_txIndex][msg.sender] = false;
emit RevokeConfirmation(msg.sender, _txIndex);
}
// 获得多签者
function getOwners() public view returns (address[] memory) {
return owners;
}
// 获得交易数量
function getTransactionCount() public view returns (uint) {
return transactions.length;
}
// 获得交易
function getTransaction(uint _txIndex)
public
view
returns (
address to,
uint value,
bytes memory data,
bool executed,
uint numConfirmations
)
{
Transaction storage transaction = transactions[_txIndex];
return (
transaction.to,
transaction.value,
transaction.data,
transaction.executed,
transaction.numConfirmations
);
}
}