FlowStake

Activity Staking Blockchain Network

View the Project on GitHub

Activity Staking Blockchain Network

Flowstake V2

Core Concepts - Race / Performance Tracking

Validators - Proof of Activity as a Stake

Recording, Attesting, Hashing, Encrypting Activity Real Time

Requirements for Flowstake Smart Contracts

HTLC Smart Contract Race Payouts

PoS Activity Ledger

Creating a proof of stake (PoS) activity ledger involves documenting the various transactions and activities within a PoS blockchain network. Below, is an outline simplified ledger format for tracking PoS activities:

  1. Date and Time: Record the date and time of each activity.
  2. Block Number: Specify the block number associated with the activity.
  3. Validator/Public Key: Identify the validator or public key involved in the activity.
  4. Transaction Type: Describe the type of transaction or activity. This could include:
  1. Transaction Details:
    • For staking: Record the amount of tokens staked.
    • For reward distribution: Record the amount of rewards distributed.
    • For unstaking: Record the amount of tokens unstaked.
    • For slashing: Record the penalty amount.
  2. Validator Status: Indicate the status of the validator after the activity.
    • Active: Validator is actively participating in block validation.
    • Inactive: Validator is temporarily inactive, perhaps due to unstaking or penalties.
    • Slashed: Validator has been penalized for malicious behavior.
  3. Remarks/Notes: Include any additional information or notes regarding the transaction or validator status.

Sample PoS Activity Ledger:

Date & Time Block Number Validator/Public Key Transaction Type Transaction Details Validator Status Remarks/Notes
2024-03-01 12:00 10567 ABC123… Staking 1000 FST tokens Active Staked by Validator 1
2024-03-02 08:30 10580 XYZ789… Reward Distribution 50 FST tokens Active Rewards for Block 10568
2024-03-03 10:45 10600 DEF456… Unstaking 500 FST tokens Inactive Unstaked by Validator 2
2024-03-05 14:20 10610 GHI789… Slashing 20 FST tokens Slashed Penalty for Validator 3

Hashed Timelock Contract (HTLC)

Threshold Signature (TS)

Threshold signature scheme (TSS)

Hashed Timelock Contract (HTLC) + Threshold signature schema (TSS)

Advantages of Hashed Timelock Contracts

  1. Time-bound transactions Using a hashed timelock contract system ensures time-bound transactions. It guarantees the timely execution of transactions and hence, the timely execution and receipt of payments.

  2. Atomic swaps Using the HTLC system to settle transactions brings the ability to engage in atomic swaps to the table. An atomic swap is a form of smart contract technology that enables the settlement of cryptocurrency transactions without the use of central bodies, exchanges, or intermediaries. It ensures faster settlement of transactions without any middlemen.

  3. Minimize counterparty risk The primary advantage of HTLC payment settlements is the fact that it minimizes counterparty risk. Its basic function is to minimize counterparty risk by eliminating the “what ifs” of a transaction. It is done by hashlocks and timelocks, thereby ensuring that the settlement of a transaction is 100% ensured.

Smart Contracts for Flowstake

Smart Contract Lifecycle

The state transitions are triggered via a call to the Oracle (leading to accomplished or failed state), and Flowstake to close the challenge after donations have been withdrawn.

Smart Contract State

Data Oracle - Integration of .TCX Files from Strava using IPFS:

  1. Generate .TCX Files from Strava:
  1. Install and Utilize IPFS:
  1. Record Hashes and Distribute:

JSON Flowstake File Format - Parsing .TCX Files into JSON:

  1. Parse .TCX Files into JSON:
    • Develop a script (like the provided Python example) to parse .TCX files into the JSON format.
    • Extract relevant data such as activity ID, type, trackpoints (including time, position, heart rate, etc.).
    • Structure the data into a JSON format suitable for Flowstake.
  2. Example JSON Structure:

Importing Data - Data Ownership

To incorporate data from Strava, RunSignUp, and photographic attestation into the MVP for ETHDenver 2024, we need to enhance the functionality of the Flowstake platform. Here’s how we can integrate these components:

