gun-eth 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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": {