add git3-v3

main
cyl19970726 2 years ago
parent 7b498b35c1
commit 7e9084de37

@ -0,0 +1,97 @@
pragma solidity ^0.8.0;
// import "hardhat/console.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "./Repository.sol";
contract Hub is AccessControlEnumerableUpgradeable{
// AccessController public accessController;
mapping(bytes=>address) public nameToRepository;
bytes[] public repoNames;
bytes32 public constant CREATOR = bytes32(uint256(1));
bytes32 public constant MANAGER = bytes32(uint256(2));
bytes32 public constant CONTRIBUTOR = bytes32(uint256(3));
bytes32[] public RoleList = [CREATOR,MANAGER,CONTRIBUTOR];
// mapping(bytes32=>address)public executors;
bool public permissionless;
function openPermissonlessJoin(bool open) public {
require(hasRole(CREATOR, _msgSender()));
permissionless = open;
}
function memberShip() public view returns(bool){
if (hasRole(CREATOR, _msgSender())){
return true;
}else if (hasRole(MANAGER, _msgSender())){
return true;
}else if (hasRole(CONTRIBUTOR, _msgSender())){
return true;
}else{
return false;
}
}
//createRepository can be invoked by anyone within Hub
function createRepository(bytes memory repoName) public returns(address){
require(hasRole(CREATOR, _msgSender()));
require(
repoName.length > 0 && repoName.length <= 100,
"RepoName length must be 1-100"
);
for (uint i; i < repoName.length; i++) {
bytes1 char = repoName[i];
require(
(char >= 0x61 && char <= 0x7A) || //a-z
(char >= 0x41 && char <= 0x5A) || //A-Z
(char >= 0x30 && char <= 0x39) || //0-9
(char == 0x2D || char == 0x2E || char == 0x5F), //-._
"RepoName must be alphanumeric or -._"
);
}
require(
nameToRepository[repoName] == address(0),
"RepoName already exist"
);
address repo = address(new Repository(repoName));
nameToRepository[repoName] = repo;
repoNames.push(repoName);
return repo;
}
function deleteRepository(bytes memory repoName) public returns(address){
require(nameToRepository[repoName]!=address(0),"repoName do not exist");
address repoAddr = nameToRepository[repoName];
delete(nameToRepository[repoName]);
// todo:remove repoName from repoNames
return repoAddr;
}
function addMember( bytes32 senderRole , bytes32 role,address member) public{
require(hasRole(senderRole, _msgSender()));
require(senderRole>role);
grantRole(role, member);
}
function deleteMember(bytes32 senderRole ,bytes32 role,address member) public{
require(hasRole(CREATOR, _msgSender()));
require(hasRole(senderRole, _msgSender()));
require(senderRole>role);
revokeRole(role, member);
}
// permissionlessJoin can be invoked by everyone who want to join this hub
function permissionlessJoin() public{
require(permissionless,"permissionless join no open");
grantRole(CONTRIBUTOR, _msgSender());
}
}

@ -0,0 +1,12 @@
pragma solidity ^0.8.0;
// import "hardhat/console.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
import "./Hub.sol";
contract HubFactory {
function createHub() public returns(Hub){
Hub hub = new Hub();
return hub;
}
}

@ -0,0 +1,111 @@
pragma solidity ^0.8.0;
import "./storage/IStorageLayer.sol";
import "./RepositoryAccess.sol";
contract Repository is RepositoryAccess{
struct refInfo {
bytes20 hash;
uint96 index;
}
struct refData {
bytes20 hash;
bytes name;
}
bytes repositoryName;
address creator;
address[] public contributorList;
mapping(bytes => refInfo) public branchToRefInfo; // dev => {hash: 0x1234..., index: 1 }
bytes[] public branchs; // branch,reference
IStorageLayer public storageManager;
bytes32 constant public ETHSTORAGEID_LAYER = bytes32(keccak256("ETHSTORAGE"));
bytes32 constant public NFTSTORAGE_LAYER = bytes32(keccak256("NFTSTORAGE"));
constructor(bytes memory repoName){
creator = msg.sender;
repositoryName = repoName;
}
modifier onlyCreator() {
require(address(storageManager) == msg.sender, "only creator");
_;
}
function listBranchs() external view returns (refData[] memory list) {
list = new refData[](branchs.length);
for (uint index = 0; index < branchs.length; index++) {
list[index] = _convertToRefData(
branchToRefInfo[branchs[index]]
);
}
}
function createBranch(bytes memory branch,bytes20 refHash) public onlyCreator {
bytes memory fullname = bytes.concat(repositoryName,"/",branch);
require(refHash!=bytes20(0),"reference hash don't allow to set 0x0" );
require(branchToRefInfo[fullname].hash == bytes20(0),"branch already exists");
branchToRefInfo[fullname].hash = refHash;
branchToRefInfo[fullname].index = uint96(branchs.length);
branchs.push(fullname);
// add branch owner
this.addBranchOperator(fullname,msg.sender);
}
function updateBranch(
bytes memory branch,
bytes20 refHash
)external onlyBranchOperator(branch){
bytes memory fullname = bytes.concat(repositoryName,"/",branch);
require(refHash!=bytes20(0),"reference hash don't allow to set 0x0" );
require(branchToRefInfo[fullname].hash != bytes20(0),"branch do not exist");
branchToRefInfo[fullname].hash = refHash;
}
function removeBranch(
bytes memory branch
) external {
bytes memory fullname = bytes.concat(repositoryName,"/",branch);
refInfo memory refI = branchToRefInfo[fullname];
require(
refI.hash != bytes20(0),
"Reference of this name does not exist"
);
uint256 lastIndex = branchs.length -1 ;
if (refI.index < lastIndex){
branchToRefInfo[branchs[lastIndex]].index = refI.index;
branchs[refI.index] = branchs[lastIndex];
}
branchs.pop();
delete branchToRefInfo[fullname];
}
function _convertToRefData(
refInfo memory info
) internal view returns (refData memory res) {
res.hash = info.hash;
res.name = branchs[info.index];
}
// data storage module
function setStorageLayer(IStorageLayer addr) external onlyCreator {
storageManager = addr;
}
function upload(
bytes20 refHash,
bytes calldata data
) external payable {
storageManager.upload(refHash, data);
}
function download(bytes20 refHash) external view returns(bytes32 storageLayerId , bytes memory data){
return storageManager.download(refHash);
}
}

@ -0,0 +1,28 @@
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract RepositoryAccess{
using EnumerableSet for EnumerableSet.AddressSet;
mapping(bytes => EnumerableSet.AddressSet) BranchOperators;
modifier onlyBranchOperator(bytes memory branch) {
require(BranchOperators[branch].contains(msg.sender),"only branch Operator");
_;
}
function _getBranchOwner(bytes memory branch) internal view returns(address){
return BranchOperators[branch].at(0) ;
}
function addBranchOperator(bytes memory branch, address member) external virtual{
require(_getBranchOwner(branch) == msg.sender,"only branch owner");
BranchOperators[branch].add(member);
}
function removeBranchOperator(bytes memory branch , address member) external virtual{
require(_getBranchOwner(branch) == msg.sender,"only branch owner");
BranchOperators[branch].remove(member);
}
}

@ -0,0 +1,12 @@
pragma solidity ^0.8.0;
interface IStorageLayer{
function upload(
bytes20 refHash,
bytes calldata data
) external payable ;
function download(bytes20 refHash) external view returns(bytes32 storageLayerId,bytes memory data);
}
Loading…
Cancel
Save