MVP Enhancements:

  1. Strava Data Integration: Fetch activity data from Strava using their API. Extract relevant details such as activity type, duration, distance, elevation, heart rate, and GPS coordinates.
  2. RunSignUp Integration: Retrieve race results and leaderboard data from RunSignUp using their API. Display race results and leaderboards for various running events within the Flowstake platform.
  3. Photographic Attestation: Allow users to upload photos as proof of their performance. Implement digital signature verification for photo attestation to ensure authenticity. Store photo attestation data securely on the blockchain.
  4. Enhanced JSON Flowstake File Format: Enhance the JSON structure to include data from Strava, RunSignUp, and photographic attestation. Add fields for Strava activity details, RunSignUp race results, and photo attestation information.
  5. User Interface Enhancements: Develop a user-friendly interface for users to interact with the Flowstake platform. Display Strava activity details, RunSignUp race results, and photo attestation status. Allow users to search for specific events, view leaderboards, and verify performance using photo attestation. Example JSON Structure (Enhanced):
{
  "activity": {
    "id": "1234567890",
    "type": "running",
    "start_time": "2024-01-28T08:00:00",
    "duration": "1:30:00",
    "distance": "10 km",
    "elevation_gain": "100 m",
    "heart_rate_avg": "150 bpm",
    "heart_rate_max": "180 bpm",
    "track_points": [
      {
        "time": "2024-01-28T08:00:00",
        "latitude": 40.7128,
        "longitude": -74.0060,
        "elevation": 10,
        "heart_rate": 150,
        "cadence": 160
      },
      {
        "time": "2024-01-28T08:05:00",
        "latitude": 40.7129,
        "longitude": -74.0061,
        "elevation": 15,
        "heart_rate": 155,
        "cadence": 162
      },
      ...
    ]
  },
  "runsignup_results": {
    "event_name": "10K",
    "finish_time": "0:44:39",
    "overall_rank": "9th",
    "age_group_rank": "3rd"
  },
  "photo_attestation": {
    "photo_url": "https://runsignup.com/Race/Results/134947/RaceDayPhotos?registrationId=74560064",
    "attestation_status": "verified",
    "verified_by": "Renat Razumov",
    "verification_date": "2024-03-01T10:00:00"
  }
}

Implementation Considerations:

Photo Attestation

Photo attestation for proof of human work with cryptographic consensus.

Photo Attestation with IPFS

from ipfshttpclient import connect
from web3 import Web3
from web3.middleware import geth_poa_middleware
import json

# Connect to your Ethereum node
web3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
web3.middleware_onion.inject(geth_poa_middleware, layer=0)

# Load your Ethereum contract ABI and address
contract_address = 'YOUR_CONTRACT_ADDRESS'
contract_abi = json.loads('YOUR_CONTRACT_ABI_JSON')

# Connect to your contract
contract = web3.eth.contract(address=contract_address, abi=contract_abi)

# Connect to IPFS
ipfs = connect('/ip4/127.0.0.1/tcp/5001/http')

# Function to upload photo to IPFS and get its hash
def upload_to_ipfs(file_path):
    with ipfs.add(file_path) as res:
        return res['Hash']

# Function to store IPFS hash in Ethereum contract
def store_hash_in_contract(ipfs_hash):
    # Your Ethereum account address which will interact with the contract
    account_address = 'YOUR_ACCOUNT_ADDRESS'

    # Unlock your Ethereum account
    web3.eth.default_account = account_address
    web3.personal.unlockAccount(account_address, 'YOUR_ACCOUNT_PASSWORD')

    # Call the smart contract function to store the IPFS hash
    tx_hash = contract.functions.storeHash(ipfs_hash).transact()
    tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash)
    print("Transaction receipt:", tx_receipt)

# Example usage
if __name__ == "__main__":
    file_path = 'path_to_your_photo.jpg'
    ipfs_hash = upload_to_ipfs(file_path)
    print("Uploaded photo to IPFS. Hash:", ipfs_hash)
    store_hash_in_contract(ipfs_hash)

Replace the placeholders with your Ethereum contract address, ABI, Ethereum account address, and password.

Make sure you have an Ethereum node running locally at http://localhost:8545, IPFS daemon running at 127.0.0.1:5001, and the necessary Python libraries installed (ipfshttpclient, web3).

This script uploads a photo to IPFS, retrieves its hash, and then stores the hash in an Ethereum smart contract. This way, you can reference the photo by its IPFS hash stored in the smart contract.


Theshold Signatures

