gun-eth 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. package/SHINE.json +262 -0
  2. package/SHINE.sol +35 -31
  3. package/index.js +74 -173
  4. package/package.json +1 -1
package/SHINE.json ADDED
@@ -0,0 +1,262 @@
1
+ {
2
+ "address": "0x43D838b683F772F08f321E5FA265ad3e333BE9C2",
3
+ "abi": [
4
+ {
5
+ "anonymous": false,
6
+ "inputs": [
7
+ {
8
+ "indexed": true,
9
+ "internalType": "bytes",
10
+ "name": "nodeId",
11
+ "type": "bytes"
12
+ },
13
+ {
14
+ "indexed": false,
15
+ "internalType": "bytes32",
16
+ "name": "contentHash",
17
+ "type": "bytes32"
18
+ },
19
+ {
20
+ "indexed": false,
21
+ "internalType": "address",
22
+ "name": "updater",
23
+ "type": "address"
24
+ }
25
+ ],
26
+ "name": "DataUpdated",
27
+ "type": "event"
28
+ },
29
+ {
30
+ "inputs": [
31
+ {
32
+ "internalType": "bytes[]",
33
+ "name": "nodeIds",
34
+ "type": "bytes[]"
35
+ },
36
+ {
37
+ "internalType": "bytes32[]",
38
+ "name": "contentHashes",
39
+ "type": "bytes32[]"
40
+ }
41
+ ],
42
+ "name": "batchUpdateData",
43
+ "outputs": [],
44
+ "stateMutability": "nonpayable",
45
+ "type": "function"
46
+ },
47
+ {
48
+ "inputs": [
49
+ {
50
+ "internalType": "bytes",
51
+ "name": "nodeId",
52
+ "type": "bytes"
53
+ }
54
+ ],
55
+ "name": "getLatestRecord",
56
+ "outputs": [
57
+ {
58
+ "internalType": "bytes32",
59
+ "name": "",
60
+ "type": "bytes32"
61
+ },
62
+ {
63
+ "internalType": "uint256",
64
+ "name": "",
65
+ "type": "uint256"
66
+ },
67
+ {
68
+ "internalType": "address",
69
+ "name": "",
70
+ "type": "address"
71
+ }
72
+ ],
73
+ "stateMutability": "view",
74
+ "type": "function"
75
+ },
76
+ {
77
+ "inputs": [
78
+ {
79
+ "internalType": "bytes",
80
+ "name": "",
81
+ "type": "bytes"
82
+ }
83
+ ],
84
+ "name": "nodeData",
85
+ "outputs": [
86
+ {
87
+ "internalType": "bytes32",
88
+ "name": "contentHash",
89
+ "type": "bytes32"
90
+ },
91
+ {
92
+ "internalType": "uint256",
93
+ "name": "timestamp",
94
+ "type": "uint256"
95
+ },
96
+ {
97
+ "internalType": "address",
98
+ "name": "updater",
99
+ "type": "address"
100
+ }
101
+ ],
102
+ "stateMutability": "view",
103
+ "type": "function"
104
+ },
105
+ {
106
+ "inputs": [
107
+ {
108
+ "internalType": "bytes",
109
+ "name": "nodeId",
110
+ "type": "bytes"
111
+ },
112
+ {
113
+ "internalType": "bytes32",
114
+ "name": "contentHash",
115
+ "type": "bytes32"
116
+ }
117
+ ],
118
+ "name": "updateData",
119
+ "outputs": [],
120
+ "stateMutability": "nonpayable",
121
+ "type": "function"
122
+ },
123
+ {
124
+ "inputs": [
125
+ {
126
+ "internalType": "bytes",
127
+ "name": "nodeId",
128
+ "type": "bytes"
129
+ },
130
+ {
131
+ "internalType": "bytes32",
132
+ "name": "contentHash",
133
+ "type": "bytes32"
134
+ }
135
+ ],
136
+ "name": "verifyData",
137
+ "outputs": [
138
+ {
139
+ "internalType": "bool",
140
+ "name": "",
141
+ "type": "bool"
142
+ },
143
+ {
144
+ "internalType": "uint256",
145
+ "name": "",
146
+ "type": "uint256"
147
+ },
148
+ {
149
+ "internalType": "address",
150
+ "name": "",
151
+ "type": "address"
152
+ }
153
+ ],
154
+ "stateMutability": "view",
155
+ "type": "function"
156
+ }
157
+ ],
158
+ "transactionHash": "0xc00b134812b2cb32d6a412fd1d1a4c9661777b0ee29ed0ff05b09c7c0b1f6f0d",
159
+ "receipt": {
160
+ "to": null,
161
+ "from": "0x8aA5F726d9F868a21a8bd748E2f1E43bA31eb670",
162
+ "contractAddress": "0x43D838b683F772F08f321E5FA265ad3e333BE9C2",
163
+ "transactionIndex": 2,
164
+ "gasUsed": "419514",
165
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
166
+ "blockHash": "0xc8bd27a2f9bf4ec35e2c61c2c2e62b47b70aa10f587ea48d4802611c36116dd6",
167
+ "transactionHash": "0xc00b134812b2cb32d6a412fd1d1a4c9661777b0ee29ed0ff05b09c7c0b1f6f0d",
168
+ "logs": [],
169
+ "blockNumber": 17723163,
170
+ "cumulativeGasUsed": "551282",
171
+ "status": 1,
172
+ "byzantium": true
173
+ },
174
+ "args": [],
175
+ "numDeployments": 4,
176
+ "solcInputHash": "40cece70198a47ff2f958bd8d77d352d",
177
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"name\":\"DataUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"nodeIds\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"contentHashes\",\"type\":\"bytes32[]\"}],\"name\":\"batchUpdateData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"}],\"name\":\"getLatestRecord\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"nodeData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"}],\"name\":\"updateData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"}],\"name\":\"verifyData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SHINE.sol\":\"SHINE\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SHINE.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.8.0;\\r\\n\\r\\ncontract SHINE {\\r\\n\\tstruct DataRecord {\\r\\n\\t\\tbytes32 contentHash;\\r\\n\\t\\tuint256 timestamp;\\r\\n\\t\\taddress updater;\\r\\n\\t}\\r\\n\\r\\n\\tmapping(bytes => DataRecord) public nodeData;\\r\\n\\r\\n\\tevent DataUpdated(\\r\\n\\t\\tbytes indexed nodeId,\\r\\n\\t\\tbytes32 contentHash,\\r\\n\\t\\taddress updater\\r\\n\\t);\\r\\n\\r\\n\\tfunction updateData(bytes memory nodeId, bytes32 contentHash) public {\\r\\n\\t\\tnodeData[nodeId] = DataRecord(contentHash, block.timestamp, msg.sender);\\r\\n\\t\\temit DataUpdated(nodeId, contentHash, msg.sender);\\r\\n\\t}\\r\\n\\r\\n\\tfunction verifyData(\\r\\n\\t\\tbytes memory nodeId,\\r\\n\\t\\tbytes32 contentHash\\r\\n\\t) public view returns (bool, uint256, address) {\\r\\n\\t\\tDataRecord memory record = nodeData[nodeId];\\r\\n\\t\\tbool isValid = record.contentHash == contentHash;\\r\\n\\t\\treturn (isValid, record.timestamp, record.updater);\\r\\n\\t}\\r\\n\\r\\n\\tfunction getLatestRecord(\\r\\n\\t\\tbytes memory nodeId\\r\\n\\t) public view returns (bytes32, uint256, address) {\\r\\n\\t\\tDataRecord memory record = nodeData[nodeId];\\r\\n\\t\\treturn (record.contentHash, record.timestamp, record.updater);\\r\\n\\t}\\r\\n\\r\\n\\tfunction batchUpdateData(\\r\\n\\t\\tbytes[] memory nodeIds,\\r\\n\\t\\tbytes32[] memory contentHashes\\r\\n\\t) public {\\r\\n\\t\\trequire(\\r\\n\\t\\t\\tnodeIds.length == contentHashes.length,\\r\\n\\t\\t\\t\\\"Arrays length mismatch\\\"\\r\\n\\t\\t);\\r\\n\\t\\tfor (uint i = 0; i < nodeIds.length; i++) {\\r\\n\\t\\t\\tupdateData(nodeIds[i], contentHashes[i]);\\r\\n\\t\\t}\\r\\n\\t}\\r\\n}\\r\\n\",\"keccak256\":\"0x1ed77b1882586a77f3e6d5bf176009c5f00b9d91f71cfd6153ca2d57ef30831d\",\"license\":\"MIT\"}},\"version\":1}",
178
+ "bytecode": "0x608060405234801561001057600080fd5b506106a0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80630d36830e1461005c5780630f07e48514610071578063d236feda14610084578063d54193d7146100c2578063d58a3de3146100f9575b600080fd5b61006f61006a3660046104a8565b61013c565b005b61006f61007f36600461057c565b6101e9565b61009761009236600461057c565b6102a2565b60408051931515845260208401929092526001600160a01b0316908201526060015b60405180910390f35b6100d56100d03660046105c1565b610302565b6040805193845260208401929092526001600160a01b0316908201526060016100b9565b6100d56101073660046105c1565b80516020818301810180516000825292820191909301209152805460018201546002909201549091906001600160a01b031683565b805182511461018a5760405162461bcd60e51b8152602060048201526016602482015275082e4e4c2f2e640d8cadccee8d040dad2e6dac2e8c6d60531b604482015260640160405180910390fd5b60005b82518110156101e4576101d28382815181106101ab576101ab6105fe565b60200260200101518383815181106101c5576101c56105fe565b60200260200101516101e9565b806101dc81610614565b91505061018d565b505050565b604080516060810182528281524260208201523381830152905160009061021190859061063b565b908152604080516020928190038301812084518155928401516001840155920151600290910180546001600160a01b0319166001600160a01b0390921691909117905561025f90839061063b565b60408051918290038220838352336020840152917fac3d4f3cbf6818c9329b6b8c61e41d9dc52fc1cc580fff6af273be3ebc1d423f910160405180910390a25050565b6000806000806000866040516102b8919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529614979096509350505050565b600080600080600085604051610318919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529097919650945092505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156103a1576103a1610362565b604052919050565b600067ffffffffffffffff8211156103c3576103c3610362565b5060051b60200190565b600082601f8301126103de57600080fd5b813567ffffffffffffffff8111156103f8576103f8610362565b61040b601f8201601f1916602001610378565b81815284602083860101111561042057600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261044e57600080fd5b8135602061046361045e836103a9565b610378565b82815260059290921b8401810191818101908684111561048257600080fd5b8286015b8481101561049d5780358352918301918301610486565b509695505050505050565b600080604083850312156104bb57600080fd5b823567ffffffffffffffff808211156104d357600080fd5b818501915085601f8301126104e757600080fd5b813560206104f761045e836103a9565b82815260059290921b8401810191818101908984111561051657600080fd5b8286015b8481101561054e578035868111156105325760008081fd5b6105408c86838b01016103cd565b84525091830191830161051a565b509650508601359250508082111561056557600080fd5b506105728582860161043d565b9150509250929050565b6000806040838503121561058f57600080fd5b823567ffffffffffffffff8111156105a657600080fd5b6105b2858286016103cd565b95602094909401359450505050565b6000602082840312156105d357600080fd5b813567ffffffffffffffff8111156105ea57600080fd5b6105f6848285016103cd565b949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161063457634e487b7160e01b600052601160045260246000fd5b5060010190565b6000825160005b8181101561065c5760208186018101518583015201610642565b50600092019182525091905056fea2646970667358221220c3ea212644c861f0e892deb0129df945a7fa2af5971e51e4b97810c73fc547f764736f6c63430008110033",
179
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c80630d36830e1461005c5780630f07e48514610071578063d236feda14610084578063d54193d7146100c2578063d58a3de3146100f9575b600080fd5b61006f61006a3660046104a8565b61013c565b005b61006f61007f36600461057c565b6101e9565b61009761009236600461057c565b6102a2565b60408051931515845260208401929092526001600160a01b0316908201526060015b60405180910390f35b6100d56100d03660046105c1565b610302565b6040805193845260208401929092526001600160a01b0316908201526060016100b9565b6100d56101073660046105c1565b80516020818301810180516000825292820191909301209152805460018201546002909201549091906001600160a01b031683565b805182511461018a5760405162461bcd60e51b8152602060048201526016602482015275082e4e4c2f2e640d8cadccee8d040dad2e6dac2e8c6d60531b604482015260640160405180910390fd5b60005b82518110156101e4576101d28382815181106101ab576101ab6105fe565b60200260200101518383815181106101c5576101c56105fe565b60200260200101516101e9565b806101dc81610614565b91505061018d565b505050565b604080516060810182528281524260208201523381830152905160009061021190859061063b565b908152604080516020928190038301812084518155928401516001840155920151600290910180546001600160a01b0319166001600160a01b0390921691909117905561025f90839061063b565b60408051918290038220838352336020840152917fac3d4f3cbf6818c9329b6b8c61e41d9dc52fc1cc580fff6af273be3ebc1d423f910160405180910390a25050565b6000806000806000866040516102b8919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529614979096509350505050565b600080600080600085604051610318919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529097919650945092505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156103a1576103a1610362565b604052919050565b600067ffffffffffffffff8211156103c3576103c3610362565b5060051b60200190565b600082601f8301126103de57600080fd5b813567ffffffffffffffff8111156103f8576103f8610362565b61040b601f8201601f1916602001610378565b81815284602083860101111561042057600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261044e57600080fd5b8135602061046361045e836103a9565b610378565b82815260059290921b8401810191818101908684111561048257600080fd5b8286015b8481101561049d5780358352918301918301610486565b509695505050505050565b600080604083850312156104bb57600080fd5b823567ffffffffffffffff808211156104d357600080fd5b818501915085601f8301126104e757600080fd5b813560206104f761045e836103a9565b82815260059290921b8401810191818101908984111561051657600080fd5b8286015b8481101561054e578035868111156105325760008081fd5b6105408c86838b01016103cd565b84525091830191830161051a565b509650508601359250508082111561056557600080fd5b506105728582860161043d565b9150509250929050565b6000806040838503121561058f57600080fd5b823567ffffffffffffffff8111156105a657600080fd5b6105b2858286016103cd565b95602094909401359450505050565b6000602082840312156105d357600080fd5b813567ffffffffffffffff8111156105ea57600080fd5b6105f6848285016103cd565b949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161063457634e487b7160e01b600052601160045260246000fd5b5060010190565b6000825160005b8181101561065c5760208186018101518583015201610642565b50600092019182525091905056fea2646970667358221220c3ea212644c861f0e892deb0129df945a7fa2af5971e51e4b97810c73fc547f764736f6c63430008110033",
180
+ "devdoc": {
181
+ "kind": "dev",
182
+ "methods": {},
183
+ "version": 1
184
+ },
185
+ "userdoc": {
186
+ "kind": "user",
187
+ "methods": {},
188
+ "version": 1
189
+ },
190
+ "storageLayout": {
191
+ "storage": [
192
+ {
193
+ "astId": 13,
194
+ "contract": "contracts/SHINE.sol:SHINE",
195
+ "label": "nodeData",
196
+ "offset": 0,
197
+ "slot": "0",
198
+ "type": "t_mapping(t_bytes_memory_ptr,t_struct(DataRecord)8_storage)"
199
+ }
200
+ ],
201
+ "types": {
202
+ "t_address": {
203
+ "encoding": "inplace",
204
+ "label": "address",
205
+ "numberOfBytes": "20"
206
+ },
207
+ "t_bytes32": {
208
+ "encoding": "inplace",
209
+ "label": "bytes32",
210
+ "numberOfBytes": "32"
211
+ },
212
+ "t_bytes_memory_ptr": {
213
+ "encoding": "bytes",
214
+ "label": "bytes",
215
+ "numberOfBytes": "32"
216
+ },
217
+ "t_mapping(t_bytes_memory_ptr,t_struct(DataRecord)8_storage)": {
218
+ "encoding": "mapping",
219
+ "key": "t_bytes_memory_ptr",
220
+ "label": "mapping(bytes => struct SHINE.DataRecord)",
221
+ "numberOfBytes": "32",
222
+ "value": "t_struct(DataRecord)8_storage"
223
+ },
224
+ "t_struct(DataRecord)8_storage": {
225
+ "encoding": "inplace",
226
+ "label": "struct SHINE.DataRecord",
227
+ "members": [
228
+ {
229
+ "astId": 3,
230
+ "contract": "contracts/SHINE.sol:SHINE",
231
+ "label": "contentHash",
232
+ "offset": 0,
233
+ "slot": "0",
234
+ "type": "t_bytes32"
235
+ },
236
+ {
237
+ "astId": 5,
238
+ "contract": "contracts/SHINE.sol:SHINE",
239
+ "label": "timestamp",
240
+ "offset": 0,
241
+ "slot": "1",
242
+ "type": "t_uint256"
243
+ },
244
+ {
245
+ "astId": 7,
246
+ "contract": "contracts/SHINE.sol:SHINE",
247
+ "label": "updater",
248
+ "offset": 0,
249
+ "slot": "2",
250
+ "type": "t_address"
251
+ }
252
+ ],
253
+ "numberOfBytes": "96"
254
+ },
255
+ "t_uint256": {
256
+ "encoding": "inplace",
257
+ "label": "uint256",
258
+ "numberOfBytes": "32"
259
+ }
260
+ }
261
+ }
262
+ }
package/SHINE.sol CHANGED
@@ -2,47 +2,51 @@
2
2
  pragma solidity ^0.8.0;
