愛記システム概念設計:個人のレベル② | 続・ティール組織 研究会のブログ

続・ティール組織 研究会のブログ

ティール組織が話題になっているが、具現化するにはどうしたらよいか?
その研究を続けるにあたり、さらに次の形態である、続・ティール組織なるものまで視野に入れ、具体的な施策・行動内容を研究・支援する会。

先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。大まかな概念としてはひとまず終えた。次は、ブロックチェーンの概念設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。

個人のレベル②

先に、結局は、自分が今どのレベルに居るのか?ということが分からないと、どのレベルの行動を重点的にしていけば良いのかが分からなくなるということだ。これが”愛”とは良く分からない崇高なモノとして見られてしまう原因なのであろう。そう、自分の今のレベルが分かれば、そのレベルと同じかもしくは1つ上のレベルの行動を重点的にしていけば良いだけなのだ。これを分析できるツールをDApps側で用意をしたい。

 

愛の行動レベルごとの愛貨受け取り率などの分析を行うことで、自身の行動の効果や改善の余地を見つけることができる。これにより、より意識的に行動を選択することができる。そのような分析結果をフロントエンドで視覚化するには、まずはブロックチェーンと通信する分析専用のAPIが必要だ。このAPIを経由し、バックエンド側のpythonプログラムでデータ処理を行い、フロントエンド側でJavaScriptで画面設計をしていくという流れになるのだろう。

個人の行動分析専用API

下記のAPIは、自分自身の愛の行動レベルや愛貨を受け取って貰えた率や目標達成度などを分析するAPIで、dapps側のバックエンドプログラムとやりとりするというAPIの設計例だ。

from flask import Flask, jsonify, request
from functools import wraps
import os

app = Flask(__name__)

# APIキーを環境変数から取得
API_KEY = os.getenv('API_KEY')

# APIキーの検証用デコレータ
def api_key_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if request.headers.get('X-API-KEY') != API_KEY:
            return jsonify({'error': 'Unauthorized access'}), 401
        return f(*args, **kwargs)
    return decorated_function

# ユーザーのデータを取得するAPI
@app.route('/user_data', methods=['GET'])
@api_key_required
def get_user_data():
    user_id = request.args.get('user_id')  # ユーザーIDを取得
    # ユーザーIDを元に、ユーザーのデータをデータベースやブロックチェーンから取得
    # 以下は仮のデータです
    user_data = {
        'user_id': user_id,
        'love_action_level': 'Lv3',
        'love_currency_received_rate': 0.75,
        'goal_achievement_rate': 0.6
    }
    return jsonify(user_data)

if __name__ == '__main__':
    app.run(debug=True, ssl_context=('cert.pem', 'key.pem'))
 

このプログラムでは、APIキーを使用して認証を行い、SSL/TLSを使用して通信を暗号化している。これにより、セキュアなAPIを実装することができる。

分析画面のバックエンドプログラム

以下は、自分自身の愛の行動レベルや愛貨を受け取って貰えた率や目標達成度などを分析する画面のバックエンドプログラムの例である。この例では、ブロックチェーンとウォレットの概念を組み合わせて、トークンの送受信や残高、取引履歴を管理し、これらを利用して分析を行う方法を示している。

from flask import Flask, jsonify, request
from datetime import datetime
import hashlib
import json
import random

app = Flask(__name__)

class Transaction:
    def __init__(self, sender, receiver, amount):
        self.sender = sender
        self.receiver = receiver
        self.amount = amount
        self.timestamp = datetime.now()

    def to_dict(self):
        return {
            'sender': self.sender,
            'receiver': self.receiver,
            'amount': self.amount,
            'timestamp': str(self.timestamp)
        }

    def __repr__(self):
        return f"Transaction(sender={self.sender}, receiver={self.receiver}, amount={self.amount}, timestamp={self.timestamp})"

class Block:
    def __init__(self, index, previous_hash, transactions, proof, timestamp=None):
        self.index = index
        self.previous_hash = previous_hash
        self.transactions = transactions
        self.proof = proof
        self.timestamp = timestamp or datetime.now()

    def to_dict(self):
        return {
            'index': self.index,
            'previous_hash': self.previous_hash,
            'transactions': [t.to_dict() for t in self.transactions],
            'proof': self.proof,
            'timestamp': str(self.timestamp)
        }

    def __repr__(self):
        return f"Block(index={self.index}, previous_hash={self.previous_hash}, transactions={self.transactions}, proof={self.proof}, timestamp={self.timestamp})"