Threshold signatures can be included in the code to facilitate group attestation by allowing multiple parties to jointly sign a message or data point. Here’s how you can integrate threshold signatures into your code:

  1. Choose a Threshold Signature Scheme: Threshold signature scheme that suits Flowstake requirements and security considerations. There are various threshold signature schemes available, including BLS (Boneh-Lynn-Shacham) threshold signatures, ECDSA (Elliptic Curve Digital Signature Algorithm) threshold signatures, and Schnorr threshold signatures.

  2. Implement Key Generation: Generate the necessary keys for the threshold signature scheme. This involves distributing shares of the private key among participating parties while retaining the public key. The key generation process should ensure that the threshold number of parties is required to reconstruct the private key.

  3. Message Signing: When a message or data point needs to be signed for group attestation, the threshold signature algorithm is executed. Each party holding a share of the private key contributes to the signature generation process. The signature is produced without revealing individual private keys.

  4. Signature Verification: The generated threshold signature can be verified using the corresponding public key. The verification process ensures that the signature is valid and authenticates the group attestation.

flowstake/bls

Here’s a simplified example of how to implement threshold signatures using the BLS BLS (Boneh-Lynn-Shacham) threshold signature scheme in JavaScript using the @chainsafe/bls library:

const { SecretKey, PublicKey, Signature } = require('@chainsafe/bls');

// Number of parties required for threshold signature
const threshold = 3;

// Generate secret keys for each party
const secretKeys = [];
for (let i = 0; i < threshold; i++) {
    secretKeys.push(SecretKey.fromKeygen());
}

// Aggregate secret keys to create a master secret key
const masterSecretKey = SecretKey.aggregate(secretKeys);

// Derive the corresponding public key
const publicKey = masterSecretKey.toPublicKey();

// Simulate message to be signed
const message = 'Group attestation message';

// Generate individual signatures from each party
const signatures = secretKeys.map(secretKey => Signature.sign(message, secretKey));

// Aggregate signatures to create a threshold signature
const thresholdSignature = Signature.aggregate(signatures);

// Verify the threshold signature using the public key
const isValid = thresholdSignature.verify(message, publicKey);

console.log('Threshold Signature:', thresholdSignature.toString());
console.log('Signature Verification:', isValid ? 'Valid' : 'Invalid');

Example Race Performance & Data Set

Data Oracle - For example .TCX files from Strava

Using IPFS (InterPlanetary File System) for hash-addressable content to record .TCX files from Strava is a viable option for ensuring data integrity and decentralized storage.

What is IPFS?

IPFS is a distributed system for storing and accessing files, websites, applications, and data. It works by creating a peer-to-peer network where each node stores a collection of hashed files. This means that files are addressed by their content, not by their location.

Recording .TCX Files from Strava on IPFS:

1. Generate .TCX Files from Strava:

Strava provides an API that allows to fetch activity data, including .TCX files, for individual workouts. Requires authentication with requests using OAuth 2.0 and then use the appropriate endpoints to download the .TCX files for the desired activities.

2. Install IPFS:

Install IPFS on local machine or set up a node on a server. IPFS provides instructions for installation and configuration on their website.

3. Add .TCX Files to IPFS:

Once the .TCX files are downloaded, add them to IPFS using the ipfs add command. This command will generate a unique hash for each file and store it in the IPFS network.

ipfs add file.tcx

4. Record Hashes:

Store the hashes generated by IPFS along with relevant metadata such as the activity type, date, and any other information you want to associate with the activity.

5. Distribute Hashes:

Then distribute these hashes through various means, such as storing them in a database, publishing them on a website, or sharing them through social media.

6. Accessing .TCX Files:

To access the .TCX files stored on IPFS, users can use the hash provided to retrieve the content through IPFS gateways or by running their own IPFS node.

Benefits of Using IPFS:

JSON Flowstake file format

{
  "activity": {
    "id_hash": "1234567890",
    "type": "running",
    "start_time": "2024-01-28T08:00:00",
    "total_time_seconds": 3600,
    "distance_meters": 10000,
    "calories": 500,
    "track_points": [
      {
        "time": "2024-01-28T08:00:00",
        "latitude": 40.7128,
        "longitude": -74.0060,
        "elevation": 10,
        "heart_rate": 150,
        "cadence": 160
      },
      {
        "time": "2024-01-28T08:05:00",
        "latitude": 40.7129,
        "longitude": -74.0061,
        "elevation": 15,
        "heart_rate": 155,
        "cadence": 162
      },
      ...
    ]
  }
}

Parse this .tcx file into JSON schema

import xml.etree.ElementTree as ET
import json

