Skip to content

Commit

Permalink
[add] test
Browse files Browse the repository at this point in the history
  • Loading branch information
ymuichiro committed Aug 6, 2023
1 parent d4902d0 commit 5cc3581
Show file tree
Hide file tree
Showing 19 changed files with 145 additions and 106 deletions.
108 changes: 44 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,49 @@
# Decentralized-Guild

Empower and Thrive Together

## 概要

`Decentralized-Guild` は個人や企業が仕事の受発注を行うプラットフォームです。プラットフォームに参加する不特定多数の人々とバーチャルなチームを組んでプロジェクトに取り組むことができる新しい働き方を検証します。このプラットフォームは、特に高度なスキルや複数の人材が必要なプロジェクトに対応する際に活躍します。また、このプラットフォームは個人や組織の仕事の実績をブロックチェーン上に消えないデータベースとして記録し、日々活動している人々が正確に評価される事を目指します。

## 主な機能

### ギルド機能

ユーザーはプラットフォーム上で自由に「ギルド」と呼ばれるバーチャルなチームを作成できます。ギルドのオーナーはギルド名とメンバーを指定して発行申請を行い、他のユーザーは参加申請画面でギルドに参加できます。ギルドは個人で対応が難しいプロジェクトに対して効果的な解決策を提供し、仕事の依頼者も高度な仕事を依頼できるようになります。また、ギルドチームの中でバディプログラムを推進し、実績が少ないユーザーも経験の豊富なユーザーと共に活動し、実績を積める機能を提供します。

### ブロックチェーンへの記録

仕事の受発注記録はブロックチェーン上に記録されます。この仕組みにより、仕事の完了時に活動の実績が消えず、安全に記録されます。また、ブロックチェーン上で発行されるトークンも割り当てられます。トークンは、仕事の完了数や実績に応じて増減し、プラットフォーム上での信頼度の可視化が可能となります。トークンの保持量が増えるほど、ユーザーの実績が多いことを証明し、報酬の高い仕事を受注する機会が増えます。

### オープンソースプラットフォーム

このサービスはオープンソースで提供されており、誰でも同じプラットフォームを別のサーバーでも起動できます。GitHub のレポジトリを Clone し、README に記載されたコマンドを実行するだけで、簡単にプラットフォームを立ち上げることができます。

### Blockchain ID を利用した認証

ユーザーアカウントの登録後、所有するブロックチェーンアカウントの秘密鍵を利用して暗号化したトランザクションをサーバーに登録します。サーバー側で正しく暗号化されているかを検証し、問題がなければアカウントにブロックチェーン ID が登録されます。これにより、この OSS が使われた各種プラットフォーム上で同一 ID で活動することが可能となります。

### 元老院機能

仕事の受発注時には一定の利率で税金としてプラットフォーム上で手数料が徴収されます。この税金はプラットフォーム上で管理されているブロックチェーンアカウント上に蓄積され、この税金の使い道はサービス上元老院と呼ぶ人々によって決定、執行されます。元老院になる事が可能なユーザーは一定以上実績を積んだユーザー、つまりトークンを一定以上保有するユーザーに限定されます。この機能によってプラットフォームを維持する為に報酬の発生が起きない善意のボランティアに取り組む人々へ報酬を発生させます。

## プラットフォーム上のトークンについて

以下種別のトークンが存在します。

- xym ... Symbol。通貨として利用する。
- wrp ... Work Reputation Point。仕事の完了時にシステムより発行される信用トークン
- gpt ... Guild Point。仕事の完了時にギルドに対してシステムより発行される信用トークン

## 注意

- サービスの詳細な使い方やセキュリティについての情報は、公式 GitHub レポジトリやドキュメンテーションを参照してください。
- ブロックチェーンを消えないデータベースとして取り扱いますが、該当のチェーンが消失した場合にはデータも消失します。プラットフォームに参加する組織は自身でノードを経て、バリデータに参加することを推奨します。

## Future

API 側

1. notification クリック時に開く URL の調整(直接飛ぶように)
2. メール送信機能追加( メールサーバー不要のもので )
3. SecretLock 解除用 transaction QR 再取得用 API の追加
4. 退会時、対応中 Quest や募集中クエストがあったら退会できない処理

UI 側

