From 9b0f0a547375bea6829d793e02fe450c70ef4d96 Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Mon, 12 Dec 2022 20:43:46 +0800 Subject: [PATCH] feat: update contract --- README.md | 7 ++++ contracts/Git3.sol | 98 ++++++++++++++-------------------------------- hardhat.config.ts | 10 +++++ package-lock.json | 16 ++++++++ package.json | 1 + scripts/deploy.ts | 16 ++------ test/git3-test.js | 14 +++++-- 7 files changed, 78 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index 7be82e5..3d4dee4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +# Contract Info + +- RPC : https://galileo.web3q.io:8545 +- ChainId : 3334 +- Git3 Contract Address: 0x981cf56258Af8B6470642cBf1f991980cAa5DBf3 + + # Sample Hardhat Project This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. diff --git a/contracts/Git3.sol b/contracts/Git3.sol index 2a09d8c..7f365bb 100644 --- a/contracts/Git3.sol +++ b/contracts/Git3.sol @@ -8,20 +8,34 @@ import "evm-large-storage/contracts/examples/FlatDirectory.sol"; // import "evm-large-storage/contracts/W3RC3.sol"; contract Git3 { - uint256 constant REF_HASH_LEN = 40; 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(220))); + storageManager = IFileOperator(address(new FlatDirectory(0))); } - // download(path: string): Promise<[Status, Buffer]> // objects/3e/3432eac32.../ function download(bytes memory path) external view returns (bytes memory, bool) { // call flat directory(FD) return storageManager.read(path); } - // upload(path: string, file: Buffer): Promise function upload(bytes memory path, bytes memory data) external payable { storageManager.writeChunk(path, 0, data); } @@ -30,7 +44,6 @@ contract Git3 { storageManager.writeChunk(path, chunkId, data); } - // delete(path: string): Promise function remove(bytes memory path) external { // The actually process of remove will remove all the chunks storageManager.remove(path); @@ -44,59 +57,6 @@ contract Git3 { return storageManager.countChunks(name); } - - /* - The Storage Layout as below: - slot n = [hash1] - slot n+1 = [hash2,index] - **/ - struct refInfo { - bytes32 hash1; - bytes8 hash2; - uint192 index; // 8 * 24 = 192 - } - - struct refData { - bytes hash; - string name; - } - - mapping (string => refInfo) public nameToRefInfo; // dev => {hash: 0x1234..., index: 1 } - string[] public refs; // [main, dev, test, staging] - - function _setRefInfo(refInfo storage ref, bytes memory hash,uint192 index) internal{ - require(hash.length == REF_HASH_LEN,"Incorrect RefHash Length"); - bytes32 hash1; - bytes32 hash2; - - assembly{ - hash1 := mload(add(hash,0x20)) - // sstore(ref.slot,hash1) - hash2 := mload(add(hash,0x40)) - // sstore(add(ref.slot,0x20),add(hash2,index)) - } - - ref.hash1 = hash1; - ref.hash2 = bytes8(hash2); - ref.index = index; - } - - // listRefs(): Promise - function _convertRefInfo(refInfo storage info) internal view returns(refData memory res){ - // res .hash = - bytes memory hash = new bytes(REF_HASH_LEN); - - // sload hash1 and hash2 - bytes32 hash1 = info.hash1; - bytes8 hash2 = info.hash2; - assembly { - mstore(add(hash,0x20),hash1) - mstore(add(hash,0x40),hash2) - } - res.hash = hash; - res.name = refs[info.index]; - } - function listRefs() public view returns (refData[] memory list) { list = new refData[](refs.length); for (uint index = 0; index < refs.length; index++) { @@ -104,34 +64,36 @@ contract Git3 { } } - // setRef(path: string, sha: string): Promise - function setRef(string memory name, bytes memory refHash) public { - + 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.hash1 == bytes32(0) && srs.hash2 == bytes8(0)) { + if (srs.hash == bytes20(0)) { // store refHash for the first time - require(refs.length <= uint256(uint192(int192(-1))),"refs exceed valid length"); + require(refsLen <= uint256(uint96(int96(-1))),"Refs exceed valid length"); + + nameToRefInfo[name].hash = refHash; + nameToRefInfo[name].index = uint96(refsLen); - _setRefInfo(nameToRefInfo[name],refHash,uint192(refs.length)); refs.push(name); + }else{ // only update refHash - _setRefInfo(nameToRefInfo[name],refHash,srs.index); + nameToRefInfo[name].hash = refHash; } } - // delRef(path: string): Promise 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.hash1 != bytes32(0) || srs.hash2 != bytes8(0),"Reference of this name does not exist"); - + 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; diff --git a/hardhat.config.ts b/hardhat.config.ts index c07f192..3ed6e16 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,8 +1,18 @@ + + +require("dotenv").config(); + import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; const config: HardhatUserConfig = { solidity: "0.8.17", + networks: { + w3qGalileo: { + url: "https://galileo.web3q.io:8545", + accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + } + } }; export default config; diff --git a/package-lock.json b/package-lock.json index 0621a4d..74b2507 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^2.0.0", + "dotenv": "^16.0.3", "hardhat": "^2.12.4" } }, @@ -3226,6 +3227,15 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -11507,6 +11517,12 @@ "path-type": "^4.0.0" } }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", diff --git a/package.json b/package.json index 92fc1b6..c15fe9e 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "homepage": "https://github.com/cyl19970726/dGithub#readme", "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^2.0.0", + "dotenv": "^16.0.3", "hardhat": "^2.12.4" }, "dependencies": { diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 6cdf2cb..0325ea7 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -1,18 +1,10 @@ import { ethers } from "hardhat"; async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000); - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const unlockTime = currentTimestampInSeconds + ONE_YEAR_IN_SECS; - - const lockedAmount = ethers.utils.parseEther("1"); - - const Lock = await ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); - - await lock.deployed(); - - console.log(`Lock with 1 ETH and unlock timestamp ${unlockTime} deployed to ${lock.address}`); + const Git3 = await ethers.getContractFactory("Git3"); + const git3 = await Git3.deploy(); + let receipt = await git3.deployed(); + console.log(receipt); } // We recommend this pattern to be able to use async/await everywhere diff --git a/test/git3-test.js b/test/git3-test.js index 6b4628f..f8152ca 100644 --- a/test/git3-test.js +++ b/test/git3-test.js @@ -66,21 +66,21 @@ describe("Git3 Test", function () { expect(await git3.countChunks("0x616263")).to.eql(ToBig(0)); }); - it("set/list Ref",async function() { + it("set/update/list/remove Reference",async function() { const Git3 = await ethers.getContractFactory("Git3"); const git3 = await Git3.deploy(); await git3.deployed(); let key0 = "0x616263"; - let data0 = "0xaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabb"; + let data0 = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; await git3.setRef(key0,data0); let key1 = "0x717273"; - let data1 = "0x1111aabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaaaaaaaaaaaa"; + let data1 = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; await git3.setRef(key1,data1); let key2 = "0x818283"; - let data2 = "0x777777777777777baabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabba88888888888"; + let data2 = "0xcccccccccccccccccccccccccccccccccccccccc"; await git3.setRef(key2,data2); @@ -102,6 +102,12 @@ describe("Git3 Test", function () { expect(refs[0]).to.eql([data2,key2]); expect(refs.length).to.eql(1); + // check update + let data3 = "0xdddddddddddddddddddddddddddddddddddddddd"; + await git3.setRef(key2,data3); + refs = await git3.listRefs(); + expect(refs[0]).to.eql([data3,key2]); + }) });