liu9293 2 years ago
parent f1f630eec2
commit 43f674d638

@ -169,7 +169,7 @@ class Git {
let data = GitUtils.encodeObject(sha) let data = GitUtils.encodeObject(sha)
let path = this.objectPath(sha) let path = this.objectPath(sha)
log("writing...", path, sha) log("writing...", path, sha)
let status = await this.storage.upload(path, data, this.remoteName, this.remoteUrl) let status = await this.storage.upload(path, data)
log("status", status) log("status", status)
} }

@ -3,7 +3,7 @@ import GitRemoteHelper from './git/git-remote-helper'
import { ApiBaseParams } from './git/git-remote-helper' import { ApiBaseParams } from './git/git-remote-helper'
import Git from './git/git' import Git from './git/git'
import { log } from './git/log' import { log } from './git/log'
import { MockStorage } from './storage/MockStorage' import { ETHStorage } from './storage/ETHStorage'
let git: Git; let git: Git;
GitRemoteHelper({ GitRemoteHelper({
@ -15,7 +15,7 @@ GitRemoteHelper({
* This will always be invoked when the remote helper is invoked * This will always be invoked when the remote helper is invoked
*/ */
init: async (p: ApiBaseParams) => { init: async (p: ApiBaseParams) => {
git = new Git(p, new MockStorage(p.remoteUrl)) git = new Git(p, new ETHStorage(p.remoteUrl))
return return
}, },
/** /**

@ -1,5 +1,5 @@
import { Ref, Status, Storage } from "./storage" import { Ref, Status, Storage } from "./storage"
import { callContractMethod } from "../wallet/index"
export class ETHStorage implements Storage { export class ETHStorage implements Storage {
repoURI: string repoURI: string
@ -7,23 +7,52 @@ export class ETHStorage implements Storage {
constructor(repoURI: string) { constructor(repoURI: string) {
this.repoURI = repoURI this.repoURI = repoURI
} }
download(path: string): Promise<[Status, Buffer]> {
throw new Error("Method not implemented.") async download(path: string): Promise<[Status, Buffer]> {
const buffer = await callContractMethod({
method: 'download',
path,
file: null,
sha: null
})
return [Status.SUCCEED, buffer]
} }
upload(path: string, file: Buffer): Promise<Status> {
throw new Error("Method not implemented.") async upload(path: string, file: Buffer): Promise<Status> {
await callContractMethod({
method: 'upload',
path,
file,
sha: null
})
return Status.SUCCEED
} }
remove(path: string): Promise<Status> { remove(path: string): Promise<Status> {
throw new Error("Method not implemented.") throw new Error("Method not implemented.")
} }
listRefs(): Promise<Ref[]> {
throw new Error("Method not implemented.") async listRefs(): Promise<Ref[]> {
const result = await callContractMethod({
method: 'listRefs',
path: null,
file: null,
sha: null
})
return result
} }
setRef(path: string, sha: string): Promise<Status> {
throw new Error("Method not implemented.") async setRef(path: string, sha: string): Promise<Status> {
await callContractMethod({
method: 'setRef',
path,
file: null,
sha
})
return Status.SUCCEED
} }
removeRef(path: string): Promise<Status> { removeRef(path: string): Promise<Status> {
throw new Error("Method not implemented.") throw new Error("Method not implemented.")
} }
} }

@ -29,8 +29,8 @@ export class MockStorage implements Storage {
catch (e) { catch (e) {
return [] return []
} }
} }
async setRef(path: string, sha: string): Promise<Status> { async setRef(path: string, sha: string): Promise<Status> {
let dict let dict
let stPath = join(mockPath, "refs.json") let stPath = join(mockPath, "refs.json")
@ -47,6 +47,7 @@ export class MockStorage implements Storage {
await fs.writeFile(stPath, JSON.stringify(dict)) await fs.writeFile(stPath, JSON.stringify(dict))
return Status.SUCCEED return Status.SUCCEED
} }
async removeRef(path: string): Promise<Status> { async removeRef(path: string): Promise<Status> {
let stPath = join(mockPath, "refs.json") let stPath = join(mockPath, "refs.json")
let refsJson = await fs.readFile(stPath) let refsJson = await fs.readFile(stPath)
@ -59,12 +60,12 @@ export class MockStorage implements Storage {
async remove(path: string): Promise<Status> { async remove(path: string): Promise<Status> {
throw new Error("Method not implemented.") throw new Error("Method not implemented.")
} }
async download(path: string): Promise<[Status, Buffer]> { async download(path: string): Promise<[Status, Buffer]> {
let buffer = await fs.readFile(join(mockPath, path)) let buffer = await fs.readFile(join(mockPath, path))
return [Status.SUCCEED, buffer] return [Status.SUCCEED, buffer]
} }
async upload(path: string, file: Buffer): Promise<Status> { async upload(path: string, file: Buffer): Promise<Status> {
let stPath = join(mockPath, path) let stPath = join(mockPath, path)
await fs.mkdir(pathUtil.dirname(stPath), { recursive: true }) await fs.mkdir(pathUtil.dirname(stPath), { recursive: true })

@ -15,7 +15,7 @@ export interface Storage {
repoURI: string repoURI: string
download(path: string): Promise<[Status, Buffer]> download(path: string): Promise<[Status, Buffer]>
upload(path: string, file: Buffer, remoteName: string, remoteUrl: string): Promise<Status> upload(path: string, file: Buffer): Promise<Status>
remove(path: string): Promise<Status> remove(path: string): Promise<Status>
listRefs(): Promise<Ref[]> listRefs(): Promise<Ref[]>
setRef(path: string, sha: string): Promise<Status> setRef(path: string, sha: string): Promise<Status>

@ -0,0 +1,260 @@
export default [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "name",
"type": "bytes"
}
],
"name": "countChunks",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
}
],
"name": "delRef",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "path",
"type": "bytes"
}
],
"name": "download",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
},
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "listRefs",
"outputs": [
{
"components": [
{
"internalType": "bytes20",
"name": "hash",
"type": "bytes20"
},
{
"internalType": "string",
"name": "name",
"type": "string"
}
],
"internalType": "struct Git3.refData[]",
"name": "list",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "nameToRefInfo",
"outputs": [
{
"internalType": "bytes20",
"name": "hash",
"type": "bytes20"
},
{
"internalType": "uint96",
"name": "index",
"type": "uint96"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "refs",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "val",
"type": "uint256"
}
],
"name": "refund",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "refund1",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "path",
"type": "bytes"
}
],
"name": "remove",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "bytes20",
"name": "refHash",
"type": "bytes20"
}
],
"name": "setRef",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "name",
"type": "bytes"
}
],
"name": "size",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "storageManager",
"outputs": [
{
"internalType": "contract IFileOperator",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "path",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "upload",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "path",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "chunkId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "uploadChunk",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]

@ -0,0 +1,5 @@
<body>
"git3://" web3 git protocol, code for the open web
</body>

@ -0,0 +1,67 @@
import { mkdirSync, readFileSync, existsSync, statSync } from "fs"
import { ethers } from 'ethers'
import parse from 'parse-git-config'
import abi from './abi.js'
// path -> /ab/123ab3123
export async function callContractMethod ({
method = 'upload',
path,
file,
sha
}) {
const wallet = 'default'
const keyPath = process.env.HOME + "/.git3/keys"
mkdirSync(keyPath, { recursive: true })
const content = readFileSync(`${keyPath}/${wallet}`).toString()
const [walletType, key] = content.split('\n')
const provider = new ethers.providers.JsonRpcProvider('https://galileo.web3q.io:8545');
let etherWallet = walletType === 'privateKey'
? new ethers.Wallet(key)
: ethers.Wallet.fromMnemonic(key)
etherWallet = etherWallet.connect(provider)
const contract = new ethers.Contract('0x680336910D9357F6aDf26c0d61eAB8e65998Ab2d', abi, etherWallet);
const pathBuffer = path ? Buffer.from(path) : ''
if (method === 'upload') {
await contract.upload(pathBuffer, file)
}
if (method === 'download') {
const res = await contract.download(pathBuffer)
const buf = Buffer.from(res[0].slice(2), 'hex')
return buf
}
if (method === 'setRef') {
const res = await contract.setRef(path, '0x' + sha)
}
if (method === 'listRefs') {
const res = await contract.listRefs()
const refs = res.map(i => ({
ref: i[1],
sha: i[0].slice(2)
}))
return refs
}
}
// callContractMethod('kai', 'upload', '/07/549ed56229550960d2cb32b086df52304d9a86')
// callContractMethod('kai', 'download', '/07/549ed56229550960d2cb32b086df52304d9a86')
// callContractMethod({
// wallet: 'kai',
// method: 'setRef',
// path: '/refs/heads/master',
// sha: '07549ed56229550960d2cb32b086df52304d9a86'
// })
callContractMethod({
wallet: 'kai',
method: 'listRefs',
// path: '/refs/heads/master',
// sha: '07549ed56229550960d2cb32b086df52304d9a86'
})

@ -1,23 +0,0 @@
// program stomach view picnic because depth ready sight appear spin cream prefer
// selfAddress = 0xd1a98cD2382B8DA25280B380C0b9D85A63aD2818
// contractAddress = '0x2A9B264471b19bAB5faD04807328F0dd4FD5549c'
import { ethers } from "ethers"
import uploader from './uploader.js'
const mnemonic = 'program stomach view picnic because depth ready sight appear spin cream prefer'
const wallet = ethers.Wallet.fromMnemonic(mnemonic)
const contractAddress = '0x2A9B264471b19bAB5faD04807328F0dd4FD5549c'
async function run () {
const addr = await wallet.getAddress()
console.log(addr)
try {
const res = await uploader.deploy('/Users/kai/Code/git-remote-git3/src/wallet/git', contractAddress, wallet.privateKey)
console.log(res)
} catch (error) {
console.log(error)
}
}
run()
Loading…
Cancel
Save