def parse_tcx_to_json(tcx_file):
    tree = ET.parse(tcx_file)
    root = tree.getroot()

    # Initialize dictionary to hold parsed data
    tcx_data = {
        "activity": {
            "id": root.find(".//Id").text,
            "type": root.find(".//Activity").attrib.get("Sport"),
            "track_points": []
        }
    }

    # Parse trackpoints
    trackpoints = root.findall(".//Trackpoint")
    for trackpoint in trackpoints:
        tp_data = {
            "time": trackpoint.find(".//Time").text,
            "position": {
                "latitude": float(trackpoint.find(".//LatitudeDegrees").text),
                "longitude": float(trackpoint.find(".//LongitudeDegrees").text),
                "elevation": float(trackpoint.find(".//AltitudeMeters").text)
            }
        }

        # Optional: Parse heart rate and cadence if available
        heart_rate = trackpoint.find(".//HeartRateBpm")
        if heart_rate is not None:
            tp_data["heart_rate"] = int(heart_rate.find(".//Value").text)

        cadence = trackpoint.find(".//Cadence")
        if cadence is not None:
            tp_data["cadence"] = int(cadence.text)

        tcx_data["activity"]["track_points"].append(tp_data)

    return tcx_data

if __name__ == "__main__":
    tcx_file = "your_tcx_file.tcx"
    json_data = parse_tcx_to_json(tcx_file)

    # Dump JSON data to a file
    with open("output.json", "w") as json_file:
        json.dump(json_data, json_file, indent=4)
{
  "metadata": {
    "time": "2023-10-14T12:59:31Z"
  },
  "tracks": [
    {
      "name": "11th Annual South Foster - 10K Race",
      "type": "running",
      "track_segment": [
        {
          "latitude": 41.785121,
          "longitude": -71.720606,
          "elevation": 163.0,
          "time": "2023-10-14T12:59:31Z",
          "heart_rate": 142
        },
        {
          "latitude": 41.785116,
          "longitude": -71.7206,
          "elevation": 163.0,
          "time": "2023-10-14T12:59:32Z",
          "heart_rate": 142
        },
        {
          "latitude": 41.785127,
          "longitude": -71.72059,
          "elevation": 163.0,
          "time": "2023-10-14T12:59:33Z",
          "heart_rate": 142
        },
        {
          "latitude": 41.785108,
          "longitude": -71.720605,
          "elevation": 162.9,
          "time": "2023-10-14T12:59:34Z",
          "heart_rate": 142
        },
        {
          "latitude": 41.785105,
          "longitude": -71.720617,
          "elevation": 162.8,
          "time": "2023-10-14T12:59:35Z",
          "heart_rate": 142
        },
        {
          "latitude": 41.785104,
          "longitude": -71.720619,
          "elevation": 162.8,
          "time": "2023-10-14T12:59:36Z",
          "heart_rate": 142
        },
        {
          "latitude": 41.785111,
          "longitude": -71.720615,
          "elevation": 162.8,
          "time": "2023-10-14T12:59:37Z",
          "heart_rate": 142
        }
      ]
    }
  ]
}

Extra Resources & Concepts

Theoretical Limitations of Performances

Top Speed

Sources

Testing the Cryptorun smart contract: a tale of obsessive perfection


FlowStake v1 + Hashrun

Flowstake V1

Proof of Activity v1

Data ownership, Content addressed storage, Hash addressed Activity Trackpoints IPFS has given the users the power of content-addressed storage. IPFS protocol generates secure & reliable records for proof of activity. Compiling trackpoints of GPS & accelerometer data from sensors on mobile & wearable devices. Parsing activity data into distributed encrypted ledgers with Blockchain technology.

Proof of Activity Smart Contract - Staking proof of activity events into escrow smart contracts with time based release to prove consistent, recoccuring runtime / activity on timechain. Trackpoint metrics analyze 1 minute segments - analyzing data for Max Accelration, Max Speed & Activity Duration

Linux / Ubuntu 18.04 Installation

Install Resources - Development Tools

IPFS.io

$ tar xvfz go-ipfs.tar.gz
$ cd go-ipfs
$ ./install.sh

Install Rustup

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown

CasperLabs Tech Spec

Generate Account / Faucet Tokens

Proof of Activity as a Stake - Key Value Storage

Step 3 - Check the value.

$ ./scripts/get.sh "Proof of Activity"

Step 4 - GraphQL

You can check the value of the counter using devnet’s GraphQL console: https://devnet-graphql.casperlabs.io Go to and then:

Step 5 - Get public key of your account

Step 6 - Query / Check the counter value.

FLOWSTAKE TO DO LIST

  1. API pull request from Strava for Athlete Activity with API Key Rate Limits - 600 requests every 15 minutes, 30000 daily