class Blockchain:
    def __init__(self):
        self.chain = []
        self.pending_transactions = []
        self.create_block(proof=0, previous_hash='0')

    def create_block(self, proof, previous_hash=None):
        block = Block(index=len(self.chain) + 1, proof=proof, previous_hash=previous_hash or self.chain[-1].hash if self.chain else '0', transactions=self.pending_transactions)
        self.chain.append(block)
        self.pending_transactions = []
        return block

    def add_transaction(self, sender, receiver, amount):
        self.pending_transactions.append(Transaction(sender, receiver, amount))
        return self.last_block.index + 1

    @property
    def last_block(self):
        return self.chain[-1]

    def hash(self, block):
        block_string = json.dumps(block.to_dict(), sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

    def is_chain_valid(self, chain):
        previous_block = chain[0]
        current_index = 1

        while current_index < len(chain):
            block = chain[current_index]

            if block.previous_hash != self.hash(previous_block):
                return False

            previous_block = block
            current_index += 1

        return True

class Wallet:
    def __init__(self, blockchain, user_id):
        self.blockchain = blockchain
        self.user_id = user_id

    def send_tokens(self, receiver_id, amount):
        sender_balance = self.get_balance()
        if sender_balance < amount:
            return False, "Insufficient balance"

        block_index = self.blockchain.add_transaction(self.user_id, receiver_id, amount)
        return True, f"Transaction will be added to Block {block_index}"

    def get_balance(self):
        balance = 0
        for block in self.blockchain.chain:
            for tx in block.transactions:
                if tx.receiver == self.user_id:
                    balance += tx.amount
                if tx.sender == self.user_id:
                    balance -= tx.amount
        return balance

    def transaction_history(self):
        history = []
        for block in self.blockchain.chain:
            for tx in block.transactions:
                if tx.sender == self.user_id or tx.receiver == self.user_id:
                    history.append(tx)
        return history

# テスト用のデモ
blockchain = Blockchain()
alice_wallet = Wallet(blockchain, "Alice")
bob_wallet = Wallet(blockchain, "Bob")

# トークンの送受信
alice_wallet.send_tokens("Bob", 50)
alice_wallet.send_tokens("Bob", 20)
bob_wallet.send_tokens("Alice", 30)

# 残高と取引履歴の表示
print(f"Alice's balance: {alice_wallet.get_balance()}")
print(f"Bob's balance: {bob_wallet.get_balance()}")
print("Alice's transaction history:")
for tx in alice_wallet.transaction_history():
    print(tx)
print("Bob's transaction history:")
for tx in bob_wallet.transaction_history():
    print(tx)

# APIのエンドポイント
@app.route('/user_data', methods=['GET'])
def get_user_data():
    user_id = request.args.get('user_id')  # ユーザーIDを取得
    # ユーザーIDを元に、ユーザーのデータを取得
    # 以下は仮のデータです
    user_data = {
        'user_id': user_id,
        'balance': alice_wallet.get_balance() if user_id == 'Alice' else bob_wallet.get_balance(),
        'transaction_history': alice_wallet.transaction_history() if user_id == 'Alice' else bob_wallet.transaction_history()
    }
    return jsonify(user_data)

if __name__ == '__main__':
    app.run(debug=True)
 

このプログラムでは、ブロックチェーンとウォレットの機能を使用してトークンの送受信や残高、取引履歴を管理している。また、APIエンドポイントを通じてユーザーのデータを取得する機能も追加されている。

分析画面のフロントエンドプログラム

以下は、前述のバックエンドプログラムに対応するフロントエンドのJavaScriptの例である。この例では、ユーザーIDを入力してそのユーザーの残高と取引履歴を表示する機能を実装している。セキュリティを強化するために、以下の点を考慮した改良を行った。

  1. ユーザーIDの入力を検証し、不正な入力を防止する。
  2. APIへのリクエスト時に、CSRF(Cross-Site Request Forgery)トークンを含めてリクエストを送信する。
const userIdInput = document.getElementById('user-id-input');
const userDataDiv = document.getElementById('user-data');
const csrfToken = document.getElementById('csrf-token').getAttribute('content');

async function getUserData() {
    const userId = userIdInput.value.trim();
    if (!userId) {
        throw new Error('User ID is required');
    }
    const response = await fetch(`/user_data?user_id=${encodeURIComponent(userId)}`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrfToken
        },
    });
    if (!response.ok) {
        throw new Error(`Failed to fetch user data: ${response.status}`);
    }
    return await response.json();
}

