You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.0 KiB
Solidity

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "./IFileOperator.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "evm-large-storage/contracts/examples/FlatDirectory.sol";
// import "evm-large-storage/contracts/W3RC3.sol";
contract Git3 {
IFileOperator public immutable storageManager;
struct refInfo {
bytes20 hash;
uint96 index;
}
struct refData {
bytes20 hash;
string name;
}
mapping (string => refInfo) public nameToRefInfo; // dev => {hash: 0x1234..., index: 1 }
string[] public refs; // [main, dev, test, staging]
function _convertRefInfo(refInfo memory info) internal view returns(refData memory res){
res.hash = info.hash;
res.name = refs[info.index];
}
constructor() {
storageManager = IFileOperator(address(new FlatDirectory(0)));
}
function download(bytes memory path) external view returns (bytes memory, bool) {
// call flat directory(FD)
return storageManager.read(path);
}
function upload(bytes memory path, bytes memory data) external payable {
storageManager.writeChunk(path, 0, data);
}
function uploadChunk(bytes memory path,uint256 chunkId, bytes memory data) external payable {
storageManager.writeChunk(path, chunkId, data);
}
function remove(bytes memory path) external {
// The actually process of remove will remove all the chunks
storageManager.remove(path);
}
function size(bytes memory name) external view returns (uint256,uint256){
return storageManager.size(name);
}
function countChunks(bytes memory name)external view returns (uint256){
return storageManager.countChunks(name);
}
function listRefs() public view returns (refData[] memory list) {
list = new refData[](refs.length);
for (uint index = 0; index < refs.length; index++) {
list[index] = _convertRefInfo(nameToRefInfo[refs[index]]);
}
}
function setRef(string memory name, bytes20 refHash) public {
// only execute `sload` once to reduce gas consumption
refInfo memory srs;
srs = nameToRefInfo[name];
uint256 refsLen = refs.length;
if (srs.hash == bytes20(0)) {
// store refHash for the first time
require(refsLen <= uint256(uint96(int96(-1))),"Refs exceed valid length");
nameToRefInfo[name].hash = refHash;
nameToRefInfo[name].index = uint96(refsLen);
refs.push(name);
}else{
// only update refHash
nameToRefInfo[name].hash = refHash;
}
}
function delRef(string memory name) public {
// only execute `sload` once to reduce gas consumption
refInfo memory srs;
srs = nameToRefInfo[name];
uint256 refsLen = refs.length;
require(srs.hash != bytes20(0),"Reference of this name does not exist");
require(srs.index < refsLen,"System Error: Invalid index");
if (srs.index < refsLen-1){
refs[srs.index] = refs[refsLen - 1];
nameToRefInfo[refs[refsLen - 1]].index = srs.index;
}
refs.pop();
delete nameToRefInfo[name];
}
}