2.Export Activity / Create Subscription with Webhooks, cURL, Httpie or Postman.

  1. Generate Hash Addressed Proof of Activity with IPFS
  2. Write Hash into CASPER - DAG Blockchain
    flowstake@flowstake:~/casperlabs-kv-storage$ ./scripts/put.sh "activity" "QmV65a2mcsNt7V4LDekgAtLaLn8Eptc9L9yKVH2XSYc6Fk"
    Deployed with hash a096d6917bccc6df9f102f951e5ce68a3db15d49791405a6e28f557c7d6cbaa5
    
  3. Reference Activity Hashes with Blocks on CasperLabs DAG / BlockChain
    $ ./scripts/get.sh "Proof of Activity"
    
    • Value of the counter should be QmV65a2mcsNt7V4LDekgAtLaLn8Eptc9L9yKVH2XSYc6Fk.
  4. GraphQL Query for Proof of Activity Blocks Write your query or mutation here
    # Proof of Activity - IPFS & Casper Key Value Storage
    query {
      globalState(
     blockHashBase16Prefix: "f6836d87da9f9efc7a5fe7707f894f7be225e8e19cbf61954a2870c58bdbb966"
     StateQueries: [
       {
         keyType: Address
         keyBase16: "64d0c86f888e925731cae4398c6ea86d26a14e2574e70b36bd4eeaec3a292cde"
         pathSegments: ["QmV65a2mcsNt7V4LDekgAtLaLn8Eptc9L9yKVH2XSYc6Fk"]
       }
     ]
      ) {
     value {
       __typename
       ... on IntValue {
         int: value
       }
     }
      }
    }
    
    • Flowstake Public Key - Base(16)
    • 74172b5a649058a6b6048b7a1d1d527369ce20b1f7a2d262836bdc9889582689

Extra Resources & Development Tools

Strava API Settings

Install httpie

Below is an example request to the Strava API using HTTPie, along with sample response headers for a successful and rate-limited request:

Example request

$ http 'https://www.strava.com/api/v3/athlete' \
    'Authorization:Bearer d4cc0724eed83ffddcb8715d7fd83d3588724cc5'

Docker Runtime Container

Both GPX (GPS Exchange Format) and TCX (Training Center XML) are file formats commonly used in the context of GPS and fitness-related activities to store and exchange data. These formats are used to represent information about tracks, waypoints, routes, and other related data gathered during activities like running, cycling, hiking, or any other outdoor pursuits.

GPX (GPS Exchange Format):

XML-based Format: GPX is an XML-based format, which means it uses a structured markup language to store data in a human-readable and machine-readable way.

Compatibility: GPX is widely supported by various GPS devices, applications, and online platforms. It has become a standard format for exchanging GPS data.

Data Types: GPX files can contain information about waypoints (specific locations), tracks (sequences of points that make up a route), and routes (predefined paths). It can also include additional data such as timestamps, elevation, and more.

Open Standard: GPX is an open standard, which means that the specifications for the format are publicly available. This openness promotes interoperability and compatibility across different systems.

Example:

xml

<gpx version="1.1" creator="Some Application">
  <trk>
    <name>Example Track</name>
    <trkseg>
      <trkpt lat="37.1234" lon="-122.5678">
        <ele>1000</ele>
        <time>2023-11-03T12:00:00Z</time>
      </trkpt>
      <!-- Additional track points go here -->
    </trkseg>
  </trk>
</gpx>

TCX (Training Center XML):

Specifically Designed for Fitness Data: TCX is a proprietary XML-based format developed by Garmin specifically for storing fitness-related data. It is commonly used for activities such as running, cycling, and other workouts.

Data Types: TCX files focus on fitness-related data, including information about laps, heart rate, speed, cadence, and power. It’s more tailored to the needs of athletes and fitness enthusiasts.

Compatibility: While TCX is widely supported by Garmin devices and software, it may not be as universally recognized as GPX. However, many fitness applications and platforms can import and export TCX files.

Example:

xml

<TrainingCenterDatabase>
  <Activities>
    <Activity Sport="Running">
      <Lap StartTime="2023-11-03T12:00:00Z">
        <TotalTimeSeconds>3600</TotalTimeSeconds>
        <!-- Additional lap data goes here -->
      </Lap>
    </Activity>
  </Activities>
</TrainingCenterDatabase>

In summary, GPX is a more generic and widely adopted format for GPS data exchange, while TCX is specifically designed for fitness-related activities with a focus on data commonly associated with workouts and training. The choice between the two depends on the devices and applications you are using and their compatibility with each format. Many platforms and tools support both formats, allowing users flexibility in choosing the one that best fits their needs.