1. Page コンポーネントの削除
2. キャンセル関連のボタンはいらないのでは。(クエストを受けますか?No みたいな。もしくは Yes を contain No を Outline
3. Modal ウィンドウを基本すりガラスにしてしまう
4. Quest の提案(提案内容作成画面が必要)
5. クエスト申込時に requester に通知する
6. Quest の詳細表示は /quest/details/[questId]
7. requester がマイページで quest の申込者一覧を表示して対応者を決める
8. 申込者へ受注通知を行い、かつ契約書をチェーンに格納する
9. 契約完了、納品画面の作成
10. 契約完了をチェーンに格納する

# Symbol を ID としての活用

- Session 回りの構築負荷軽減としてログイン自体には SNS ログインを利用する
- ただし、クエストに対するアクセス権限や記録に Symbol Public Key を用い、Decentralized Guild を他事業者が起動した際に、ログイン ID が異なっても同一人物か判定可能な実装とする

# 何を改善するか

- 頑張る人が正しく評価される状態を目指す
- 短時間で大きく収益を挙げるより長期間コンスタントに NW 上で活動する人々を評価する
- また、ギルドプログラムの中で評価ポイントを導入しポイントを得る事を促す
- 古参が有利になりすぎるため、バディプログラムとしてマルチシグで古参者と組み、一定期間 RPT を底上げ可能とする
- 元老院システムの構築

## 各ポイントの取り扱い

**RPT** アカウントに対して RPT TOKEN を報酬額に応じて案件達成時に付与する
**GPT** ギルドアカウントに対して GPT TOKEN を報酬額に応じて案件達成時に付与する

## 各種コントラクトフロー

System account が署名をしなければ模倣アカウントとの区別がややこしい
Secret Lock の送信先を2箇所にできない?

```mermaid
sequenceDiagram
box when contract
actor R AS Requester
actor W AS Worker
participant S as Distributed ledger
participant D as Database
end
W-->>R: Quest Apply
R-->>W: Approval
D-->>R: Send Transaction Serialize data
R-->>S: Sign
alt [aggregate transaction]
R->>W: Transfer Tx (Contract)
R->>D: Transfer Tx (System Fee)
R->>S: Secret Lock Tx(Reward)
end
R-->>D: Secret Key(Set)
W-->>R: Task completed
D-->>W: Secret Key(Get)
D->>W: Transfer Tx Mosaic A
S->>W: Secret Proof Tx(Reward)
```
2. 退会時、対応中 Quest や募集中クエストがあったら退会できない処理
1 change: 1 addition & 0 deletions packages/app/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ NEXT_PUBLIC_SYMBOL_SYSTEM_PUBLICKEY=832623BE4FF038B95BC1CA437E71082C7F9670A8B589
# system
NEXT_PUBLIC_WORLD_NAME="Symbol World β"
NEXT_PUBLIC_SYSTEM_FEE=1
NEXT_PUBLIC_APP_URL=http://localhost:3000

# web-push
NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=BI9x2JGkDmaERcr8H9KY4ymn02d54IDqk39V8Eff8EnauJ8-KgGX7_mVkl8JxJeBiQFSCzMnC56gKYRKPJU_7QU
2 changes: 2 additions & 0 deletions packages/app/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ NEXT_PUBLIC_SYMBOL_RTP_MOSAIC_DIVISIVILITY=0
NEXT_PUBLIC_SYMBOL_CURRENCY_DIVISIVILITY=6
NEXT_PUBLIC_SYMBOL_SYSTEM_PUBLICKEY=832623BE4FF038B95BC1CA437E71082C7F9670A8B5894C1AE54F668EEC7960C1


# sysyem
NEXT_PUBLIC_WORLD_NAME="Symbol World β"
NEXT_PUBLIC_SYSTEM_FEE=1
NEXT_PUBLIC_APP_URL=https://decentralized-guild.blockchain-authn.app

# web-push
NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=BI9x2JGkDmaERcr8H9KY4ymn02d54IDqk39V8Eff8EnauJ8-KgGX7_mVkl8JxJeBiQFSCzMnC56gKYRKPJU_7QU
1 change: 1 addition & 0 deletions packages/app/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ declare namespace NodeJS {
readonly NEXT_PUBLIC_SYMBOL_NETWORKTYPE: string;
readonly NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY: string;
readonly NEXT_PUBLIC_SYSTEM_FEE: string;
readonly NEXT_PUBLIC_APP_URL: string;
readonly MAIL_HOST: string;
readonly MAIL_PORT: string;
readonly MAIL_SECURE: string;
Expand Down
33 changes: 21 additions & 12 deletions packages/app/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,30 @@ import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { SessionProvider } from 'next-auth/react';
import { AppProps } from 'next/app';
import Head from 'next/head';
import { SWRConfig } from 'swr';

export default function App({ Component, pageProps }: AppProps) {
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<SessionProvider session={pageProps.session}>
<SWRConfig value={{ revalidateOnFocus: false }}>
<ThemeProvider theme={theme}>
<CssBaseline />
<div style={{ maxWidth: '100vw', overflow: 'hidden' }}>
<Component {...pageProps} />
</div>
</ThemeProvider>
</SWRConfig>
</SessionProvider>
</LocalizationProvider>
<>
<Head>
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
<meta name='twitter:card' content='summary_large_image' />
<meta name='twitter:site' content='@faunsu19000' />
<meta name='twitter:image' content={`${process.env.NEXT_PUBLIC_APP_URL || ''}/twitter-card.png`} />
</Head>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<SessionProvider session={pageProps.session}>
<SWRConfig value={{ revalidateOnFocus: false }}>
<ThemeProvider theme={theme}>
<CssBaseline />
<div style={{ maxWidth: '100vw', overflow: 'hidden' }}>
<Component {...pageProps} />
</div>
</ThemeProvider>
</SWRConfig>
</SessionProvider>
</LocalizationProvider>
</>
);
}
2 changes: 2 additions & 0 deletions packages/app/pages/api/quests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ async function POST(req: NextApiRequest, res: NextApiResponse<Quest>) {
},
});

