2
2
pragma solidity ^ 0.8.0 ;
3
3
import "./gwt.sol " ;
4
4
import "./sortedlist.sol " ;
5
- import "@openzeppelin/contracts/utils/cryptography/MerkleProof .sol " ;
5
+ import "./PublicDataProof .sol " ;
6
6
7
7
import "hardhat/console.sol " ;
8
8
@@ -125,10 +125,6 @@ contract PublicDataStorage {
125
125
}
126
126
}
127
127
128
- function lengthFromMixedHash (bytes32 dataMixedHash ) public pure returns (uint64 ) {
129
- return uint64 (uint256 (dataMixedHash) >> 192 & ((1 << 62 ) - 1 ));
130
- }
131
-
132
128
function _verifyBlockNumber (bytes32 dataMixedHash , uint256 blockNumber ) internal pure returns (bool ) {
133
129
// (blockNumber xor dataMixedHash) % 64 == 0
134
130
return uint256 (bytes32 (blockNumber) ^ dataMixedHash) % 64 == 0 ;
@@ -184,7 +180,7 @@ contract PublicDataStorage {
184
180
require (publicDataInfo.maxDeposit == 0 , "public data already exists " );
185
181
186
182
// get data size from data hash
187
- uint64 dataSize = lengthFromMixedHash (dataMixedHash);
183
+ uint64 dataSize = PublicDataProof. lengthFromMixedHash (dataMixedHash);
188
184
// 区分质押率和最小时长。最小时长是系统参数,质押率depositRatio是用户参数
189
185
// 质押率影响用户SHOW数据所需要冻结的质押
190
186
// minAmount = 数据大小*最小时长*质押率,
@@ -281,7 +277,7 @@ contract PublicDataStorage {
281
277
}
282
278
283
279
function _getLockAmount (bytes32 dataMixedHash ) internal view returns (uint256 ) {
284
- uint64 dataSize = lengthFromMixedHash (dataMixedHash);
280
+ uint64 dataSize = PublicDataProof. lengthFromMixedHash (dataMixedHash);
285
281
return _dataSizeToGWT (dataSize) * sysMinDepositRatio * sysMinLockWeeks;
286
282
}
287
283
@@ -299,112 +295,13 @@ contract PublicDataStorage {
299
295
emit SupplierBalanceChanged (supplierAddress, supplierInfo.avalibleBalance, supplierInfo.lockedBalance);
300
296
}
301
297
302
- function _verifyDataProof (bytes32 dataMixedHash ,uint256 nonce_block_high , uint32 index , bytes16 [] calldata m_path , bytes calldata leafdata , bytes32 noise ) private view returns (bytes32 ,bytes32 ) {
298
+ function _verifyDataProof (bytes32 dataMixedHash ,uint256 nonce_block_high , uint32 index , bytes16 [] calldata m_path , bytes calldata leafdata ) private view returns (bytes32 ,bytes32 ) {
303
299
require (nonce_block_high < block .number , "invalid nonce_block_high " );
304
300
require (block .number - nonce_block_high < 256 , "nonce block too old " );
305
301
306
302
bytes32 nonce = blockhash (nonce_block_high);
307
303
308
- //先验证index落在MixedHash包含的长度范围内
309
- require (index < (lengthFromMixedHash (dataMixedHash) >> 10 ) + 1 , "invalid index " );
310
-
311
- //验证leaf_data+index+path 和 dataMixedHash是匹配的,不匹配就revert
312
- // hash的头2bits表示hash算法,00 = sha256, 10 = keccak256
313
- uint8 hashType = uint8 (uint256 (dataMixedHash) >> 254 );
314
-
315
- bytes32 dataHash = _merkleRoot (hashType,m_path,index, _hashLeaf (hashType,leafdata));
316
- //验证leaf_data+index+path 和 dataMixedHash是匹配的,不匹配就revert
317
- // 只比较后192位
318
- require (dataHash & bytes32 (uint256 ((1 << 192 ) - 1 )) == dataMixedHash & bytes32 (uint256 ((1 << 192 ) - 1 )), "mixhash mismatch " );
319
-
320
- // 不需要计算插入位置,只是简单的在Leaf的数据后部和头部插入,也足够满足我们的设计目的了?
321
- bytes memory new_leafdata = bytes .concat (leafdata, nonce);
322
- bytes32 new_root_hash = _merkleRoot (hashType,m_path,index, _hashLeaf (hashType,new_leafdata));
323
- bytes32 pow_hash = bytes32 (0 );
324
-
325
- if (noise != 0 ) {
326
- //Enable PoW
327
- pow_hash = _hashLeaf (hashType, bytes .concat (noise, leafdata, nonce));
328
- }
329
-
330
- return (new_root_hash, pow_hash);
331
- }
332
-
333
- function _merkleRoot (uint8 hashType ,bytes16 [] calldata proof , uint32 leaf_index ,bytes16 leaf_hash ) internal pure returns (bytes32 ) {
334
- if (hashType == 0 ) {
335
- // sha256
336
- return _merkleRootWithSha256 (proof, leaf_index, leaf_hash);
337
- } else if (hashType == 2 ) {
338
- // keccak256
339
- return _merkleRootWithKeccak256 (proof, leaf_index, leaf_hash);
340
- } else {
341
- revert ("invalid hash type " );
342
- }
343
- }
344
-
345
- function _hashLeaf (uint8 hashType ,bytes memory leafdata ) internal pure returns (bytes16 ) {
346
- if (hashType == 0 ) {
347
- // sha256
348
- return _bytes32To16 (sha256 (leafdata));
349
- } else if (hashType == 2 ) {
350
- // keccak256
351
- return _bytes32To16 (keccak256 (leafdata));
352
- } else {
353
- revert ("invalid hash type " );
354
- }
355
- }
356
-
357
- // from openzeppelin`s MerkleProof.sol
358
- function _efficientKeccak256 (bytes16 a , bytes16 b ) private pure returns (bytes32 value ) {
359
- /// @solidity memory-safe-assembly
360
- assembly {
361
- mstore (0x00 , a)
362
- mstore (0x10 , b)
363
- value := keccak256 (0x00 , 0x20 )
364
- }
365
- }
366
-
367
- function _bytes32To16 (bytes32 b ) private pure returns (bytes16 ) {
368
- return bytes16 (uint128 (uint256 (b)));
369
- }
370
-
371
- function _merkleRootWithKeccak256 (bytes16 [] calldata proof , uint32 leaf_index ,bytes16 leaf_hash ) internal pure returns (bytes32 ) {
372
- bytes16 currentHash = leaf_hash;
373
- bytes32 computedHash = bytes32 (0 );
374
- for (uint32 i = 0 ; i < proof.length ; i++ ) {
375
- if (proof[i] != bytes32 (0 )) {
376
- if (leaf_index % 2 == 0 ) {
377
- computedHash = _efficientKeccak256 (currentHash, proof[i]);
378
- } else {
379
- computedHash = _efficientKeccak256 (proof[i], currentHash);
380
- }
381
- }
382
- currentHash = _bytes32To16 (computedHash);
383
-
384
- //require(leaf_index >= 2, "invalid leaf_index");
385
- leaf_index = leaf_index / 2 ;
386
- }
387
-
388
- return computedHash;
389
- }
390
-
391
- // sha256要比keccak256贵,因为它不是一个EVM内置操作码,而是一个预置的内部合约调用
392
- // 当hash 1kb数据时,sha256要贵160,当hash 两个bytes32时,sha256要贵400
393
- function _merkleRootWithSha256 (bytes16 [] calldata proof , uint32 leaf_index , bytes16 leaf_hash ) internal pure returns (bytes32 ) {
394
- bytes16 currentHash = leaf_hash;
395
- bytes32 computedHash = 0 ;
396
- for (uint32 i = 0 ; i < proof.length ; i++ ) {
397
- if (leaf_index % 2 == 0 ) {
398
- computedHash = sha256 (bytes .concat (currentHash, proof[i]));
399
- } else {
400
- computedHash = sha256 (bytes .concat (proof[i], currentHash));
401
- }
402
- currentHash = _bytes32To16 (computedHash);
403
- //require(leaf_index >= 2, "invalid leaf_index");
404
- leaf_index = leaf_index / 2 ;
405
- }
406
-
407
- return computedHash;
304
+ return PublicDataProof.calcDataProof (dataMixedHash, nonce, index, m_path, leafdata, bytes32 (0 ));
408
305
}
409
306
410
307
function showData (bytes32 dataMixedHash , uint256 nonce_block , uint32 index , bytes16 [] calldata m_path , bytes calldata leafdata ) public {
@@ -444,7 +341,7 @@ contract PublicDataStorage {
444
341
445
342
// 如果不是新的show,判定为对上一个show的挑战,要检查nonce_block_high是否一致
446
343
require (is_new_show || publicDataInfo.nonce_block_high == nonce_block, "nonce_block_high not match " );
447
- (bytes32 root_hash ,) = _verifyDataProof (dataMixedHash,nonce_block,index,m_path,leafdata, bytes32 ( 0 ) );
344
+ (bytes32 root_hash ,) = _verifyDataProof (dataMixedHash,nonce_block,index,m_path,leafdata);
448
345
449
346
if (is_new_show) {
450
347
publicDataInfo.nonce_block_high = nonce_block;
@@ -478,7 +375,7 @@ contract PublicDataStorage {
478
375
CycleInfo storage cycleInfo = cycle_infos[_cycleNumber ()];
479
376
CycleDataInfo storage dataInfo = cycleInfo.data_infos[dataMixedHash];
480
377
if (is_new_show) {
481
- dataInfo.score += lengthFromMixedHash (dataMixedHash);
378
+ dataInfo.score += PublicDataProof. lengthFromMixedHash (dataMixedHash);
482
379
483
380
// insert supplier into last_showers
484
381
if (dataInfo.shower_index >= 5 ) {
@@ -577,7 +474,6 @@ contract PublicDataStorage {
577
474
// 设置已取标志
578
475
dataInfo.withdraw_status |= withdrawUser;
579
476
580
-
581
477
emit WithdrawAward (dataMixedHash, msg .sender , reward);
582
478
}
583
479
}
0 commit comments