-
Notifications
You must be signed in to change notification settings - Fork 191
/
Semaphore.sol
131 lines (105 loc) · 4.38 KB
/
Semaphore.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
/*
* semaphorejs - Zero-knowledge signaling on Ethereum
* Copyright (C) 2019 Kobi Gurkan <kobigurk@gmail.com>
*
* This file is part of semaphorejs.
*
* semaphorejs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* semaphorejs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with semaphorejs. If not, see <http://www.gnu.org/licenses/>.
*/
pragma solidity >=0.4.21;
import "./verifier.sol";
import "./MerkleTreeLib.sol";
import "./Ownable.sol";
contract Semaphore is Verifier, MultipleMerkleTree, Ownable {
uint256 public external_nullifier;
uint8 signal_tree_index;
uint8 id_tree_index;
uint8 constant root_history_size = 100;
uint256[root_history_size] root_history;
uint8 current_root_index = 0;
mapping (uint => bool) nullifiers_set;
uint256 reward;
event SignalBroadcast(bytes signal, uint256 nullifiers_hash, uint256 external_nullifier);
uint256 public gas_price_max = 30000000000;
constructor(uint8 tree_levels, uint256 zero_value, uint256 external_nullifier_in, uint256 reward_amount_in_max_gas_price) Ownable() public
{
external_nullifier = external_nullifier_in;
id_tree_index = init_tree(tree_levels, zero_value);
signal_tree_index = init_tree(tree_levels, zero_value);
reward = reward_amount_in_max_gas_price;
}
event Funded(uint256 amount);
function fund() public payable {
emit Funded(msg.value);
}
function insertIdentity(uint256 leaf) public onlyOwner {
insert(id_tree_index, leaf);
root_history[current_root_index++ % root_history_size] = tree_roots[id_tree_index];
}
function updateIdentity(uint256 old_leaf, uint256 leaf, uint32 leaf_index, uint256[] memory old_path, uint256[] memory path) public onlyOwner {
update(id_tree_index, old_leaf, leaf, leaf_index, old_path, path);
root_history[current_root_index++ % root_history_size] = tree_roots[id_tree_index];
}
function broadcastSignal(
bytes memory signal,
uint[2] a,
uint[2][2] b,
uint[2] c,
uint[5] input // (root, nullifiers_hash, signal_hash, external_nullifier, broadcaster_address)
) public {
uint256 start_gas = gasleft();
uint256 signal_hash = uint256(sha256(signal)) >> 8;
require(signal_hash == input[2]);
require(external_nullifier == input[3]);
require(verifyProof(a, b, c, input));
require(nullifiers_set[input[1]] == false);
address broadcaster = address(input[4]);
require(broadcaster == msg.sender);
bool found_root = false;
for (uint8 i = 0; i < root_history_size; i++) {
if (root_history[i] == input[0]) {
found_root = true;
break;
}
}
require(found_root);
insert(signal_tree_index, signal_hash);
nullifiers_set[input[1]] = true;
emit SignalBroadcast(signal, input[1], external_nullifier);
uint256 gas_price = gas_price_max;
if (tx.gasprice < gas_price) {
gas_price = tx.gasprice;
}
uint256 gas_used = start_gas - gasleft();
// pay back gas: 21000 constant cost + gas used + reward
//require((msg.sender).send((21000 + gas_used)*tx.gasprice + reward));
require((msg.sender).send((21000 + gas_used + reward)*gas_price));
//require(msg.sender.send(1 wei));
}
function roots(uint8 tree_index) public view returns (uint256 root) {
root = tree_roots[tree_index];
}
function getIdTreeIndex() public view returns (uint8 index) {
index = id_tree_index;
}
function getSignalTreeIndex() public view returns (uint8 index) {
index = signal_tree_index;
}
function setExternalNullifier(uint256 new_external_nullifier) public onlyOwner {
external_nullifier = new_external_nullifier;
}
function setMaxGasPrice(uint256 new_max_gas_price) public onlyOwner {
gas_price_max = new_max_gas_price;
}
}