Logger.info('A new quest has been created', req, newQuestData);

return res.status(200).json({
id: newQuestData.id,
createdAt: newQuestData.createdAt,
Expand Down
38 changes: 13 additions & 25 deletions packages/app/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import spaces from '@/assets/backgrounds/blockchain.json';
import Template from '@/components/templates/Template';
import paths from '@/services/Navigaion';
import Button from '@mui/material/Button';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import Lottie from 'lottie-react';
import { useSession } from 'next-auth/react';
Expand All @@ -23,31 +24,18 @@ export default function Home(): JSX.Element {

return (
<Template>
<div
className='center'
style={{
flexDirection: 'column',
gap: '3rem',
position: 'absolute',
zIndex: 1,
height: '100svh',
width: '100vw',
}}
>
<Typography
component='h1'
sx={{
whiteSpace: 'pre-wrap',
textAlign: 'center',
typography: { xs: 'h3', sm: 'h1', md: 'h1' },
maxWidth: '600px',
}}
>
Decentralized Guild
</Typography>
<Button color='primary' size='large' style={{ maxWidth: '90vw', minWidth: '250px' }} onClick={handleStart}>
Start Application
</Button>
<div className='center' style={{ position: 'absolute', zIndex: 1, height: '100svh', width: '100vw' }}>
<Container style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '2rem' }}>
<Typography
component='h1'
sx={{ whiteSpace: 'pre-wrap', textAlign: 'center', typography: { xs: 'h3', sm: 'h1', md: 'h1' } }}
>
Decentralized Guild
</Typography>
<Button color='primary' size='large' style={{ maxWidth: '90vw', minWidth: '250px' }} onClick={handleStart}>
Start Application
</Button>
</Container>
</div>
<div
style={{
Expand Down
59 changes: 55 additions & 4 deletions packages/app/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,31 @@
"theme_color": "#000000",
"background_color": "#000000",
"start_url": "/",
"description": "Empower and Thrive Together",
"icons": [
{
"src": "/icons/icon-192-192.webp",
"src": "/maskable_icon_x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "any"
},
{
"src": "/maskable_icon_x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "any"
},
{
"src": "/maskable_icon_x192.png",
"sizes": "192x192",
"type": "image/webp"
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-512-512.webp",
"src": "/maskable_icon_x512.png",
"sizes": "512x512",
"type": "image/webp"
"type": "image/png",
"purpose": "any"
}
],
"screenshots": [
Expand All @@ -24,6 +39,42 @@
"type": "image/webp",
"platform": "wide",
"label": "Dashboard Screen"
},
{
"src": "/screenshot1.png",
"type": "image/png",
"sizes": "944x1380",
"form_factor": "narrow"
}
],
"shortcuts": [
{
"name": "dashboard",
"short_name": "open dashboard",
"description": "Open the dashboard",
"url": "/quest/dashboard",
"icons": [{ "src": "/maskable_icon_x192.png", "sizes": "192x192" }]
},
{
"name": "new quest",
"short_name": "create quest",
"description": "Create a quest",
"url": "/quest/create",
"icons": [{ "src": "/maskable_icon_x192.png", "sizes": "192x192" }]
},
{
"name": "notice",
"short_name": "view notice",
"description": "View notice",
"url": "/account/notice",
"icons": [{ "src": "/maskable_icon_x192.png", "sizes": "192x192" }]
},
{
"name": "config",
"short_name": "open config",
"description": "Open config",
"url": "/account",
"icons": [{ "src": "/maskable_icon_x192.png", "sizes": "192x192" }]
}
]
}
Binary file added packages/app/public/maskable_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/app/public/maskable_icon_x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/app/public/maskable_icon_x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/app/public/maskable_icon_x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/app/public/maskable_icon_x96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions packages/app/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# *
User-agent: *
Allow: /

# Host
Host: https://decentralized-guild.blockchain-authn.app/
Binary file added packages/app/public/twitter-card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion packages/app/services/AccountSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import AccountBase from './AccountBase';

export class AccountSystem extends AccountBase {
public constructor(networkType: NetworkType) {
console.log('NEXT_PUBLIC_SYMBOL_SYSTEM_PUBLICKEY', process.env.NEXT_PUBLIC_SYMBOL_SYSTEM_PUBLICKEY);
if (!process.env.NEXT_PUBLIC_SYMBOL_SYSTEM_PUBLICKEY) {
throw new Error('NEXT_PUBLIC_SYMBOL_SYSTEM_PUBLICKEY is not set');
}
Expand Down

0 comments on commit 5cc3581

Please sign in to comment.