3
3
 
4
4
  contract SHINE {
5
- struct DataInfo {
6
- bool exists;
7
- address storer;
8
- bytes nodeId;
5
+ struct DataRecord {
6
+ bytes32 contentHash;
7
+ uint256 timestamp;
8
+ address updater;
9
9
  }
10
10
 
11
- mapping(bytes32 => DataInfo) public dataHashes;
11
+ mapping(bytes => DataRecord) public nodeData;
12
12
 
13
- event DataHashStored(
14
- bytes32 indexed dataHash,
15
- address indexed storer,
16
- bytes nodeId
13
+ event DataUpdated(
14
+ bytes indexed nodeId,
15
+ bytes32 contentHash,
16
+ address updater
17
17
  );
18
18
 
19
- function storeDataHash(
20
- bytes32 dataHash,
21
- bytes memory nodeId
22
- ) public returns (bytes memory, bytes32) {
23
- require(!dataHashes[dataHash].exists, "Hash already stored");
24
- dataHashes[dataHash] = DataInfo(true, msg.sender, nodeId);
25
- emit DataHashStored(dataHash, msg.sender, nodeId);
26
- return (nodeId, dataHash);
19
+ function updateData(bytes memory nodeId, bytes32 contentHash) public {
20
+ nodeData[nodeId] = DataRecord(contentHash, block.timestamp, msg.sender);
21
+ emit DataUpdated(nodeId, contentHash, msg.sender);
22
+ }
23
+
24
+ function verifyData(
25
+ bytes memory nodeId,
26
+ bytes32 contentHash
27
+ ) public view returns (bool, uint256, address) {
28
+ DataRecord memory record = nodeData[nodeId];
29
+ bool isValid = record.contentHash == contentHash;
30
+ return (isValid, record.timestamp, record.updater);
27
31
  }
28
32
 
29
- function verifyDataHash(
30
- bytes32 dataHash
31
- ) public view returns (bool exists, address storer, bytes memory nodeId) {
32
- DataInfo memory info = dataHashes[dataHash];
33
- return (info.exists, info.storer, info.nodeId);
33
+ function getLatestRecord(
34
+ bytes memory nodeId
35
+ ) public view returns (bytes32, uint256, address) {
36
+ DataRecord memory record = nodeData[nodeId];
37
+ return (record.contentHash, record.timestamp, record.updater);
34
38
  }
35
39
 
36
- function batchStoreDataHashes(
37
- bytes32[] memory hashes,
38
- bytes[] memory nodeIds
40
+ function batchUpdateData(
41
+ bytes[] memory nodeIds,
42
+ bytes32[] memory contentHashes
39
43
  ) public {
40
- require(hashes.length == nodeIds.length, "Arrays length mismatch");
41
- for (uint i = 0; i < hashes.length; i++) {
42
- if (!dataHashes[hashes[i]].exists) {
43
- dataHashes[hashes[i]] = DataInfo(true, msg.sender, nodeIds[i]);
44
- emit DataHashStored(hashes[i], msg.sender, nodeIds[i]);
45
- }
44
+ require(
45
+ nodeIds.length == contentHashes.length,
46
+ "Arrays length mismatch"
47
+ );
48
+ for (uint i = 0; i < nodeIds.length; i++) {
49
+ updateData(nodeIds[i], contentHashes[i]);
46
50
  }
47
51
  }
48
52
  }
package/index.js CHANGED
@@ -2,6 +2,12 @@ const Gun = require("gun/gun");
2
2
  const SEA = require("gun/sea");
3
3
  const ethers = require("ethers");
4
4
 
5
+ const SHINE = require("./SHINE.json");
6
+ const SHINE_ABI = SHINE.abi;
7
+ const SHINE_OPTIMISM_SEPOLIA = SHINE.address;
8
+
9
+ let SHINE_CONTRACT_ADDRESS;
10
+
5
11
  // Aggiungi il metodo alla catena di Gun
6
12
  Gun.chain.verifySignature = async function (message, signature) {
7
13
  try {
@@ -87,147 +93,8 @@ Gun.chain.getAndDecryptPair = async function (address, signature) {
87
93
  }
88
94
  };
89
95
 
90
- const SHINE_ABI = [
91
- {
92
- anonymous: false,
93
- inputs: [
94
- {
95
- indexed: true,
96
- internalType: "bytes32",
97
- name: "dataHash",
98
- type: "bytes32",
99
- },
100
- {
101
- indexed: true,
102
- internalType: "address",
103
- name: "storer",
104
- type: "address",
105
- },
106
- {
107
- indexed: false,
108
- internalType: "bytes",
109
- name: "nodeId",
110
- type: "bytes",
111
- },
112
- ],
113
- name: "DataHashStored",
114
- type: "event",
115
- },
116
- {
117
- inputs: [
118
- {
119
- internalType: "bytes32[]",
120
- name: "hashes",
121
- type: "bytes32[]",
122
- },
123
- {
124
- internalType: "bytes[]",
125
- name: "nodeIds",
126
- type: "bytes[]",
127
- },
128
- ],
129
- name: "batchStoreDataHashes",
130
- outputs: [],
131
- stateMutability: "nonpayable",
132
- type: "function",
133
- },
134
- {
135
- inputs: [
136
- {
137
- internalType: "bytes32",
138
- name: "",
139
- type: "bytes32",
140
- },
141
- ],
142
- name: "dataHashes",
143
- outputs: [
144
- {
145
- internalType: "bool",
146
- name: "exists",
147
- type: "bool",
148
- },
149
- {
150
- internalType: "address",
151
- name: "storer",
152
- type: "address",
153
- },
154
- {
155
- internalType: "bytes",
156
- name: "nodeId",
157
- type: "bytes",
158
- },
159
- ],
160
- stateMutability: "view",
161
- type: "function",
162
- },
163
- {
164
- inputs: [
165
- {
166
- internalType: "bytes32",
167
- name: "dataHash",
168
- type: "bytes32",
169
- },
170
- {
171
- internalType: "bytes",
172
- name: "nodeId",
173
- type: "bytes",
174
- },
175
- ],
176
- name: "storeDataHash",
177
- outputs: [
178
- {
179
- internalType: "bytes",
180
- name: "",
181
- type: "bytes",
182
- },
183
- {
184
- internalType: "bytes32",
185
- name: "",
186
- type: "bytes32",
187
- },
188
- ],
189
- stateMutability: "nonpayable",
190
- type: "function",
191
- },
192
- {
193
- inputs: [
194
- {
195
- internalType: "bytes32",
196
- name: "dataHash",
197
- type: "bytes32",
198
- },
199
- ],
200
- name: "verifyDataHash",
201
- outputs: [
202
- {
203
- internalType: "bool",
204
- name: "exists",
205
- type: "bool",
206
- },
207
- {
208
- internalType: "address",
209
- name: "storer",
210
- type: "address",
211
- },
212
- {
213
- internalType: "bytes",
214
- name: "nodeId",
215
- type: "bytes",
216
- },
217
- ],
218
- stateMutability: "view",
219
- type: "function",
220
- },
221
- ];
222
-
223
- // Indirizzo del contratto SHINE deployato
224
- const SHINE_OPTIMISM_SEPOLIA = "0xb78E3E846FAf57Db15FfF17d8200a7736A7EDfBF"; // Inserisci qui l'indirizzo del contratto deployato
225
-
226
- let SHINE_CONTRACT_ADDRESS;
227
-
228
- Gun.chain.shine = function (chain, data, callback) {
96
+ Gun.chain.shine = function (chain, nodeId, data, callback) {
229
97
  const gun = this;
230
- const sea = Gun.SEA;
231
98
 
232
99
  // select address based on chain
233
100
  if (chain === "optimismSepolia") {
@@ -248,60 +115,94 @@ Gun.chain.shine = function (chain, data, callback) {
248
115
  };
249
116
 
250
117
  // Funzione per scrivere on-chain
251
- const writeOnChain = async (hash, nodeId) => {
118
+ const writeOnChain = async (nodeId, contentHash) => {
252
119
  const signer = await getSigner();
253
120
  const contract = new ethers.Contract(
254
121
  SHINE_CONTRACT_ADDRESS,
255
122
  SHINE_ABI,
256
123
  signer
257
124
  );
258
- const tx = await contract.storeDataHash(hash, ethers.toUtf8Bytes(nodeId));
125
+ const tx = await contract.updateData(
126
+ ethers.toUtf8Bytes(nodeId),
127
+ contentHash
128
+ );
259
129
  await tx.wait();
130
+ return tx;
260
131
  };
261
132
 
262
133
  // Funzione per verificare on-chain
263
- const verifyOnChain = async (hash) => {
134
+ const verifyOnChain = async (nodeId, contentHash) => {
264
135
  const signer = await getSigner();
265
136
  const contract = new ethers.Contract(
266
137
  SHINE_CONTRACT_ADDRESS,
267
138
  SHINE_ABI,
268
139
  signer
269
140
  );
270
- return await contract.verifyDataHash(hash);
141
+ return await contract.verifyData(ethers.toUtf8Bytes(nodeId), contentHash);
271
142
  };
272
143
 
273
- // Processo SHINE
274
- gun.put(data, async (ack) => {
275
- if (ack.err) {
276
- if (callback) callback({ err: ack.err });
277
- return;
278
- }
144
+ // Funzione per ottenere l'ultimo record on-chain
145
+ const getLatestRecord = async (nodeId) => {
146
+ const signer = await getSigner();
147
+ const contract = new ethers.Contract(
148
+ SHINE_CONTRACT_ADDRESS,
149
+ SHINE_ABI,
150
+ signer
151
+ );
152
+ return await contract.getLatestRecord(ethers.toUtf8Bytes(nodeId));
153
+ };
279
154
 
155
+ // Processo SHINE
156
+ gun.get(nodeId).once(async (existingData) => {
280
157
  try {
281
- // Calcola l'hash del dato
282
- const dataString = JSON.stringify(data);
283
- const dataHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
284
-
285
- // Ottieni l'ID del nodo corrente
286
- const nodeId = gun.back("opt.pid") || "unknown";
287
-
288
- // Scrivi on-chain
289
- await writeOnChain(dataHash, nodeId);
290
-
291
- // Verifica GunDB e chain
292
- const gunData = await gun.get(ack.get).then();
293
- const [exists, storer, storedNodeId] = await verifyOnChain(dataHash);
294
-
295
- if (JSON.stringify(gunData) === dataString && exists) {
296
- if (callback)
297
- callback({
298
- ok: true,
299
- message: "Data verified on GunDB and blockchain",
300
- storer: storer,
301
- nodeId: ethers.toUtf8String(storedNodeId),
302
- });
158
+ const dataToVerify = existingData || data;
159
+ const dataString = JSON.stringify(dataToVerify);
160
+ const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
161
+
162
+ // Ottieni l'ultimo record on-chain
163
+ const [lastContentHash, lastTimestamp, lastUpdater] =
164
+ await getLatestRecord(nodeId);
165
+
166
+ if (lastContentHash !== ethers.ZeroHash) {
167
+ // Il dato esiste on-chain
168
+ if (lastContentHash === contentHash) {
169
+ // Il dato on-chain corrisponde al dato in GunDB
170
+ if (callback)
171
+ callback({
172
+ ok: true,
173
+ message: "Data verified on GunDB and blockchain",
174
+ updater: lastUpdater,
175
+ timestamp: lastTimestamp.toString(),
176
+ });
177
+ } else {
178
+ // Il dato on-chain è diverso dal dato in GunDB
179
+ if (callback)
180
+ callback({ err: "Data mismatch between GunDB and blockchain" });
181
+ }
303
182
  } else {
304
- if (callback) callback({ err: "Data verification failed" });
183
+ // Il dato non esiste on-chain, procedi alla scrittura
184
+ if (!existingData) {
185
+ gun.get(nodeId).put(dataToVerify);
186
+ }
187
+
188
+ await writeOnChain(nodeId, contentHash);
189
+
190
+ // Verifica dopo la scrittura
191
+ const [newContentHash, newTimestamp, newUpdater] =
192
+ await getLatestRecord(nodeId);
193
+
194
+ if (newContentHash === contentHash) {
195
+ if (callback)
196
+ callback({
197
+ ok: true,
198
+ message: "Data written and verified on GunDB and blockchain",
199
+ updater: newUpdater,
200
+ timestamp: newTimestamp.toString(),
201
+ });
202
+ } else {
203
+ if (callback)
204
+ callback({ err: "Data verification failed after writing" });
205
+ }
305
206
  }
306
207
  } catch (error) {
307
208
  if (callback) callback({ err: error.message });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gun-eth",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "A GunDB plugin for Ethereum, and Web3",
5
5
  "main": "index.js",
6
6
  "scripts": {