async function displayUserData() {
    try {
        const userData = await getUserData();
        userDataDiv.innerHTML = `
            <h3>User ID: ${userData.user_id}</h3>
            <p>Balance: ${userData.balance}</p>
            <h4>Transaction History:</h4>
            <ul>
                ${userData.transaction_history.map(tx => `<li>${tx.sender} sent ${tx.amount} tokens to ${tx.receiver} at ${tx.timestamp}</li>`).join('')}
            </ul>
        `;
    } catch (error) {
        userDataDiv.innerHTML = `<p>Error: ${error.message}</p>`;
    }
}

document.getElementById('get-user-data-btn').addEventListener('click', displayUserData);
 

このフロントエンドでは以下の機能が含まれている。

  1. ユーザーが入力したユーザーIDを使用して、バックエンドのAPIエンドポイントからユーザーのデータを取得する機能がある。
  2. 取得したユーザーのデータを表示する機能がある。これには、ユーザーの残高と取引履歴が含まれる。
  3. バックエンドのAPIエンドポイントを通じて、ユーザーのデータを取得するためのfetchリクエストを行う機能がある。
  4. ユーザーIDの入力欄が空である場合や、リクエストが失敗した場合にエラーメッセージを表示する機能がある。

これにより、ユーザーは自分のデータを安全に取得し、トークンの送受信、残高、取引履歴などを管理することができる。

分析結果の表示ツール

分析結果をグラフ化したり、標にして表示したりという機能も後付けしたい。分析結果をグラフ化したり、統計的に表示するための機能を追加するには、JavaScriptのグラフ描画ライブラリを使用すると便利であろう。例えば、Chart.jsやD3.jsなどがよく使われる。以下は、Chart.jsを使用して分析結果を円グラフとして表示する例である。

// Chart.jsを読み込む
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

// チャートを表示するCanvas要素を用意
<canvas id="myChart" width="400" height="400"></canvas>

// チャートを描画するJavaScript
<script>
    // APIからデータを取得する関数
    async function getData() {
        const response = await fetch('/user_data');
        const data = await response.json();
        return data;
    }

    // チャートを描画する関数
    async function renderChart() {
        const data = await getData();
        const ctx = document.getElementById('myChart').getContext('2d');
        const myChart = new Chart(ctx, {
            type: 'pie',
            data: {
                labels: ['Love Action Level', 'Love Currency Received Rate', 'Goal Achievement Rate'],
                datasets: [{
                    label: 'Analysis Result',
                    data: [data.love_action_level, data.love_currency_received_rate, data.goal_achievement_rate],
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(255, 206, 86, 0.2)'
                    ],
                    borderColor: [
                        'rgba(255, 99, 132, 1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(255, 206, 86, 1)'
                    ],
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false
            }
        });
    }

    renderChart();  // ページロード時にチャートを描画
</script>
 

この例では、Chart.jsを使って円グラフを描画している。APIから取得したデータを元に、各項目の値をチャートに表示している。必要に応じて、表示形式やデータの取得方法を変更していけばよいのだろう。

 

 

いかがであろうか、これが自己分析ツールの概要だ。このような自己分析ツールは極めて重要である。自分の状態を客観的に知ることが出来るというのは貴重であるのだから。上記のフロントエンドで、自分が愛の行動レベル5を重点的に行ったにも関わらず、相手が受け取ってくれない、というような、愛の行動レベルごとの愛貨受け取り率などのようなものも分析できる。愛の行動レベルごとの愛貨受け取り率などの分析を行うことで、自身の行動の効果や改善の余地を見つけることができる。これにより、より意識的に行動を選択することができる。そのような分析結果をフロントエンドで視覚化することで、データの理解や活用がより容易になるだろう。