# Introduction to Witness Chain

Powering Real-World Verification with InfinityWatch

WitnessChain is building the future where autonomous AI systems can seamlessly orchestrate real-world actions—verifiably, securely, and for the greater good. The disconnect between digital intelligence and the real physical world is no longer. InfinityWatch enables humans to carry out actions in the real-world requested by autonomous systems and verify if they have been done. We empower innovators to create “Autonomous Real Apps”—applications that leverage verified real-world activity to solve global challenges, unlock new opportunities, and drive innovation at scale.

## What is Witness Chain's InfinityWatch Network? <a href="#what-is-eigenlayer" id="what-is-eigenlayer"></a>

The **InfinityWatch Network** is a layer of decentralized watchtowers designed to observe, verify, and transform real-world events into trusted digital proofs. These proofs serve as the foundation for new services, applications, and ecosystems that require high-confidence data from the physical world.

InfinityWatch operates on the principle of **Proof of Location**, enabling trust in space and time. By validating real-world tasks, it acts as a robust coordination layer for humanity, ensuring that physical actions—such as humanitarian aid deliveries or environmental monitoring—are verifiable and accountable. By translating unverified real-world attributes into trusted digital proofs, InfinityWatch also empowers decentralized physical infrastructure networks (DePIN) to innovate and scale with confidence.

{% hint style="success" %}
**Status:**&#x20;

**We are live on mainnet!**
{% endhint %}

## Why Use Witness Chain's InfinityWatch?

Building any app that needs real physical world observations and/or performs tasks in the real world - InfinityWatch not only gives you access to provably verified observations, it also enables you to bootstrap and scale your real-world operations.

The platform relies on three core systems: Proof of Location, the InfinityWatch app, and the Autonomous Real app interface.

1. **Proof of Location**
   1. Proof of Location is a decentralised  BFT proof of "geolocation", which can be used to validate the geographical location of a "prover" device connected to Internet.
   2. The Participation and challenging are both permission-less, anyone can trigger a PoL challenge on any node in the network using the [challenge api](/infinity-watch/apis/challenge-apis)
2. **InfinityWatch app**
   1. The InfinityWatch app allows anyone to capture reality to generate verifiable digital evidences to real world actions.&#x20;
   2. This netowrk is also permissionless and accessible to any AI or projects who'd want to run campaigns or real world verified witnesses
3. **Autonomous Real app interface**
   1. Coming soon!

## Unlocking the Potential of Real Apps

With InfinityWatch, Witness Chain is creating a future where real-world actions are verifiable and secure. By empowering developers, innovators, and infrastructure providers, InfinityWatch lays the foundation for a new era of decentralized coordination—one where trust in real-world activity unlocks the true potential of AI and beyond.

***

**Ready to Build?** Explore our documentation to get started with Witness Chain’s InfinityWatch Network and begin building the next generation of Real Apps.<br>


# Decentralized Image Verification Service

### **Overview**

The **Decentralized Image Verification Service (DIVS)** is a trustless, network-driven platform designed to&#x20;

* verify the authenticity of the claims referred in images shared across the internet.&#x20;
* Spot celebrities in photos
* Identify deepfakes&#x20;
* Describe an image
* Summarize a video
* and more..

Using a distributed network of inference providers running advanced **Vision-Language Models (VLMs)**, DIVS allows developers, fact-checkers, and applications to request independent, verifiable assessments of whether an image supports a given claim—without relying on a **single centralized authority.**

By leveraging the power of **decentralized computation and VLMs, consensus mechanisms, and backed by EigenLayer's crypto-economic security**, DIVS provides a censorship-resistant and scalable foundation for truth verification in visual content.

***

### **What It Solves**

The internet is flooded with images that contain **textual claims, captions, or embedded information**, often spreading **misinformation** rapidly. Today, verifying these claims is:

* **Centralized:** Controlled by a few big platforms or organizations.
* **Opaque:** Lacking transparency in how decisions are made.
* **Slow:** Manual fact-checking cannot keep pace with viral image content.

DIVS solves this by creating a **trustless verification marketplace** where:

* Anyone can **submit an image and a textual claim** to verify.
* Independent node operators run **VLMs to analyze the image** and return factual verdicts.
* A **consensus score** is derived from multiple independent model results. (In Progress)
* Builders get a **fast, transparent, and verifiable API response**, usable in apps, bots, and extensions.

This creates an **open and scalable truth layer for the visual web.**

***

### **How It Works (High-Level)**

1. **Task Submission:** A Builder (developer) calls the DIVS API with an image and a claim to verify.
2. **Task Distribution:** The request is sent to a **decentralized network of Node Runners (aka Watchtowers)** running open VLMs.
3. **Parallel Processing:** Each node analyzes the image independently and submits a verification verdict with confidence scores.
4. **Consensus Engine:** The system aggregates responses, filters out malicious actors, and computes a **final trust score and verdict**. (Work in Progress)
5. **Result Delivery:** The Builder receives a **JSON response** containing verdict, confidence, and references (if available).

This design ensures **speed, transparency, and neutrality**—no single entity controls truth verification.

***

### **Who Should Read This**

* **🔹 Builders (API Consumers)** – Developers building apps, bots, extensions, and platforms that need **automated claim verification** for images. If you want to integrate truth-checking into your products, start here.
* **🔹 Node Runners (Compute Providers)** – Individuals or organizations operating GPU-enabled infrastructure willing to run **DIVS VLM nodes** and contribute to a **trustless verification network**.

Both groups are essential to the ecosystem: Builders generate demand, Node Runners supply decentralized computation.

***

### **Quick Links**

* 🚀 [**Get Started for Builders →**](/infinity-watch/proof-of-model-testnet/for-builders)
* ⚡ [**Get Started for Node Runners →**](/infinity-watch/proof-of-model-testnet/for-node-runners)


# For Builders

### **Introduction**

The **DIVS Python SDK** enables developers to integrate **trustless image claim verification** directly into their applications, bots, browser extensions, or moderation tools. This guide helps you make your **first verification request in under 5 minutes**, giving you access to decentralized image analysis powered by independent Vision-Language Model (VLM) nodes.

***

### **1️⃣ Prerequisites**

Before you start, you’ll need:

* ✅ An **account on Witness Chain:** [Sign up here](https://playgrounds.infinitywatch.ai/)
* ✅ An **API key** : Generate from this [dashboard](https://playgrounds.infinitywatch.ai/manage-apis)

<figure><img src="/files/yeJ3ttND8tvv3PmPnzeM" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Copy the generated key (prefixed `wtns_`)
{% endhint %}

* ✅ A **Python 3.10.17+ environment**

```
python -m venv witnesschain_env
source witnesschain_env/bin/activate
python --version 
python3 --version 
pip --version
```

* ✅ A publicly accessible image URL or base64-encoded image

***

### **2️⃣ Install the SDK**

Install the official Witness SDK via PyPI

```bash
pip install witnesschain
```

Verify installation:

```bash
python -c "import witnesschain; print('witnesschain imported successfully')"
```

***

***

### 3️⃣ **Verify Your Image**

#### **Option 1 – Public Image URL**

```python
import asyncio
from infinitywatch import Infinitywatch

API_KEY = "YOUR_WITNESSCHAIN_DIVS_KEY_HERE"

async def main():
    client = Infinitywatch(api_key=API_KEY)

    async for node_response in client.query(
        "what does this image suggest?",
        models=["Qwen/Qwen2.5-VL-7B-Instruct"],
        inputs=["https://img.freepik.com/premium-psd/peanut-butter-png-transparent_955012-13366.jpg?w=360"],  # Publicly accessible URL
    ):
        print(node_response.model_response)

if __name__ == "__main__":
    asyncio.run(main())
```

***

#### **Option 2 – Local File Path (from your script's directory)** ✅

```python
import asyncio
from infinitywatch import Infinitywatch

API_KEY = "YOUR_WITNESSCHAIN_DIVS_KEY_HERE"

async def main():
    client = Infinitywatch(api_key=API_KEY)

    async for node_response in client.query(
        "what does this image suggest?",
        models=["Qwen/Qwen2.5-VL-7B-Instruct"],
        inputs=["./peanut-butter.png"],  # Local file in the same directory
    ):
        print(node_response.model_response)

if __name__ == "__main__":
    asyncio.run(main())
```

***

#### **Option 3 – Base64-Encoded Image**

```python
import asyncio
import base64
from infinitywatch import Infinitywatch

API_KEY = "YOUR_WITNESSCHAIN_DIVS_KEY_HERE"

async def main():
    client = Infinitywatch(api_key=API_KEY)

    # Convert image to base64
    with open("./peanut-butter.png", "rb") as f:
        img_base64 = base64.b64encode(f.read()).decode("utf-8")

    async for node_response in client.query(
        "what does this image suggest?",
        models=["Qwen/Qwen2.5-VL-7B-Instruct"],
        inputs=[img_base64],  # Base64 string instead of file path
    ):
        print(node_response.model_response)

if __name__ == "__main__":
    asyncio.run(main())
```

***

✅ **Key Points:**

* You can pass **URLs**, **local file paths**, or **base64 strings** interchangeably in `inputs=[...]`.
* Local files are easiest for dev environments; URLs are useful for remote images; base64 works well for in-memory or private images.

***

### 4️⃣ **Sample Output**

```
InfinitywatchNodeResponse (
   node_id='IPv4/0x0b54e605b867eba82602fee2dfcb76204177fe0a', 
   model_response='The image suggests a spoonful of peanut butter, which is often associated with    snacks or meals that include this popular spread.', 
   model='Qwen/Qwen2.5-VL-7B-Instruct', 
   challenge_id='394f4756-c390-4587-be7b-1e35c736b056'
)
```

***

### **5️⃣ Advanced Usage**

#### Verify Multiple Images

```python
async for resp in client.query(
    "Describe what’s happening in these frames.",
    models=["HuggingFaceTB/SmolVLM2-2.2B-Instruct"],
    inputs=["./frame1.jpeg", "./frame2.jpeg", "./frame3.jpeg"],
):
    ...
```

***

#### Custom options

```python
async for resp in client.query(
    "Summarize this diagram.",
    models=["THUDM/GLM-4.1V-9B-Thinking"],
    inputs=["https://example.com/image.png"],
    model_parameters = {
        max_tokens=512,              
        temperature=0.3,
    }             
):
    ...
```

***

### **6️⃣ Best Practices**

* **Cache Results:** Avoid repeated verifications for the same image+claim pair.

***

### **7️⃣ Example Use Cases**

* **Fact-checking bots:** Validate viral images before sharing.
* **News authenticity tools:** Detect manipulated or miscaptioned images.
* **Moderation pipelines:** Flag potentially misleading visuals.
* **Browser extensions:** Give end-users quick access to decentralized verification results.

***

### **8️⃣** Troubleshooting

* **`ModuleNotFoundError: No module named 'witnesschain'`** Ensure you ran `pip install witnesschain` in the same environment.
* **Authentication errors**
  * Check that `WITNESSCHAIN_API_KEY` matches exactly the string on your dashboard.
  * Confirm you haven’t accidentally revoked the key or has been expired.
* **Slow or no responses**
  * Verify your network connectivity.
  * Check the challenge\_id for more insights

***


# For Node Runners

## **Introduction**

As a **Node Runner**, you contribute GPU-powered computation to the **DIVS decentralized network**, running **Vision-Language Models (VLMs)** to verify claims in images submitted by Builders.

Node Runners help build a **trustless, censorship-resistant truth layer for online images**.

This guide walks you through installing the node client, configuring your compute resources, and starting your first verification tasks.

***

## **1️⃣ Prerequisites**

✅ **Hardware Requirements:** We support a range of models — from GPU-hungry giants to ones that can chill on your laptop.

* **GPU (recommended):** NVIDIA with CUDA is ideal. More VRAM = happier models.
* **CPU (possible):** 4+ cores, but It’ll work… eventually. Great time to grab a coffee. Or two.
* **RAM:** At least 8GB. For bigger models, 16GB+ is safer.
* **Architecture**: x86\_64 and ARM supported (some models prefer x86 + CUDA).
* **Disk:** 120+ GB free space for keeping things comfy

✅ **Software Requirements**

* **Docker (v20+)** for containerized setup. That’s it. No additional installs or builds — just pull the image and run.

✅  **Network Requirements**

Our protocol uses peer-to-peer communication over UDP.

* **Ports:** Open **UDP ports 12000–12009** on your router or firewall.
* **Connectivity:** A stable public internet connection is best. NAT traversal is attempted, but port forwarding is recommended.
* **Docker note:** Make sure Docker can expose the above ports correctly.

✅ **DIVS Wallet Configuration**

* **Automatic:** Node keys are auto-generated on first run.
* **Optional override:** You can supply your own key using environment variables when starting the container.

***

## **2️⃣ Run the DIVS node**

### Create a Volume&#x20;

So that the node will not pull models again and again

```
docker volume create wtns-vol
```

### 🚀 Option 1: With NVIDIA GPU (Recommended) <a href="#option-1-with-nvidia-gpu-recommended" id="option-1-with-nvidia-gpu-recommended"></a>

For the best performance and support for larger models, run your Watchtower using a CUDA-enabled NVIDIA GPU:

```
docker run \
 -d \
 --gpus all \
 --network=host \
 -v wtns-vol:/root \
 -e WALLET_PUBLIC_KEY=0x_your_key_here \
 -e MODEL_NAME=MODEL_NAME \
 -e NETWORK=testnet \
 --name mywatchtower \
 witnesschain/infinity-watch-nvidia:2.0.0
```

### 🧪 Option 2: CPU-Only (Lightweight Model) <a href="#option-2-cpu-only-lightweight-model" id="option-2-cpu-only-lightweight-model"></a>

No GPU? You can still join the network by running a smaller model on your CPU:

```
docker run \
 -d \
 -v wtns-vol:/root \
 -e WALLET_PUBLIC_KEY=0x_your_key_here \
 -e MODEL_NAME=MODEL_NAME \
 -e NETWORK=testnet \
 --name mywatchtower \
 witnesschain/infinity-watch:2.0.0
```

{% hint style="info" %}
Note: if you want to use your own private key for your watchtower,  add the environment variable PRIVATE\_KEY in your docker run command

-e PRIVATE\_KEY="your\_custom\_private\_key"
{% endhint %}

### **Models Supported**

Following are the models we support as of now. Use the below models to pick one for the MODEL\_NAME variable.

{% hint style="success" %}
We keep adding models frequently. If you want to add your model to the list, write to us at <support@witnesschain.com>
{% endhint %}

<table><thead><tr><th width="479.91796875">🤗 HuggingFace family </th><th align="center">RAM Requirement</th></tr></thead><tbody><tr><td>HuggingFaceTB/SmolVLM2-2.2B-Instruct</td><td align="center">6 GB</td></tr><tr><td>HuggingFaceTB/SmolVLM-500M-Instruct</td><td align="center">2 GB</td></tr><tr><td>HuggingFaceTB/SmolVLM-256M-Instruct</td><td align="center">1 GB</td></tr></tbody></table>

<table><thead><tr><th width="479.5625">🔮 Qwen Family</th><th align="center">RAM Requirement</th></tr></thead><tbody><tr><td>Qwen/Qwen2.5-VL-7B-Instruct</td><td align="center">16 GB</td></tr><tr><td>Qwen/Qwen2.5-VL-3B-Instruct</td><td align="center">8 GB</td></tr></tbody></table>

<table><thead><tr><th width="480.06640625">🧠 GLM Family</th><th align="center">RAM Requirement</th></tr></thead><tbody><tr><td>zai-org/GLM-4.1V-9B-Thinking</td><td align="center">22 GB</td></tr></tbody></table>


# Proof of Location (Mainnet)

{% hint style="success" %}
LIVE on MAINNET
{% endhint %}

## What is Proof-of-Location?

Proof of Location is a decentralised proof of "geolocation", which can be used to validate the geographical location of a "prover" device connected to Internet.

## Why is Proof-of-Location required ?

![](/files/17j1OcV41cO9BgTvNAxN)![](/files/e2I1CSpqvPqkiAuZddzp)

A trust-free Proof of Location is beneficial for decentralized physical infrastructure networks that offer services like storage, GPU compute, wireless connectivity, and energy distribution. These networks rely on decentralized nodes to provide essential services without centralized control, making trust and verification critical challenges. Here’s why Witness Chain's trust-free Proof of Location is helpful in these contexts:

1. **Enhanced Security and Fraud Prevention**:
   * In decentralized storage networks, nodes store data on behalf of users. Trust-free Proof of Location ensures that storage nodes are actually located where they claim, preventing nodes from pretending to be in multiple locations to illicitly gain more contracts or compromise data redundancy.
   * For GPU compute networks, users want to ensure that their computational tasks are executed in specific jurisdictions or regions due to regulatory or performance reasons. Trust-free location proofs prevent compute nodes from spoofing their location to bypass these restrictions.
2. **Efficient Resource Allocation**:
   * **Energy Distribution**: In decentralized energy networks (like those trading solar power), Proof of Location ensures that energy is being produced and consumed in the claimed locations. This is crucial for balancing local energy grids and for regulatory reporting.
   * **Wireless Networks**: For decentralized wireless networks, trust-free Proof of Location helps in dynamically allocating bandwidth and other resources based on the verified locations of users and equipment. This optimizes network performance and access without a central managing authority.
3. **Operational Integrity and Compliance**:
   * **Regulatory Compliance**: Many regions have specific regulations about where data can be stored and where compute tasks can be processed. Proof of Location helps ensure that nodes comply with these legal requirements, enabling operations in sensitive industries like healthcare and finance.
   * **Auditability**: Blockchain-based Proof of Location creates an immutable record of the locations of nodes over time. This helps in auditing and verifying that the network has operated within the expected parameters, which is important for both regulatory compliance and internal audits.
4. **Automated Smart Contracts**:
   * Decentralized networks often use smart contracts to manage interactions between nodes automatically. Trust-free Proof of Location can trigger these contracts when a node enters a specific area or meets certain location-based conditions. For instance, an energy network could use smart contracts to automatically buy or sell excess power when a node (like a battery or solar panel) is verified to be in an area of high demand.
5. **Enhancing User Trust**:
   * By providing a trust-free mechanism for proving location, users and participants in the network can have greater confidence in the services provided. This increases user adoption and participation, as stakeholders know that the system is resistant to manipulation and fraud.
6. **Scalability and De-centralization**:
   * Trust-free Proof of Location allows the network to scale without a corresponding increase in vulnerability to location-based attacks or the need for a central authority to verify location data. As more nodes join the network, maintaining decentralized integrity and verification remains manageable.
7. **Optimized Network Performance**:
   * In GPU compute networks, tasks can be routed to nodes with the necessary computational resources nearest to the data source, minimizing latency. Trust-free Proof of Location ensures that these optimizations are based on accurate data.
   * For storage networks, data can be replicated across nodes in different geographical locations to enhance accessibility and redundancy. Proof of Location ensures that this replication strategy respects actual geographic constraints and benefits.
8. **Interoperability and Flexible Participation**:
   * A standardized Proof of Location mechanism allows different types of physical infrastructure to interact and coordinate more smoothly. For example, energy systems can interact with storage systems when both can reliably report their locations, leading to more efficient cross-sector operations.
9. **Incentive Mechanisms**:
   * In decentralized networks, participants are often rewarded based on their contributions. Proof of Location can be used to verify that participants are indeed contributing from the locations they claim, ensuring that incentives and rewards are distributed fairly.
10. **Location-Based Dynamic Pricing**:
    * **Energy Trading**: In decentralized energy networks, Proof of Location can facilitate dynamic pricing based on the geographic demand and supply. For example, energy produced in areas with surplus renewable energy can be priced differently compared to areas with high demand. DeFi mechanisms can enable automatic trading and settlement of energy tokens based on real-time location data.
    * **Storage and Compute Resources**: Prices for decentralized storage or GPU compute can vary based on the location of the requester and the provider. Proof of Location ensures that these services are billed accurately, and smart contracts can adjust prices in real-time as the availability and demand change geographically.
11. **Automated Location-Based Smart Contracts**:
    * **Insurance**: DeFi can offer parametric insurance products that automatically settle based on location-specific events. For example, a smart contract could release funds to insured farmers if drought conditions are verified in their location, without any manual claims process.
    * **Logistics and Supply Chain**: In logistics, Proof of Location can trigger payments and update financing based on the goods reaching certain geographic checkpoints. DeFi can facilitate quick, trust-free payments to logistics providers when goods are verifiably delivered to the right location.
12. **Enhanced Liquidity and Collateralization**:
    * **Asset Tokenization**: Physical assets, including real estate, vehicles, or machinery, can be tokenized based on their location. Proof of Location helps verify these assets’ existence and current position, enabling them to be used as collateral in DeFi lending platforms or for issuing location-specific asset-backed tokens.
    * **Flexible Financing**: For decentralized physical assets like energy storage systems or shared equipment, Proof of Location combined with DeFi can create flexible financing models where investors can fund assets based on their utilization and location, receiving returns based on actual usage data.
13. **Geofencing and Access Control**:
    * **Subscription Services**: Access to certain services or resources can be controlled based on location. For instance, a DeFi protocol can manage subscriptions to WiFi networks or shared facilities, with smart contracts granting access only when the user’s location is verified.
    * **Conditional Access**: In shared economies, access to vehicles, equipment, or even buildings can be managed via DeFi smart contracts that check Proof of Location before granting usage rights or unlocking the asset.
14. **Decentralized Verification and Governance**:
    * **Community Operations**: For community-driven services like local energy grids or cooperative storage solutions, Proof of Location ensures that participants are actually part of the local community. This can be integrated into DeFi models where voting rights and governance tokens are distributed based on verified participation in specific locations.
    * **Dispute Resolution**: In DeFi protocols where disputes might arise from service quality or delivery, Proof of Location can provide tamper-proof evidence that can be used in decentralized arbitration processes.
15. **Risk Assessment and Mitigation**:
    * **Real-Time Data for Underwriting**: Insurers and financial providers can use real-time location data to assess risks more accurately. For instance, properties or assets in areas prone to natural disasters can have their policies and premiums dynamically adjusted based on data verified through Proof of Location.
    * **Operational Risk Management**: For decentralized networks providing critical services, Proof of Location helps assess and manage operational risks by ensuring that infrastructure is not placed in high-risk zones without appropriate mitigations.

In conclusion, a trust-free Proof of Location is a foundational element for decentralized physical infrastructure networks, enhancing their security, efficiency, and compliance while fostering trust among users and enabling robust, scalable, and transparent operations across storage, compute, wireless, and energy services.

&#x20;


# Introduction

Introduction to Proof of Location

{% hint style="success" %}
Live on MAINNET!
{% endhint %}

> Proof of Location is a decentralised proof of "geolocation" which can be used to validate the geographic location of a "prover" node connected to Internet.

## **tl;dr**

A prover (a node providing storage or compute or any service) asserts or claims their geographic location. This claim is verified by a network of watchtowers : decentralized set of nodes globally. This protocol relies on analyzing internet latency to determine the prover's location .&#x20;

## How does it work?

The protocol involves two key steps:

* Calibration&#x20;
* Measurement

### Calibration Phase

1. The protocol comprises a **prover**, whose location is to be validated and a decentralized set of **watchtowers**, whose location are known a priori
2. In calibration phase, the watchtowers measure Internet delay to each other via application layer UDP pings
3. A watchtower then calibrates delay to distance mapping for itself using the delay measurements and the location of other watchtowers

### Measurement Phase

1. In the measurement phase, the location claim of the prover is validated
2. The watchtowers measure delay to the prover using application layer UDP pings
3. Using the delay to distance mapping obtained during calibration phase, each watchtower outputs a region where the prover can be present
4. Our protocol aggregates the output across different watchtowers and then outputs the maximum distance that the prover can be from its claimed location

## <mark style="color:blue;">Key Parties Involved</mark>  <a href="#parties-involved" id="parties-involved"></a>

1. **Payer:** A party who pays for the challenge and starts one
2. **Prover:** The device connected to Internet whose location needs to be validated
3. **Blockchain full-node:** Decentralised ledger for recording all the challenge requests and outcomes
4. **Watchtowers:** A pool of decentralized nodes that validate the location claim of the prover
5. **Challenge coordinator:** Centralised services for&#x20;
   1. Communication between the parties
   2. Computing challenge meta data; and&#x20;
   3. Cnteracting with the ledger
6. **Broker:** Centralized API service layer&#x20;

## <mark style="color:blue;">Functional description</mark> <a href="#functional-description-of-the-protocol" id="functional-description-of-the-protocol"></a>

Functionally the different components involved in Proof of Location challenge are similar to that of [Proof of Backhaul](/archive/proof-of-bandwidth/introduction#functional-description-of-the-protocol). The different steps in a Proof of Location challenge remain similar to the [Proof of Backhaul](/archive/proof-of-bandwidth/introduction#challenge-execution), except during challenge execution, the measurement phase described above to validate prover's location is carried out instead of measuring the backhaul in Proof of Backhaul.

## <mark style="color:blue;">Trust and Threat Model (current)</mark> <a href="#trust-and-threat-model-for-pob-v1.0" id="trust-and-threat-model-for-pob-v1.0"></a>

The trust assumptions for challenge coordinator remain same to [Proof of Backhaul](/archive/proof-of-bandwidth/introduction#challenge-coordinator)

### **Prover**

1. The prover can claim a false location&#x20;
2. The prover can inflate the ping delays to the watchtower during measurement phase of challenge execution

### **Watchtowers**

1. In current version of Proof of Location, the challengers are a mix of trusted and trust-free nodes.&#x20;
   1. They report their correction location&#x20;
   2. They do not inflate delays to other watchtowers in calibration phase
   3. They use a correct delay to distance mapping in measurement phase
2. In future, our Proof of Location protocol will be able to tolerate a certain fraction of adversarial watchtowers, where the above trust assumptions will be relaxed


# Process flow

Describes the sequence of steps involved in a PoL challenge

<figure><img src="/files/Hjp08WEB1Zbe278Tpubv" alt=""><figcaption></figcaption></figure>


# Architecture

<figure><img src="/files/keRonD7mdDtkpyNWW40q" alt=""><figcaption></figcaption></figure>

## Challenger Selection Logic for Decentralized Proof of Location

This technical note describes the logic and constraints for selecting challenger nodes in a decentralized proof of location (PoL) system. The selection process ensures that challengers are both active and capable of participating in the verification process.&#x20;

{% hint style="info" %}
The selection process is currently centralized, carried out by the Challenge Coordinator
{% endhint %}

### <mark style="color:blue;">Inclusion Criteria</mark>

#### 1. Activity Status

* Challengers must have been active within the last 60 seconds
* This ensures only currently available nodes are selected for challenges

#### 2. Wallet Requirements

* All challengers must have an associated wallet address
* Wallet address is used for:
  * Identity verification
  * Transaction signing

#### 3. IP Address Rules

**If Prover with Private IP**

* Only challengers with public IP addresses are eligible
* This ensures reliable communication paths
* Prevents potential NAT traversal issues

**If Prover with Public IP**

* Both public and private IP challengers are eligible
* Allows for greater network participation
* Must still meet other selection criteria

### <mark style="color:blue;">Exclusions</mark>

#### 4. Participation Status

* Paused devices are excluded
  * Prevents selection of maintenance mode devices
  * Allows nodes to opt-out temporarily
* Currently active challengers are excluded
  * Prevents concurrent challenge participation
  * Ensures resource availability

#### 5. Geographic Constraints

* Maximum distance: 2000 kilometers from the prover. Determined by the `lat, long` config&#x20;
* Distance calculation:
  * Based on registered coordinates in the initial setup phase
  * Uses great circle distance formula
* Purpose:
  * Ensures realistic challenge timeframes
  * Reduces network latency impact
  * Maintains challenge credibility

#### 6. Selection Limits

* Maximum of 128 challengers per challenge
* Self-selection prevention:
  * Prover cannot be selected as its own challenger
  * Verified via public key comparison


# Run a watchtower!

Introduction to participation in witness chain Infinity Watch!

### Join the Decentralized Network Revolution

Behold the **watchtowers**!![👀](https://abs-0.twimg.com/emoji/v2/svg/1f440.svg)\
In an age where truth is as rare as a quiet day on the internet, the watchtowers stand, not just as relics of the past but as Guardians of Verity. And now, with Witness Chain, you too can join the ranks, for in the future, every witness can be a beacon of truth!&#x20;

Are you passionate about networking and have extra bandwidth to share? If so, you may be the perfect candidate to become a  watchtower. By utilizing your unused bandwidth, you can engage in decentralized speed tests and location challenges. Join us in shaping the future!

## Become a watchtower for Location Proofs

**What You Need**

* **Unused Bandwidth:** Utilize your excess bandwidth to support network challenges.
* **Machine Specification**: A machine **comparable to an AWS t2 micro (1 vcpu, 1GB RAM and 5GB harddisk)**, though we recommend 2 cores, 4 GB RAM and 10 GB of storage.
* **Network Equipment:** Ensure you have reliable networking hardware to participate in the challenge effectively.&#x20;
* **Interest in Decentralized Networks:** A passion for contributing to de-centralized networks and enhancing their security and efficiency.

**How It Works**

1. **Register Your Watchtower:** Sign up as a Node Operator on Witness Chain's Infinity Watch by registering your watchtower. Provide details about your geographic location. Specific details are specified in the next section.
2. **Participate in Challenges:** Your node will participate in network challenges on provers that require Proof of location. These challenges help verify the integrity and reliability of the participating nodes.

**The next section details the technical steps in running a Proof of Location Watchtower client**


# For Partner node runners

Steps to run a Witness Chain watchtower

In an age where truth is as rare as a quiet day on the internet, the watchtowers stand, not just as relics of the past but as Guardians of Verity. And now, with Witness Chain, you too can join the ranks, for in the future, every witness can be a beacon of truth!&#x20;

There are many simple ways to participate with witnesschain, the next few pages explore them one by one!


# Running on Akash Cloud

Steps to run a Witness Chain watchtower client (PoL Watchtower Client) on Akash network

The PoL Watchtower Client Node is a DePIN Challenger node that participates in the PoL (Proof-of-Location) protocol and measures the location claims made by a DePIN Prover.

PoL Watchtower Client Nodes can be run on community members’ laptops, desktops or even on cloud instances. As long as the node is running, there is a probabilistic algorithm that determines if the node will participate in a PoL challenge from the network.&#x20;

Before a node can participate in the protocol, it has to prove it's own capabilities (run a prover to prove it's own location - this mechanism is inbuilt in the challenger client container)

You can now run the watchtower directly on [Akash network](https://akash.network/)!

1. Register your watchtower key (steps listed below) \[please use a dedicated key for watchtower]
2. Go to [Akash console for deployment](https://console.akash.network/templates/akash-network-awesome-akash-witnesschain-watchtower)
3. Fill in the watchtower config params in '**Environment Variables'**&#x20;
4. choose your provider in and deploy!

### 1. Registering the Watchtower Key

You can register the watchtower key easily with the help of our registration cli, to do so

1. Download our **witness-cli** <br>

   ```sh
   curl -sSfL https://witnesschain-com.github.io/install-dcl-cli | bash
   ```

   \
   Check the cli is installed correctly and is upto date ( WitnessChain version v0.0.12)\
   \
   `witness-cli --version`<br>
2. run the following command to register your watchtower

<pre class="language-bash"><code class="lang-bash"><strong>witness-cli registerWatchtower --mainnet --watchtower-private-key &#x3C;your-watchtower-private-key>
</strong></code></pre>

Example:

<pre class="language-bash"><code class="lang-bash"><strong>witness-cli registerWatchtower --mainnet --watchtower-private-key 12b3786f113a6564b0c4835d8026087478d2c408d4a0b22b2a6faf43de56cc11
</strong></code></pre>


# Running on SuperNoderz

Steps to run a Witness Chain Watchtower on SuperNoderz powered by Spheron network

The PoL Watchtower Client Node is a location watchtower node that participates in the PoL (Proof-of-Location) protocol and measures the location claims made by a Prover.

PoL Watchtower Client Nodes can be run on community members’ laptops, desktops or even on cloud instances. As long as the node is running, there is a probabilistic algorithm that determines if the node will participate in a PoL challenge from the network.

Before a node can participate as PoL Challenger, it has to prove it's own capabilities (run a prover to prove it's own location - this mechanism is inbuilt in the watchtower client container). Additionally anyone can challenge the watchtower for it's own claim at any time.

You can now run the watchtower directly on [SuperNoderz](https://www.supernoderz.com/marketplace?id=6751744a140cbf761e2a36ec)!

{% hint style="info" %}
This is the watchtower's signing key, we recommend creating a new dedicated key with no funds in it
{% endhint %}

1. Register your [watchtower key](#id-1.-registering-the-watchtower-key) (steps listed below)&#x20;
2. Go to [SuperNoderz for deployment](https://www.supernoderz.com/marketplace?id=6751744a140cbf761e2a36ec)
3. Fill in the watchtower config params&#x20;
4. choose your region and deploy!

<figure><img src="/files/mDwrE097zQmR1mSbtXDN" alt=""><figcaption></figcaption></figure>

### 1. Registering the Watchtower Key

You can register the watchtower key easily with the help of our registration cli, to do so

1. Download our **witness-cli** <br>

   ```sh
   curl -sSfL https://witnesschain-com.github.io/install-dcl-cli | bash
   ```

   \
   Check the cli is installed correctly and is upto date ( WitnessChain version v0.0.12)\
   \
   `witness-cli --version` <br>
2. run the following command to register your watchtower

<pre class="language-bash"><code class="lang-bash"><strong>witness-cli registerWatchtower --mainnet --watchtower-private-key &#x3C;your-watchtower-private-key>
</strong></code></pre>

Example:

<pre class="language-bash"><code class="lang-bash"><strong>witness-cli registerWatchtower --mainnet --watchtower-private-key 12b3786f113a6564b0c4835d8026087478d2c408d4a0b22b2a6faf43de56cc11
</strong></code></pre>


# Running Watchtower: for DePIN/Validator Node provider

Steps to run a Witness Chain watchtower client (PoL Challenger Client)

The PoL Challenger Client Node is a DePIN Challenger node that participates in the PoL (Proof-of-Location) protocol and measures the location claims made by a DePIN Prover.

PoL Challenger Client Nodes can be run on community members’ laptops, desktops or even on cloud instances. As long as the node is running, there is a probabilistic algorithm (based on stake in the upcoming releases) that determines if the node will participate in a PoL challenge from the network.&#x20;

Before a node can participate as PoL Challenger, it has to prove it's own capabilities (run a prover to prove it's own location - this mechanism is inbuilt in the challenger client container)

#### Prerequisites

Before you begin, ensure you have the following

* **Docker** (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* **Instance** comparable to a t2 micro (**1 vcpu, 1GB RAM and 5GB harddisk**), though we recommend 2 cores, 4 GB RAM and 10 GB of storage.<br>

## Running your Challenger client

{% hint style="info" %}
Explorer: <https://blue-orangutan-blockscout.eu-north-2.gateway.fm/>&#x20;

Our chain is gasless, so you do **NOT** have to fund either or the operator or challenger account with tokens.
{% endhint %}

### <mark style="color:red;">Key Points to consider before proceeding...</mark>

{% hint style="warning" %}
Note: For **EigenLayer** operators, it's important to maintain the distinction between Operator Key and Challenger Key. Refer the correct docs for setup as an EL operator [here](/infinity-watch/proof-of-location-mainnet/run-a-watchtower/eigenlayer-operators/running-a-pol-watchtower)
{% endhint %}

1. Generate a **dedicated watchtower key - ECDSA KeyPair** ( This [video](https://www.youtube.com/watch?v=ke9j2wuYhPE) demonstrates how you can use MetaMask to export one ). This will be used for registration & signing purposes.&#x20;
2. **Ports to be opened if using public IP:**&#x20;

```
Incoming ports to be opened (TCP & UDP ):

11112
22223
33334
33335
33336
44445
44446
44447
55556

Outgoing ports: Allow all
```

### 1. Registering the Watchtower Key

Download and install the *witness CLI:*

```bash
curl -sSfL https://witnesschain-com.github.io/install-dcl-cli | bash
```

After the installation is completed, register your watchtower key on WitnessChain's  Layer 2 Chain: Use the KeyPair that you would have exported or created using Metamask or any other wallet.

<pre class="language-bash"><code class="lang-bash"><strong>witness-cli registerWatchtower --testnet --watchtower-private-key &#x3C;your-watchtower-private-key-without-0x-prefix>
</strong></code></pre>

{% hint style="info" %}
**Why should I register?**

Registration helps with identification of your watchtower inside Witness Chain's watchtower network
{% endhint %}

### 2. Setting up the Watchtower keys and the config file

{% hint style="success" %}
Use ECDSA Keypairs
{% endhint %}

1. You can pass the required configuration to the docker container env via a file or directly with `-e` flag in the run command [(read more)](https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/). Prepare a configuration file `watchtower.env` with the following entries as example shown below:

```bash
latitude=37.01511676489697
longitude=-79.0392271449855
country=US
region=Virginia
city=Ashburn
radius=1000
privateKey=<my_super_secret_private_key>
walletPublicKey=<my_open_public_address>
keyType=ethereum
saveResultsInDatabase=false
submitResultsToContract=true
rpcUrl=https://blue-orangutan-rpc.eu-north-2.gateway.fm
projectName=<my_DePIN_project_name/my_validator_network_name>
```

\
**Explanation:**

* ```
   
      "latitude": 37.015, // Required. Latitude of the machine running the challenger client
      "longitude": -79.039, // Required. Longitude of the machine running the challenger client
      
      "country": "US", // Optional. Country in which the machine is located
      "region": "Virginia", // Optional. State/Region in which the machine is located
      "city": "Ashburn", // Optional. City in which the machine is located
      "radius": 1000 // Optional. Accuracy in meters
      
  ```
* `privateKey` is your PoL signing key (Watchtower/Challenger Key)
* `walletPublicKey` is the wallet addresses where your contributions go&#x20;
* `havePublicIPv4Address` (and `havePublicIPv6Address`) set them to **true** if you have a public IPv4 (or IPv6)&#x20;
* `havePrivateIPv4Address` (and `havePrivateIPv6Address`) set them to **true** if you want to force the use of private IP
* `saveResultsInDatabase` saves the login, session, and challenge related data in a `.sqlite` file within the container
* `projectName` tags the watchtower with the project - examples include "spheron", "akash", "pingpong", "eigenlayer", etc. This is an optional field

### 3. Running the watchtower

Once you have the `watchtower.env` ready, the watchtower client can be started with

```sh
docker run -d \
  --network=host \
  --name pol-watchtower \
  --env-file ./watchtower.env \ 
  witnesschain/pol-multiclient:0.4-alpha
```

\
you can verify that the challenger is running by looking at the container status

```sh
docker ps 
```

**Explanation**:

1. `docker run -d`: Runs the container in detached mode (in the background).
   * ```
     --network=host
     Uses the host's network stack.
     ```
   * ```
     --name pol-challenger
     Names the container as 'pol-challenger'.
     ```
   * ```
     --env-file ./watchtower.env
     The container's environment is set using the attributes specified in 'watchtower.env' file
     ```
   * ```
     witnesschain/pol-multiclient:0.4-alpha: The name of the Docker image to run.
     ```

{% hint style="danger" %}
You may observe the following errors in the docker container&#x20;

"registration is required on DCL contract. Please register your challenger publicKey:"

Don't worry, this is normal. if you [COMPLETE STEP 1](#id-1.-registering-the-challenger-key), these logs should disappear
{% endhint %}

## Post Setup

Once the setting up and registration is successful, you can check the logs from the challenger client ready for challenges. (`docker logs pol-challenger`). Congratulations, you are now a part of our DePIN family!

## Troubleshooting

As the only prerequisite is docker, make sure you are running atleast version 23.0.0 or above for the commands mentioned in the doc to work. \
\
The days might be rainy or snowy, but we've got umbrellas and sweaters!\
Join our [Discord](https://discord.gg/Y9Eu2U5s) or reach out to us over Telegram—we're happy to help. :D


# EigenLayer operators

Introduction to node operators participating in Witness Chain Proof Challenges

Are you a network enthusiast with bandwidth to spare, or perhaps a tech-savvy individual with a keen interest in decentralized networks? If you've got unused bandwidth and are eager to put it to good use, you're a potential Node Operator who can leverage that extra bandwidth to participate in running decentralized speed test or location challenges

## Become a Node Operator for Location Proofs

**What You Need**

* **Unused Bandwidth:** Utilize your excess bandwidth to support network challenges.
* **Machine Specification**: A machine comparable to an AWS t2 micro (1 vcpu, 1GB RAM and 5GB harddisk), though we recommend 2 cores, 4 GB RAM and 10 GB of storage.
* **Network Equipment:** Ensure you have reliable networking hardware to participate in the challenge effectively.&#x20;
* **Interest in Decentralized Networks:** A passion for contributing to de-centralized networks and enhancing their security and efficiency.

**How It Works**

1. **Register Your Node:** Sign up as a Node Operator on Witness Chain's DePIN Coordination platform. Provide details about your geographic location. Specific details are specified in the next section.
2. **Participate in Challenges:** Your node will participate in network challenges on DePIN provers that require Proof of location. These challenges help verify the integrity and reliability of the participating DePIN network's nodes.
3. **Earn Credits (in future):**&#x20;

**The next section details the technical steps in running a Proof of Location Challenger client**


# Running a PoL Watchtower

Steps to run a PoL Watchtower multi-client

The PoL Watchtower is a node in the infinity watch that participates in the PoL (Proof-of-Location) protocol and measures the location claims made by a prover. It can also act as a Prover to prove it's own location claim when challenged.&#x20;

## Witness Chain AVS mainnet Upgrade notes

{% hint style="success" %}
This note is only for existing Mainnet operators of Witness Chain AVS. If you're new to witness chain watchtower setup, you can skip to [Prerequisites](#prerequisites)

* This upgrade enables the watchtowers to validate location claims made by various participants over internet, using the internet telemetry.
* As a part of the upgrade, **you are no longer required to run any L1 or L2 nodes**, and only run a lightweight watchtower client - significantly reducing the infrastructure provisioning
* As earlier, it is **recommended using dedicated watchtower keys with no funds in the wallet** to minimize the risks. As our chain is completely gasless, you'll **not** require any token for registration or proof submissions.
* You are **encouraged to register and setup multiple watchtowers** (each with it's own unique watchtower key) at every location of your infrastructure operation (read 1 watchtower per region). This will serve 2 purposes in the network:
  * It increases geographical spread of the watchtowers, and hence increasing accuracy and coverage globally for location validation
  * It helps us map out the geographical stake distribution attached to the eigenlayer operator (It's a global stake map for Eigenlayer team to showcase decentralization of their network in a verifiable manner)&#x20;
* Avoid using VPNs or other proxies which might add network delays to an external connection to your watchtower node connecting over internet
* The current mainnet contracts will be locked/paused in favour of the new contracts part of this upgrade soon
  {% endhint %}

## Prerequisites

Before you begin, ensure you have the following

* You have opted-in for Witness Chain AVS [(guide here)](/infinity-watch/proof-of-location-mainnet/run-a-watchtower/eigenlayer-operators/witness-chain-avs-opt-in-guide)
* **Docker** (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* **Instance** comparable to a t2 micro (1 vcpu, 1GB RAM and 5GB harddisk)

## Running your Watchtower client

### <mark style="color:red;">Key Points to consider before proceeding...</mark>

1. We have 2 sets of keys - Operator Key and Watchtower Key.&#x20;
   1. **Operator Key** is your EigenLayer Operator Key that you have been using with various AVSes including our Witness Chain AVS. Continue to use that here too. This key is used for registering the Watchtower Key(s).
   2. **Watchtower Key** - This is the signing key for the PoL Watchtower Client. Create a new Key for the same. **Don't reuse the Operator Key for the Watchtower Key**. It has to be a ECDSA Key.&#x20;
2. You are encouraged to setup as many unique watchtowers as you can support (ideally **1 per region of your infrastructure** operating). All of the should be registered with the same operator key in the process described in this doc.
3. **Ports to be opened if using public IP:**&#x20;

```
Incoming ports to be opened (TCP & UDP ):

11112
22223
33334
33335
33336
44445
44446
44447
55556

Outgoing ports: Allow all
```

### 0. Creating the Watchtower Key

{% hint style="success" %}
Use ECDSA Keypairs
{% endhint %}

1. Create a ECDSA private key using Metamask or other utilities that will be used as Watchtower Key.&#x20;
2. Store the watchtower's private key in the file (Make sure you keep track of the file name and its location, as it would be refered later)

```bash
echo "YOUR_WATCHTOWER_PRIVATE_KEY" > my_watchtower_private.key
```

### Setting up the watchtower

1. Prepare a environment file `watchtower.env` with the following entries as example shown below:

```
latitude=37.01511676489697
longitude=-79.0392271449855
radius=1000
privateKey=<my_super_secret_watchtower_private_key>
walletPublicKey=<my_open_operator_public_address>
keyType=ethereum
saveResultsInDatabase=false
submitResultsToContract=false
rpcUrl=https://rpc.witnesschain.com
projectName=eigenlayer-<my_operator_name>
```

{% hint style="info" %}
**Latitude** and **Longitude** are optional. If not provided, they will be automatically determined based on the approximate location of the IP address. However it's recommended to be set for better accuracy.
{% endhint %}

\
**Explanation:**

* ```

      "latitude": 37.015, // Latitude of the machine running the watchtower client
      "longitude": -79.039, // Longitude of the machine running the watchtower client
      "radius": 1000 // Optional. Accuracy in km

  ```
* `privateKey` is your PoL signing key (Watchtower Key)
* `walletPublicKey` is the wallet addresses where your contributions go (Operator address)
* `havePublicIPv4Address` (and `havePublicIPv6Address`) set them to **true** if you have a public IPv4 (or IPv6)&#x20;
* `havePrivateIPv4Address` (and `havePrivateIPv6Address`) set them to **true** if you want to force the use of private IP
* `saveResultsInDatabase` saves the login, session, and challenge related data in a .sqlite file within the container
* `projectName` is the tagging mechanism to ensure we can identify our operators. It is a required field in the format `eigenlayer-<your operator name>`

{% hint style="info" %}
We collect various telemetry data from your node, such as the logs etc. You can choose to opt-out by setting `TELEMETRY=false` in the `watchtower.env` file
{% endhint %}

2. Once you have the `config.json` ready, the watchtower client can be started with

```sh
docker run -d \
  --network=host \
  --name pol-watchtower \
  --env-file ./watchtower.env \
  witnesschain/infinity-watch:1.0.2
```

\
you can verify that the watchtower is running by looking at the container status

```sh
docker ps 
```

**Explanation**:

1. `docker run -d`: Runs the container in detached mode (in the background).
   * ```
     --network=host
     Uses the host's network stack.
     ```
   * ```
     --name pol-watchtower
     Names the container as 'pol-watchtower'.
     ```
   * ```
     witnesschain/infinity-watch:1.0.2: The name of the Docker image to run.
     ```

## Post Setup

Once the setting up and registration is successful, you can check the logs from the watchtower client ready for challenges. (`docker logs -f pol-watchtower`). Congratulations, you are now a part of our Watchtower family!

## Troubleshooting

As the only prerequisite is docker, make sure you are running atleast version 23.0.0 or above for the commands mentioned in the doc to work. \
\
The days might be rainy or snowy, but we've got umbrellas and sweaters!\
Join our [Discord](https://discord.gg/Y9Eu2U5s) or Telegram—we're happy to help. :D


# Witness Chain AVS opt-in guide

This page describes steps for EigenLayer operators to opt-in to WitnessChain AVS

### **Step 1: Get whitelisted on the Watchtower Network**.&#x20;

The Witness Chain watchtower network is a permissioned network currently (only for EigenLayer operators - others can permissionlessly setup a watchtower using [this guide](/infinity-watch/proof-of-location-mainnet/run-a-watchtower/at-home-watchtowers)) .  Please connect with us on our [Discord](https://discord.gg/7hRNBDeY5e), if you want to become a watchtower operator via EigenLayer

### Step 2: Register the operator on the Witness Chain Watchtower Network&#x20;

{% hint style="info" %}
Before you start any activity on this network, ensure your operator address is sufficiently funded to cover the gas costs for registration
{% endhint %}

Register your EL operator address on the  WitnessChain **OperatorRegistry** contract. You can do so with the help of our CLI utility.&#x20;

#### Prerequisites

The CLI tool expects Ubuntu 22.04 (if you are running on linux) or if you are running on Ubuntu 20.04, ensure the glibc version is 2.34+&#x20;

```bash
# Run ldd --version to get the GLIBC version
ldd --version
```

#### Step 3.1 : Installation and Running the CLI

1. Installation:

   ```bash
   curl -sSfL https://witnesschain-com.github.io/install-operator-cli | bash
   ```

2. Running:

   <pre class="language-bash"><code class="lang-bash"><strong>export PATH="$PATH:~/.witnesschain/cli/"
   </strong>watchtower-operator --version

   Expected VERSION:
      v0.3.0 and higher
   </code></pre>

{% hint style="warning" %}
If you are facing the following error, please upgrade to Ubuntu 22.04

$ watchtower-operator --version

watchtower-operator: /lib/x86\_64-linux-gnu/libc.so.6: version \`GLIBC\_2.32' not found (required by watchtower-operator)

watchtower-operator: /lib/x86\_64-linux-gnu/libc.so.6: version \`GLIBC\_2.34' not found (required by watchtower-operator)
{% endhint %}

#### Step 3.2 : Registering the operator and the watchtowers on Ethereum Mainnet (L1)

Once you've ensured the tool is installed correctly, run the below commands to register the operator with our AVS and associate the watchtowers to the operator.

{% hint style="info" %}
**Note:** Refer to our [FAQs](/archive/proof-of-diligence-watchtower-protocol/faqs#how-is-a-watchtower-address-different-from-operator-address) to understand the difference between watchtower addresses and operator addresses
{% endhint %}

**Setup the configuration files for the OPERATOR CLI**

#### operator-config.json

```
# Set of watchtower private keys that will sign the location Proofs. 
# This is used for registration purposes
# Registration will happen both on L1 and L2 simultaneously
```

```json
{
  "watchtower_private_keys": [
    "<raw-watchtower-private-key e.g. 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef>"
  ],
  "operator_private_key": "<raw-watchtower-private-key e.g. 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef>",
  "eth_rpc_url": "https://eth.llamarpc.com", 
  "proof_submission_rpc_url": "https://rpc.witnesschain.com"
}
```

{% hint style="danger" %}

<pre><code>If your operator address is already registered on L1, set

<strong>"eth_rpc_url": ""
</strong>
This will register the Operator EoA only on L2.
</code></pre>

{% endhint %}

```sh
# Registers the Operator to WitnessHub AVS on EigenLayer 
# This is required for the Operator to be listed on EigenLayer's App

# Witnesschain Txns can be monitored via Blockscout at https://explorer.witnesschain.com/

# Feel free to skip if this step is already carried out

$ watchtower-operator registerOperatorToAVS --config-file <path to L1 config file>
```

```bash
# Registers the Operator's watchtower to WitnessHub AVS on Layer 1
# This registration is required for operators to be associated with the 
# submissions recorded as a result of participating in location proofs.
# To understand what are watchtowers, please read the FAQs

watchtower-operator registerWatchtower --config-file <path to L1 config file>
```


# At-home watchtowers

Steps to run a Witness Chain watchtower client to validate location claims

The PoL Watchtower Client Node participates in the Proof-of-Location (PoL) protocol by verifying location claims made by network nodes.

Watchtower nodes can run on community members' laptops, desktops, or cloud instances. Nodes are selected to participate in PoL watchtowers via a probabilistic algorithm.&#x20;

### <mark style="color:green;">Prerequisites</mark>

* **Docker**: Version 23.0.0 or higher ([Install Docker](https://docs.docker.com/desktop/install/linux-install/)).
* **Instance**: Minimum t2.micro equivalent (1 vCPU, 1GB RAM, 5GB disk). Recommended: 2 cores, 4GB RAM, 10GB disk.&#x20;
* **ECDSA KeyPair** ( This [video](https://www.youtube.com/watch?v=ke9j2wuYhPE) demonstrates how you can use MetaMask to export one ). This will be used for registration & signing purposes. &#x20;
* **Ports to Open (*****for public IP only*****)**
  * **Incoming (TCP & UDP)**: 11112, 22223, 33334-33336, 44445-44447, 55556
  * **Outgoing**: Allow all.

### <mark style="color:green;">Running the Watchtower Client</mark>

#### 1. Configuring *watchtower.env* File

* Create a `watchtower.env` configuration file with the following example entries.&#x20;
* If you are running this at home and DON'T have a public IP, you need to change the following entries only in the watchtower.env file&#x20;
  * `latitude, longitude, region, privateKey, walletPublicKey`

<pre class="language-bash"><code class="lang-bash">latitude=37.0151
longitude=-79.0392
radius=1000
privateKey=&#x3C;your_private_key>
<strong>walletPublicKey=&#x3C;your_public_key>
</strong>saveResultsInDatabase=false
submitResultsToContract=false
rpcUrl=https://rpc.witnesschain.com
</code></pre>

{% hint style="info" %}
You can get detailed explanation about these parameters [here](#faqs)
{% endhint %}

{% hint style="info" %}
**Latitude** and **Longitude** are optional. If not provided, they will be automatically determined based on the approximate location of the IP address. However it's recommended to be set for better accuracy.
{% endhint %}

#### 2. Running the Watchtower Client

Start the challenger client:

```bash
docker run -d \
  --network=host \
  --name pol-watchtower \
  --env-file ./watchtower.env \
  witnesschain/infinity-watch:1.0.2
```

Verify the client is running:

```bash
docker ps
```

If you see an error about *"registration required on DCL contract,*" make sure to complete the watchtower key registration.

### <mark style="color:green;">Post-Setup</mark>

Check logs using:

```bash
docker logs -f pol-watchtower
```

Once the client is ready, you're part of Witness Chain's Watchtower family!

#### <mark style="color:green;">Troubleshooting</mark>

The days might be rainy or snowy, but we've got umbrellas and sweaters!. For support, join our [Discord](https://discord.gg/Y9Eu2U5s) or reach out on Telegram.

#### FAQs

#### What do the parameters in *watchtower.env* mean ?

```
 
latitude=37.015, // Required. Latitude of the machine running the challenger client
longitude=-79.039, // Required. Longitude of the machine running the challenger client

radius=1000 // Optional. Accuracy in meters


privateKey= //  PoL signing key (Watchtower Key)
walletPublicKey= //  Ethereum Wallet addresses where your contributions go (Operator Key)

saveResultsInDatabase=true // Saves the login, session, and challenge related data in a .sqlite file within the container
rpcUrl=https://rpc.witnesschain.com // Witness chain's Layer 2 Chain which holds the proofs of location
```

#### What do the parameters in the docker run mean?

`docker run -d`: Runs the container in detached mode (in the background).

* ```
  --network=host
  Uses the host's network stack.
  ```
* ```
  --name pol-watchtower
  Names the container as 'pol-watchtower'.
  ```
* ```
  --env-file ./watchtower.env
  The container's environment is set using the attributes specified in 'watchtower.env' file
  ```
* ```
  witnesschain/infinity-watch:1.0.2: The name of the Docker image to run.
  ```

***


# For DePIN/Validator Node provider

Steps to run a Witness Chain PoL Watchtower Client

#### Prerequisites

Before you begin, ensure you have the following

* **Docker** (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* **Instance** comparable to a t2 micro (1 vcpu, 1GB RAM and 5GB harddisk)

## Running your Watchtower client

There are two aspects in setting up the watchtower,

* Registration: so the challengers are aware of it
* Running: so the challengers can engage with it

Here's how to get the watchtowers successfully running&#x20;

### <mark style="color:red;">Key Points to consider before proceeding...</mark>

1. **Ports to be opened if using public IP:**&#x20;

```
Incoming ports to be opened (TCP & UDP ):

11112
22223
33334
33335
33336
44445
44446
44447
55556

Outgoing ports: Allow all
```

## Setting up the Watchtower

You can provide the private key (for example, generated from Metamask) which will be used by the Witnesschain's PoL  Watchtower client.

{% hint style="success" %}
Use ECDSA Keypairs
{% endhint %}

### Registering the Watchtower Key

Download and install the *witness CLI:*

```bash
curl -sSfL https://witnesschain-com.github.io/install-dcl-cli | bash
```

After the installation is completed, verify the cli is installed correctly and upto date  ( WitnessChain version v0.0.12)<br>

`witness-cli --version`

Then proceed to register your watchtower key on WitnessChain's  Layer 2 Chain: Use the KeyPair that you would have exported or created using Metamask or any other wallet.

<pre class="language-bash"><code class="lang-bash"><strong>witness-cli registerWatchtower --mainnet --watchtower-private-key &#x3C;your-watchtower-private-key-without-0x-prefix>
</strong></code></pre>

{% hint style="info" %}
**Why should I register?**

Registration helps with identification of your watchtower inside Witness Chain's watchtower network
{% endhint %}

### Setting up the Watchtower keys and the config file

1. You can pass the required configuration to the docker container env via a file or directly with `-e` flag in the run command [(read more)](https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/). Prepare a configuration file `watchtower.env` with the following entries as example shown below:

```bash
latitude=37.01511676489697
longitude=-79.0392271449855
radius=1000
privateKey=<my_super_secret_private_key>
walletPublicKey=<my_open_public_address>
keyType=ethereum
saveResultsInDatabase=false
submitResultsToContract=true
rpcUrl=https://rpc.witnesschain.com
projectName=<my_DePIN_project_name/my_validator_network_name>
```

{% hint style="info" %}
**Latitude** and **Longitude** are optional. If not provided, they will be automatically determined based on the approximate location of the IP address. However it's recommended to be set for better accuracy.
{% endhint %}

**Explanation:**

* ```
   
      "latitude": 37.015, // Required. Latitude of the machine running the challenger client
      "longitude": -79.039, // Required. Longitude of the machine running the challenger client
      "radius": 1000 // Required. Range in KM
      
  ```
* `privateKey` is your PoL signing key (Watchtower Key)
* `walletPublicKey` is the PoL watchtower address (eth address)&#x20;
* `havePublicIPv4Address` (and `havePublicIPv6Address`) set them to **true** if you have a public IPv4 (or IPv6)&#x20;
* `havePrivateIPv4Address` (and `havePrivateIPv6Address`) set them to **true** if you want to force the use of private IP
* `saveResultsInDatabase` saves the login, session, and challenge related data in a `.sqlite` file within the container
* `projectName` tags the watchtower with the project - examples include "spheron", "akash", "pingpong", "eigenlayer", etc. This is an optional field

### 3. Running the watchtower

Once you have the `watchtower.env` ready, the watchtower client can be started with

```sh
docker run -d \
  --network=host \
  --name pol-watchtower \
  --env-file ./watchtower.env \
  witnesschain/infinity-watch:1.0.2
```

\
you can verify that the challenger is running by looking at the container status

```sh
docker ps 
```

**Explanation**:

* `docker run -d`: Runs the container in detached mode (in the background).
* ```
  --network=host
  Uses the host's network stack.
  ```
* ```
  --name pol-watchtower
  Names the container as 'pol-watchtower'.
  ```
* ```
  witnesschain/infinity-watch:1.0.2 The name of the Docker image to run.
  ```

\
you can verify that the watchtower is running by looking at the container status<br>

```sh
docker ps 
```

## Post Setup

Once the setting up and registration is successful, you can check the logs from the watchtower client ready for challenges. (`docker logs -f pol-watchtower`). Congratulations, you are now a part of our Infinity watch family!<br>

## Troubleshooting

As the only prerequisite is docker, make sure you are running atleast version 23.0.0 or above for the commands mentioned in the doc to work. \
\
The days might be rainy or snowy, but we've got umbrellas and sweaters!\
Join our [Discord](https://discord.gg/Y9Eu2U5s) or Telegram—we're happy to help. :D


# Demos

This page holds the working demonstrations of  Proof-of-Location (PoL)

## PoL (Proof of Location) Demo

{% embed url="<https://www.loom.com/share/79667612185e4f43b1580cecf6bf4611?sid=72e67772-0abc-4e3a-96e3-3333d8e1b36b>" %}


# PoL Research

This page holds all the papers published by our research team on PoL

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><p><strong>Proof of Location:</strong>  </p><p><em>Byzantine fortified trigonometric proof of location protocol using internet delays</em></p></td><td></td><td>Decentralised protocol to verify the geographical locations of IP addresses using Internet delay measurements, enhancing accuracy and Byzantine resistance.</td><td><a href="https://arxiv.org/abs/2403.13230">https://arxiv.org/abs/2403.13230</a></td><td><a href="/files/AzXOYz7DYcpsqdhGBEAY">/files/AzXOYz7DYcpsqdhGBEAY</a></td></tr></tbody></table>


# APIs

APIs for Builders to integrate image verification, location verification proofs into their apps

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Image Verification APIs</strong></td><td>Integrate Trustless image verification</td><td><a href="/files/yeJ3ttND8tvv3PmPnzeM">/files/yeJ3ttND8tvv3PmPnzeM</a></td><td><a href="/pages/KSdV5wpPF8lfahFSGxO4">/pages/KSdV5wpPF8lfahFSGxO4</a></td></tr><tr><td><strong>Campaign APIs</strong></td><td>Create geo-fenced photo campaigns</td><td><a href="/files/17j1OcV41cO9BgTvNAxN">/files/17j1OcV41cO9BgTvNAxN</a></td><td><a href="/pages/HCgCkpqL4IMWxcl7RoYj">/pages/HCgCkpqL4IMWxcl7RoYj</a></td></tr><tr><td><strong>Challenge APIs</strong></td><td>Access challenge and verification endpoints</td><td><a href="/files/e2I1CSpqvPqkiAuZddzp">/files/e2I1CSpqvPqkiAuZddzp</a></td><td><a href="/pages/bGbBD6DLnD3Yk1Y3XnJV">/pages/bGbBD6DLnD3Yk1Y3XnJV</a></td></tr></tbody></table>


# Campaign APIs

## Overview

The Witness Chain Campaign APIs provide developers with powerful tools for requesting tasks and observations in the real world. They work in conjunction with the InfinityWatch app, which acts as a portal to the physical world. These APIs enable developers and organizations to crowdsource authentic, geo-verified photographs by launching campaigns on the InfinityWatch app and rewarding participants through a gamified system.

### Early developer access

> <mark style="color:green;">Please fill out this</mark> [<mark style="color:red;">**form**</mark>](https://forms.gle/1ZPXiSWweQLyU2Qs5) <mark style="color:green;">for early developer access to the campaign API and the app</mark>

## tl;dr

* [Create Campaign](/infinity-watch/apis/campaign-apis/create-campaign)\
  The Create Campaign API lets you create campaigns in InfinityWatch app. For example, you can use this endpoint to create a campaign to capture photos of your new coffee rollouts from your coffee lovers at the stores. You can target your campaigns based on locations that match the product profile that you want to roll out to.
* [Get Photo Feed from Campaign](/infinity-watch/apis/campaign-apis/get-photo-feed-from-campaign)\
  The Get Campaign Report API lets you get all the photos from a specific campaign
* [Get Campaigns](/infinity-watch/apis/campaign-apis/get-campaigns)\
  The Get Campaigns API lets you get a list of all campaigns created

### Key Features

#### Location Verification

* Create geofenced campaigns that only accept tasks and observations from specific geographic areas
* Capture observations via a trusted camera integrated into the InfinityWatch app
* Define custom radius boundaries for photo submissions
* Ensure observations are captured at the claimed location and time through built-in verification utilizing Witness Chain's PoL (Proof of Location) network

#### Reward System (<mark style="color:purple;">COMING SOON</mark>)

* Implement campaign points for successful photo submissions
* Set custom campaign points per task
* Define campaign-wide campaign point pool
* Track and manage fuel consumption for user activities

#### Campaign Management

* Create individual, group, or task-based campaigns
* Set campaign duration with start and end dates
* Control submission limits
* Add rich media content (banners and posters) to campaigns
* Tag and categorize campaigns for better organization

### Use Cases

Campaigns enable your code to actuate and observe the physical world. This has applications for all use cases that need on-the-ground operations.

1. **Verifiable News**
   1. Request observations - verified photos - at local news hotspots
   2. Discover new local events&#x20;
   3. Gather and summarize the latest intelligence on events happening near you&#x20;
2. **Real community engagement and incentivization**
   1. Request communities to attest their physical attributes&#x20;
   2. Prevent farmers and Sybil attacks&#x20;
   3. Ensure fair incentive distribution with custom policies
3. **Infrastructure expansion and monitoring**
   1. Incentivize new infrastructure deployment
   2. Track deployment progress&#x20;
   3. Monitor maintenance needs&#x20;
   4. Document facility conditions
4. **Marketing campaigns**
   1. Collect authentic user-generated content
   2. Verify in-store promotions
   3. Document brand activations
5. **Community Engagement**
   * Organize local clean-up documentation
   * Create neighborhood improvement initiatives
   * Run citizen journalism projects

### Getting Started

To begin using the Campaign APIs:

1. Please fill out this [form](https://forms.gle/1ZPXiSWweQLyU2Qs5) for early developer access to the API and the app
2. Complete the authentication flow using pre-login and login endpoints
3. Create a campaign with specific geographic boundaries
4. Set reward parameters to incentivize participation
5. Monitor and collect verified photo submissions

### Implementation Flow

1. **Authentication**
   * Secure your API access through two-step authentication
   * Maintain session tokens for continuous operation
2. **Campaign Creation**
   * Define campaign parameters
   * Set geographic boundaries
   * Configure reward structure
3. **Photo Collection**
   * Receive location-verified submissions
   * Track campaign progress
4. **Campaign Management (COMING SOON)**
   * Reward campaign points
   * Monitor submission rates
   * Adjust campaign parameters as needed
   * Access submission data and analytics

### Best Practices

1. **Geographic Targeting**
   * Set appropriate radius boundaries based on campaign needs
   * Consider population density when defining target areas
   * Use recommended coordinate precision for accurate location verification
2. **Reward Structure**
   * Balance campaign point amounts with the campaign budget
   * Consider task complexity when setting campaign points
   * Implement fair fuel consumption rates
3. **Campaign Duration**
   * Set realistic timeframes for photo collection
   * Consider seasonal factors affecting outdoor photography
   * Plan for peak participation periods
4. **User Experience**
   * Provide clear campaign descriptions
   * Use high-quality campaign banners and posters
   * Set achievable submission targets

### Technical Considerations

* All API endpoints require authentication
* Implement proper error handling for geographic verification
* Cache authentication tokens appropriately
* Monitor campaign points pool consumption
* Handle timezone differences in campaign scheduling

The Campaign APIs provide a robust foundation for building location-aware photo collection systems while maintaining data integrity through verification mechanisms. Whether you're building a community engagement platform or a marketing campaign tool, these APIs offer the flexibility and features needed for successful implementation.


# Key Terminologies

This page describes the key terms used in the APIs

## CAMPAIGN

Is a set of tasks that the AI or a protocol needs to get done in the real world.&#x20;

{% hint style="success" %}
From taking a photo for AI training to having a musician play at your Valentine’s favorite café—if it’s requested, it's a campaign.
{% endhint %}

## WITNESS

is the proof of task participation or completion. A decentralized network of participants on the InfinityWatch app step in to execute tasks, verify events, and capture observations. They don’t just complete the work; they attest it cryptographically.

## FEED

is the stream of outputs (in this case, photos clicked) originating from the task completion

{% hint style="success" %}
Photos taken through the InfinityWatch's mobile app for the particular campaign
{% endhint %}

## WATCHTOWER

Any device running the InfinityWatch Mobile App ( or even the docker container )


# Authentication

The **pre-login** and **login APIs** are crucial for the security and functionality of the Proof of Bandwidth or Proof of Location system. The APIs handles initial authentication steps, like generating session tokens and validating access. These APIs are foundational for safeguarding the prover's information and controlling system access, ensuring only authenticated users can interact with critical resources

Start the process by performing a **pre-login** and **login** requesttart the process by performing a **pre-login** and **login** request

{% hint style="info" %}
**Note:** The `{proof_type}` parameter is crucial in all API requests and **must** be set to one of the following values:

* `pol` (Proof of Location) -> Currently supported
* `pob` (Proof of Bandwidth)

{% endhint %}

#### Pre-login

{% openapi src="/files/WWLjK2RiH8JZs6E8BepB" path="/proof/v1/{proof\_type}/pre-login" method="post" %}
[challenge\_api.json](https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2FSxD3akB7T6Vy6Ek6wdcA%2Fchallenge_api.json?alt=media\&token=45395a70-77eb-498b-8209-c4ae4f512011)
{% endopenapi %}

#### Login

After the result is obtained, the **/login** api needs to be invoked

{% openapi src="/files/WWLjK2RiH8JZs6E8BepB" path="/proof/v1/{proof\_type}/login" method="post" %}
[challenge\_api.json](https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2FSxD3akB7T6Vy6Ek6wdcA%2Fchallenge_api.json?alt=media\&token=45395a70-77eb-498b-8209-c4ae4f512011)
{% endopenapi %}


# Create Campaign

Creates a new campaign in WitnessChain.

### Endpoint

<pre><code><strong>POST /create-campaign
</strong></code></pre>

Before creating a campaign, you must complete the authentication flow using the pre-login and login endpoints.

The documentation for the endpoints can be found at [Authentication](/infinity-watch/apis/campaign-apis/authentication)

### Request Body

```json
{
  "type": "object",
  "required": [
    "campaign",
    "description",
    "type",
    "currency",
    "total_rewards",
    "reward_per_task",
    "fuel_required",
    "starts_at",
    "ends_at",
    "max_submissions",
    "is_active"
  ],
  "properties": {
    "campaign": {
      "type": "string",
      "description": "Name of the campaign"
    },
    "description": {
      "type": "string",
      "description": "Detailed description of the campaign"
    },
    "type": {
      "type": "string",
      "enum": ["individual", "group", "task"],
      "description": "Type of campaign. Currently only 'individual' is supported",
      "default": "individual"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Array of tags associated with the campaign"
    },
    "latitude": {
      "type": "number",
      "format": "float",
      "description": "Geographical latitude for campaign visibility (recommended)"
    },
    "longitude": {
      "type": "number",
      "format": "float",
      "description": "Geographical longitude for campaign visibility (recommended)"
    },
    "radius": {
      "type": "number",
      "description": "Radius in kilometers within which the campaign is valid",
      "default": 100
    },
    "banner_url": {
      "type": "string",
      "format": "uri",
      "description": "URL of the banner image shown to users"
    },
    "poster_url": {
      "type": "string",
      "format": "uri",
      "description": "URL of the poster image shown to users"
    },
    "currency": {
      "type": "string",
      "enum": ["POINTS"],
      "description": "Reward currency type. Currently only 'POINTS' is supported"
    },
    "total_rewards": {
      "type": "number",
      "format": "float",
      "description": "Maximum total rewards available for the campaign"
    },
    "reward_per_task": {
      "type": "number",
      "format": "float",
      "description": "Reward amount given per completed task"
    },
    "fuel_required": {
      "type": "number",
      "format": "float",
      "description": "Amount of fuel spent by user per task (recommended: 1.0)",
      "default": 1.0
    },
    "starts_at": {
      "type": "string",
      "format": "date-time",
      "description": "Campaign start date and time"
    },
    "ends_at": {
      "type": "string",
      "format": "date-time",
      "description": "Campaign end date and time"
    },
    "max_submissions": {
      "type": "integer",
      "description": "Maximum number of submissions allowed for the campaign"
    },
    "is_active": {
      "type": "boolean",
      "description": "Whether the campaign is immediately available to users",
      "default": true
    }
  }
}
```

### Example Request

```json
{
  "campaign": "Summer Promotion",
  "description": "Special summer promotional campaign",
  "type": "individual",
  "tags": ["summer", "promotion"],
  "latitude": 37.7749,
  "longitude": -122.4194,
  "radius": 100,
  "banner_url": "https://example.com/banner.png",
  "poster_url": "https://example.com/poster.png",
  "currency": "POINTS",
  "total_rewards": 10.0,
  "reward_per_task": 2.0,
  "fuel_required": 1.0,
  "starts_at": "2025-06-01T00:00:00Z",
  "ends_at": "2025-08-31T23:59:59Z",
  "max_submissions": 10000,
  "is_active": true
}
```

### &#x20;Example response

```json
{
  "result" : {
    "success" : true
  }
}
```

### Sample reference code

Please see tutorial on create campaign here:

<https://github.com/witnesschain-com/tutorials/tree/main/create-campaign>

| Status Code | Description                             |
| ----------- | --------------------------------------- |
| 400         | Bad Request - Invalid parameters        |
| 401         | Unauthorized - Authentication required  |
| 403         | Forbidden - Insufficient permissions    |
| 429         | Too Many Requests - Rate limit exceeded |
| 500         | Internal Server Error                   |

### Notes

* The `type` field currently only supports "individual" campaigns
* For group campaigns (future feature), additional fields will be required:
  * `location_limit_in_meters`: Distance limit for group members
  * `time_limit_in_minutes`: Validity period for referral links
* Geographical coordinates (latitude, longitude) are recommended for better campaign targeting
* Setting `is_active` to true makes the campaign immediately available to users


# Edit campaign

Edits an existing campaign in WitnessChain.

### Endpoint

<pre><code><strong>POST /edit-campaign
</strong></code></pre>

### Request Body

```json
Same as the /create-campaign
```


# Get Photo feed from campaign

Retrieves photos associated with a specific campaign by its name.

### Endpoint

```
POST /photo-feed-from-campaign
```

Before creating a campaign, you must complete the authentication flow using the pre-login and login endpoints.

The documentation for the endpoints can be found at [Authentication](/infinity-watch/apis/campaign-apis/authentication)

### Request Body

```json
{
  "type": "object",
  "required": ["campaign"],
  "properties": {
    "campaign": {
      "type": "string",
      "description": "Name of the campaign to retrieve photos for"
    },
    "since": {
      "type": "string",
      "format": "date-time",
      "description": "Retrieve photos posted after this timestamp"
    }
  }
}
```

### Example Request

```json
{
  "campaign": "summer-promotion",
  "since": "2025-01-01T00:00:00Z"
}
```

### Response

```json
{
  "type": "object",
  "properties": {
    "photos": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "photo_id": {
            "type": "string",
            "description": "Unique identifier for the photo"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the photo"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the photo was uploaded"
          }
        }
      }
    }
  }
}
```

### Example Response

```json
{
  "photos": [
    {
      "photo_id": "photo_123456",
      "url": "https://example.com/photos/123456.jpg",
      "created_at": "2025-06-15T14:30:00Z"
    }
  ]
}
```

### Error Codes

| Status Code | Description                             |
| ----------- | --------------------------------------- |
| 400         | Bad Request - Invalid parameters        |
| 401         | Unauthorized - Authentication required  |
| 403         | Forbidden - Insufficient permissions    |
| 404         | Not Found - Campaign not found          |
| 429         | Too Many Requests - Rate limit exceeded |
| 500         | Internal Server Error                   |

### Notes

* The `since` parameter is optional and can be used to filter photos by upload date
* Photos are returned in chronological order (newest first)
* If no photos are found, an empty array will be returned

### Error Codes

| Status Code | Description                             |
| ----------- | --------------------------------------- |
| 400         | Bad Request - Invalid parameters        |
| 401         | Unauthorized - Authentication required  |
| 403         | Forbidden - Insufficient permissions    |
| 404         | Not Found - Campaign not found          |
| 429         | Too Many Requests - Rate limit exceeded |
| 500         | Internal Server Error                   |

### Notes

* The request accepts pagination parameters in the request body
* Photos are returned in paginated format with a default limit of 20 photos per request
* The `thumbnail_url` provides a smaller, optimized version of the photo for preview purposes
* Use the pagination parameters to iterate through all photos in the campaign
* Photos are sorted by creation date (newest first) by default
* The response includes metadata about each photo's dimensions and file format
* The `thumbnail_url` provides a smaller, optimized version of the photo for preview purposes
* Use the pagination parameters to iterate through all photos in the campaign
* Photos are sorted by creation date (newest first) by default
* The response includes metadata about each photo's dimensions and file format


# Get Campaigns

Retrieves all campaigns created on Infinity Watch

### Endpoint

```
POST /all-campaigns
```

### Response

```json
{
  "type": "object",
  "properties": {
    "result": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the campaign"
          },
          "banner_url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the banner image shown to users"
          },
          "poster_url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the poster image shown to users"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the campaign was created"
          },
          "created_by": {
            "type": "string",
            "description": "Username of the campaign creator"
          },
          "created_by_publicKey": {
            "type": "string",
            "description": "Public key of the campaign creator"
          },
          "description": {
            "type": "string",
            "description": "Detailed description of the campaign"
          },
          "starts_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the campaign starts"
          },
          "ends_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the campaign ends"
          },
          "fuel_required": {
            "type": "number",
            "description": "Amount of fuel required for participation"
          },
          "is_active": {
            "type": "boolean",
            "description": "Whether the campaign is currently active"
          },
          "latitude": {
            "type": "number",
            "description": "Geographical latitude of the campaign center"
          },
          "longitude": {
            "type": "number",
            "description": "Geographical longitude of the campaign center"
          },
          "radius": {
            "type": "number",
            "description": "Radius in kilometers within which the campaign is valid"
          },
          "location_limit_in_meters": {
            "type": "number",
            "description": "Limit in meters for location verification"
          },
          "max_submissions": {
            "type": "integer",
            "description": "Maximum total submissions allowed for the campaign"
          },
          "max_submissions_per_witness": {
            "type": "integer",
            "description": "Maximum submissions allowed per individual witness"
          },
          "submissions": {
            "type": "integer",
            "description": "Current number of submissions received"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of tags associated with the campaign"
          },
          "type": {
            "type": "string",
            "enum": ["individual", "group", "task"],
            "description": "Type of campaign"
          },
          "currency": {
            "type": "string",
            "description": "Currency type for rewards"
          },
          "reward_per_task": {
            "type": "number",
            "description": "Amount of reward given per completed task"
          },
          "total_rewards": {
            "type": "number",
            "description": "Total rewards available for the campaign"
          },
          "tasks": {
            "type": "object",
            "description": "For task-type campaigns, contains task definitions",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "description": {
                  "type": "string",
                  "description": "Description of the task"
                },
                "fuel_required": {
                  "type": "number",
                  "description": "Amount of fuel required for this specific task"
                }
              }
            }
          },
          "whitelist": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of public keys allowed to participate in this campaign"
          }
        }
      }
    }
  }
}
```

### Example Response

```json
{
  "result": [
    {
      "banner_url": "https://truesnap.s3.us-east-1.amazonaws.com/horizontal_artistics_eye_for_ai.png",
      "created_at": "2025-01-31T14:53:25.800Z",
      "created_by": "@witnesschain",
      "description": "Get started with the first artistic eye for AI campaign",
      "ends_at": "2025-05-11T14:53:25.800Z",
      "fuel_required": 1,
      "id": "ArtisticEyeForAI",
      "is_active": true,
      "latitude": 40,
      "longitude": -73,
      "max_submissions": 500000,
      "max_submissions_per_witness": 10,
      "poster_url": "https://truesnap.s3.us-east-1.amazonaws.com/2.png",
      "radius": 20000,
      "starts_at": "2025-01-31T14:53:25.800Z",
      "submissions": 110,
      "tags": ["AI", "Art"],
      "type": "individual"
    },
    {
      "banner_url": "https://truesnap.s3.us-east-1.amazonaws.com/6176690776340284330.jpg",
      "created_at": "2025-02-21T06:46:56.833Z",
      "created_by": "@witnesschain",
      "created_by_publicKey": "0x701441ee7150744fb01b7cb8aa5366617451f9f6",
      "currency": "POINTS",
      "description": "Prove your gains",
      "ends_at": "2025-06-01T06:43:37.751Z",
      "fuel_required": 1,
      "id": "ProveYourGains",
      "is_active": true,
      "latitude": 40,
      "location_limit_in_meters": 22000000,
      "longitude": -73,
      "max_submissions": 500000,
      "max_submissions_per_witness": 10,
      "poster_url": "https://truesnap.s3.us-east-1.amazonaws.com/6176690776340284331.jpg",
      "radius": 22000,
      "reward_per_task": 2,
      "starts_at": "2025-02-21T06:40:28.230Z",
      "submissions": 6,
      "tags": ["loss", "gains"],  
      "total_rewards": 10000,
      "type": "individual"
    }
  ]
}  
```

### Example Task-Type Campaign Response

```json
{
  "result": [
    {
      "banner_url": "https://images.wallpapersden.com/image/download/serene-nature-hd-pixel-art-sunset_bmhlZ22UmZqaraWkpJRnamtlrWZpaGo.jpg",
      "created_at": "2025-02-21T13:07:15.584Z",
      "created_by": "@witnesschain",
      "created_by_publicKey": "0xae3c67152ee393082f85e9d59a471b375f3ce406",
      "currency": "POINTS",
      "description": "This is a test campaign for the type \"task\"",
      "ends_at": "2025-03-06T11:33:07.423Z",
      "fuel_required": 1,
      "id": "my-task-campaign",
      "is_active": true,
      "latitude": 13.03,
      "location_limit_in_meters": 1000,
      "longitude": 77.5,
      "max_submissions": 10000,
      "poster_url": "https://placehold.co/180x320",
      "radius": 100,
      "reward_per_task": 1,
      "starts_at": "2025-02-24T11:33:07.423Z",
      "submissions": 7,
      "tags": [],
      "tasks": {
        "task0": {
          "description": "Test task 0. Upload a random picture to test multi-task campaigns",
          "fuel_required": 1
        },
        "task1": {
          "description": "Test task 1. Upload a random picture to test multi-task campaigns",
          "fuel_required": 1
        },
        "task2": {
          "description": "Test task 2. Upload a random picture to test multi-task campaigns",
          "fuel_required": 1
        }
      },
      "total_rewards": 10,
      "type": "task",
      "whitelist": [
        "0x...",
        "0x..."
      ]
    }
  ]
}
```

### Error Codes

| Status Code | Error Code               | Description                                           |
| ----------- | ------------------------ | ----------------------------------------------------- |
| 400         | INVALID\_REQUEST         | Request is malformed or missing required fields       |
| 400         | INVALID\_CAMPAIGN\_TYPE  | Campaign type must be one of: individual, group, task |
| 400         | INVALID\_COORDINATES     | Invalid latitude or longitude values                  |
| 400         | INVALID\_DATE\_RANGE     | End date must be after start date                     |
| 401         | UNAUTHORIZED             | Authentication token is missing or invalid            |
| 403         | FORBIDDEN                | User does not have permission to perform this action  |
| 403         | CAMPAIGN\_LIMIT\_REACHED | User has reached maximum allowed campaigns            |
| 404         | CAMPAIGN\_NOT\_FOUND     | The requested campaign does not exist                 |
| 409         | DUPLICATE\_CAMPAIGN\_ID  | A campaign with this ID already exists                |
| 429         | RATE\_LIMIT\_EXCEEDED    | Too many requests, please try again later             |
| 500         | INTERNAL\_SERVER\_ERROR  | An unexpected error occurred                          |
| 503         | SERVICE\_UNAVAILABLE     | Service is temporarily unavailable                    |

### Response Fields

#### Common Campaign Fields

| Field                  | Type    | Description                             |
| ---------------------- | ------- | --------------------------------------- |
| id                     | string  | Unique identifier for the campaign      |
| banner\_url            | string  | Banner image URL                        |
| poster\_url            | string  | Poster image URL                        |
| created\_at            | string  | Creation timestamp (ISO 8601)           |
| created\_by            | string  | Username of campaign creator            |
| created\_by\_publicKey | string  | Public key of campaign creator          |
| description            | string  | Campaign description                    |
| starts\_at             | string  | Start timestamp (ISO 8601)              |
| ends\_at               | string  | End timestamp (ISO 8601)                |
| is\_active             | boolean | Active status                           |
| type                   | string  | Campaign type (individual, group, task) |
| tags                   | array   | Array of campaign tags                  |
| submissions            | integer | Current submission count                |

#### Location Fields

| Field                       | Type   | Description                   |
| --------------------------- | ------ | ----------------------------- |
| latitude                    | number | Center latitude               |
| longitude                   | number | Center longitude              |
| radius                      | number | Campaign radius in kilometers |
| location\_limit\_in\_meters | number | Location verification limit   |

#### Reward Fields

| Field             | Type   | Description                     |
| ----------------- | ------ | ------------------------------- |
| currency          | string | Reward currency type            |
| total\_rewards    | number | Total available rewards         |
| reward\_per\_task | number | Reward per completed task       |
| fuel\_required    | number | Required fuel for participation |

#### Task-Type Campaign Fields

| Field     | Type   | Description                         |
| --------- | ------ | ----------------------------------- |
| tasks     | object | Map of task IDs to task definitions |
| whitelist | array  | List of authorized public keys      |


# Challenge APIs

You can find the full API documentation for interacting with the Proof of Backhaul (PoB) and Proof of Location (PoL) core networks, including details about the **Prover Information** endpoints, on the interactive ReDoc page [here](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/Proof-of-X/Proof-of-Backhaul/main/api.json#tag/Prover-Information). This page provides detailed information about the API endpoints, request parameters, response schemas, and usage examples.


# Overview

The Challenge APIs are an HTTP-based API that you can use to programmatically query data about watchtowers/provers, submit and manage challenges. Since the API is HTTP-based it works with any language or software that supports HTTP, including cURL and almost all modern web browsers.

## Basic Concepts <a href="#basics" id="basics"></a>

### Provers

The device connected to Internet whose claimed location or bandwidth needs to be validated

### Watchtowers (aka Challengers)

A pool of decentralized, trustfree servers that validate the location / bandwidth claim of the prover

### Challenge

A series of UDP ping pongs/pings between the prover and watchtowers to validate the claim (Location or Bandwidth)

### Broker

A server which provides APIs for provers/challengers/payers. These APIs are used to login/request-for-challenges/participate-in-challenges/submit-results-of-challenges.

### Challenge Coordinator (CC)

A server which randomly selects eligible challengers for a given challenge.

It ensures that available and compatible challengers are chosen for a given challenge.

CC only responds to events from Broker and does not interact with any other system.


# Getting Started

## Step 1: Pre-login and login

The **pre-login** and **login APIs** are crucial for the security and functionality of the Proof of Bandwidth or Proof of Location system. The APIs handles initial authentication steps, like generating session tokens and validating access. These APIs are foundational for safeguarding the prover's information and controlling system access, ensuring only authenticated users can interact with critical resources

Start the process by performing a **pre-login** and **login** request

{% hint style="info" %}
**Note:** The `{proof_type}` parameter is crucial in all API requests and **must** be set to one of the following values:

* `pol` (Proof of Location)
* `pob` (Proof of Bandwidth)

Be sure to specify the appropriate value based on the context of your proof request.
{% endhint %}

#### Pre-login

{% openapi src="/files/WWLjK2RiH8JZs6E8BepB" path="/proof/v1/{proof\_type}/pre-login" method="post" %}
[challenge\_api.json](https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2FSxD3akB7T6Vy6Ek6wdcA%2Fchallenge_api.json?alt=media\&token=45395a70-77eb-498b-8209-c4ae4f512011)
{% endopenapi %}

#### Login

After the result is obtained, the **/login** api needs to be invoked

{% openapi src="/files/WWLjK2RiH8JZs6E8BepB" path="/proof/v1/{proof\_type}/login" method="post" %}
[challenge\_api.json](https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2FSxD3akB7T6Vy6Ek6wdcA%2Fchallenge_api.json?alt=media\&token=45395a70-77eb-498b-8209-c4ae4f512011)
{% endopenapi %}

## Step 2: Submit an on-chain Challenge Request&#x20;

Refer to the following chain parameters to trigger a on-chain **submitRequest**

| Parameters                                                                                                                                                        | Values                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Chain ID                                                                                                                                                          | 1237146866                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Chain Kind                                                                                                                                                        | Polygon CDK (Validium)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Chain RPC                                                                                                                                                         | <https://blue-orangutan-rpc.eu-north-2.gateway.fm/>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Chain Block Explorer                                                                                                                                              | <https://blue-orangutan-blockscout.eu-north-2.gateway.fm/txs>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Contract Address Proxy to interact to initiate a on-chain challenge                                                                                               | [0x8A02C91373929a4764F015309B072DC9C9Fabc49](https://blue-orangutan-blockscout.eu-north-2.gateway.fm/address/0x8A02C91373929a4764F015309B072DC9C9Fabc49)                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Function to invoke                                                                                                                                                | submitRequest                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| <p>Parameters to pass to <strong>submitRequest</strong><br><strong>- timeout</strong> <br><strong>- attributeIDs</strong><br><strong>- challengeInfo</strong></p> | <p>For PoB,<br><a href="https://github.com/witnesschain-com/pox-scheduler/blob/28b305c1faad39c47ae90e159303bc68695c09a1/src/run_challenge.py#L43"><https://github.com/witnesschain-com/pox-scheduler/blob/28b305c1faad39c47ae90e159303bc68695c09a1/src/run_challenge.py#L43></a><br><br>For PoL,<br><a href="https://github.com/witnesschain-com/pox-scheduler/blob/28b305c1faad39c47ae90e159303bc68695c09a1/src/run_challenge.py#L96"><https://github.com/witnesschain-com/pox-scheduler/blob/28b305c1faad39c47ae90e159303bc68695c09a1/src/run_challenge.py#L96></a></p> |
| Contract ABI                                                                                                                                                      | <https://blue-orangutan-blockscout.eu-north-2.gateway.fm/address/0x39B42E1CA5F34E989Df957f4D391996266a460bB?tab=contract>                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

{% hint style="info" %}
We also have a [sample script](https://github.com/witnesschain-com/pox-scheduler/tree/main) written in Python, to trigger a PoL or a PoB challenge.
{% endhint %}

## Step 3: Trigger a Challenge with the Witness Chain Broker

Pass the **challenge-id** obtained in the previous step to the **challenge-request-dcl API**&#x20;

{% openapi src="/files/WWLjK2RiH8JZs6E8BepB" path="/proof/v1/{proof\_type}/challenge-request-dcl" method="post" %}
[challenge\_api.json](https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2FSxD3akB7T6Vy6Ek6wdcA%2Fchallenge_api.json?alt=media\&token=45395a70-77eb-498b-8209-c4ae4f512011)
{% endopenapi %}

## Step 4: Monitor the status of the Challenge to obtain the results

One can monitor the status of the challenge to obtain the results using the **challenge-status-dcl** API

{% openapi src="/files/TzM16hlXy0ClCPhsIbnm" path="/proof/v1/{proof\_type}/challenge-status-dcl" method="post" %}
[challenge\_api.json](https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2FE7gV5fiTkL764eLCzuS1%2Fchallenge_api.json?alt=media\&token=156dbeea-b4f5-4079-b8cd-e703c0827962)
{% endopenapi %}


# Blogs

Blog articles related to Proof of Location

<table data-view="cards"><thead><tr><th data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><a href="/pages/QU46yuhxTI8WJEMH8CoG">/pages/QU46yuhxTI8WJEMH8CoG</a></td><td><a href="/files/wnIWyitZ2KcuKnaU9SRa">/files/wnIWyitZ2KcuKnaU9SRa</a></td></tr><tr><td><a href="/pages/f5UVa8AkBcyHckvg4LmA">/pages/f5UVa8AkBcyHckvg4LmA</a></td><td><a href="/files/AurY0grEPRhBdrqclfoS">/files/AurY0grEPRhBdrqclfoS</a></td></tr></tbody></table>


# How Proof of Location Works

Explanation of how 360-degree challenger selection improves accuracy

Location verification is a critical component in many modern applications, from supply chain tracking to decentralized finance. Traditional methods often rely on trusted hardware or centralized authorities, creating single points of failure. Witness Chain's innovative Proof of Location protocol takes a fundamentally different approach, leveraging network physics to provide robust location verification without specialized hardware.

### The Core Mechanism: Network Latency as a Distance Proxy

At the heart of Witness Chain's system is a remarkably elegant concept: internet delay can serve as a reliable proxy for physical distance. The protocol works through these key steps:

1. A network of geographically distributed challengers send signed UDP packets to a prover claiming to be at a specific location
2. Both parties cryptographically sign these packets, creating an immutable record of the interaction
3. The measured network delay is converted to an estimated physical distance
4. By combining measurements from multiple challengers, the system triangulates the prover's actual location

This approach provides strong guarantees against manipulation while requiring no specialized hardware on the prover's side.

### Scientific Calibration: Building Reliable Delay-Distance Models

The critical innovation in Witness Chain's approach is how challengers are calibrated. Rather than using theoretical models, each challenger builds an empirical delay-distance curve based on real-world measurements with other known challengers to ensure guarantees against Byzantine behaviour by the prover.&#x20;

What makes this approach particularly powerful is the use of monotone curves - as network delay increases, the estimated distance never decreases. This mathematical property enables the system to provide concrete location guarantees even when facing adversarial provers attempting to manipulate the system.

<figure><img src="/files/dqkMzOXrxZE3uC21dDKS" alt=""><figcaption><p><strong>Fig. 1 Delay-Distance calibration curve for a challenger</strong></p></figcaption></figure>

For calibration, each challenger measures Internet delays with respect to other challengers whose locations are known. Thus a challenger has a series of delay-distance points as shown in Fig. 1 from its measurements. From these measurements a challenger computes a monotone curve shown by the solid line in Fig. 1. The monotone curve has the property that with increasing delay the distance is non-decreasing. This monotone curve enables us to offer location guarantees in case of byzantine prover as illustrated in \[1].

### Geometric Verification: The Intersection of Probability Circles

#### tl;dr

Once each challenger has estimated the prover's distance, Witness Chain employs geometric principles to verify location claims:

1. Each challenger creates a probability circle with radius equal to its estimated distance
2. The prover must be located within the intersection of all these circles
3. The "Location Uncertainty" is defined as the maximum possible distance between the claimed location and the edge of this intersection area

This approach provides a mathematically rigorous bound on location accuracy rather than just a best guess.

#### Detailed Explanation

After each challenger estimates a distance for the delay measured to the prover, we can compute the final location of the prover as follows. As we use a monotone delay-distance curve for the challenger, the prover will be within the circle of radius equal to estimated distance of the challenger centred at the location of the challenger as shown in Fig. 2.&#x20;

Accordingly, if we aggregate across the multiple challengers, the prover will be within the intersection of all the circles from all the challengers. Thus the farthest distance the prover can be from its claimed location is maximum distance between the prover and the periphery of the intersection area, marked as “Location Uncertainty” in Fig. 2. This location uncertainty is the guarantee of our proof of location protocol. For more technical details refer \[1].&#x20;

<figure><img src="/files/nQt30hFsXYPbrQeNU7eM" alt=""><figcaption><p>Fig. 2 Location estimation of the prover</p></figcaption></figure>

### Strategic Challenger Selection: A 360° Perspective

Witness Chain's global network of challengers enables a powerful optimization: strategic challenger selection. By choosing challengers distributed in a 360-degree pattern around the prover's claimed location, the system dramatically reduces the size of the intersection area and consequently the *location uncertainty*.

This strategic selection represents a significant improvement over random challenger assignment, substantially enhancing location verification accuracy without requiring additional infrastructure, as explained in Fig 3

<figure><img src="/files/wnIWyitZ2KcuKnaU9SRa" alt=""><figcaption><p>Fig. 3 Location Uncertainty for spread out challengers</p></figcaption></figure>

### Practical Applications and Future Directions

This technology has far-reaching implications for applications requiring trustworthy location verification:

* Decentralized finance protocols with location-dependent features
* Proof of presence for events or activities / geo-fenced marketing campaigns.
* Geographic access control for sensitive services

As Witness Chain's challenger network continues to expand globally, the protocol's accuracy and resilience will only improve, opening new possibilities for location-verified applications across industries.

### References

1. [BFT-PoLoc: A Byzantine Fortified Trigonometric Proof of Location Protocol using Internet Delays](https://arxiv.org/abs/2403.13230)

<br>

<br>


# Redefining Geolocation Compliance: Witness Chain & Predicate

Witness Chain Enables Onchain Geolocation Verification for the Predicate Ecosystem

### Geolocation Systems

Geolocation is widely used across industries. In the blockchain space, geolocation primarily serves to restrict user access from certain jurisdictions due to legal and regulatory requirements. The most common method of geofencing relies on IP addresses. However, this approach is neither robust nor suitable for decentralized systems. IP addresses are collected at the application frontend, meaning the enforcing entity must control the frontend itself. This introduces a centralization risk and makes the system vulnerable to circumvention via simple methods such as VPNs.

### Smart Contract Level Geolocation Verification

Witness Chain introduces a decentralized proof-of-location (PoL) system. Its network of watchtowers, called InfinityWatch, observes event requests and generates cryptographic location proofs. These proofs offer a robust alternative to traditional geofencing methods.

\
The Predicate Network enables developers to integrate pre-transaction logic into their smart contracts. Using Witness Chain’s proof of location, developers integrating Predicate can add geolocation requirements for transactions. This integration allows developers to take a more robust and decentralized approach, avoiding reliance on IP addresses—a mechanism that is easily bypassed.

Witness Chain’s PoL system can be used to verify the location of swappers in a decentralized exchange pool through Predicate for assets that require geofencing. Location based policies can ensure fair incentive distribution for protocols during major events such as airdrops or token launches—discouraging farming and sniping.&#x20;

### The Future of Decentralized Geolocation and Policies

Witness Chain’s PoL system offers a geofencing solution designed for decentralized environments. Similarly, Predicate policies are designed to be censorship resistant through a distributed network of operators. This allows policies to exist as critical infrastructure for onchain applications.

As risk management practices evolve, traditional, centralized solutions will become obsolete. Decentralized risk management systems, like those enabled by Witness Chain and Predicate, will set the new standard.

### About Witness Chain

Witness Chain is a network that enables verifiable observation and actuation of the real physical world. Observability in the real world ensures protocols can correctly incentivize, regulate, and activate communities that are best suited at the right location at the right time. Witness Chain lays the groundwork for a future where digital agreements are seamlessly anchored in physical reality, driving smarter, more responsive coordination systems.&#x20;

[Twitter](https://x.com/witnesschain) | [Website](https://www.witnesschain.com/)

### About Predicate

Predicate is a network for simplifying transaction prerequisites. Through Predicate, users, developers, and communities define rules for on-chain interactions, integrating expressive pre-transaction logic into decentralized applications. These rules, like legos, can be stacked to form policies, which are enforced by the Predicate Network. For more information, visit: predicate.io.

[Twitter](https://x.com/0xPredicate) | [Website](https://predicate.io/)


# Research

This page holds all the papers published by our research team

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Proof of Backhaul:</strong> <em>Decentralized speedtests for backhaul</em></td><td><p><a href="https://www.witnesschain.com/assets/Proof_of_Backhaul-f417e09d.pdf"><img src="https://www.witnesschain.com/assets/speed-test-866c8aaa.png" alt=""></a></p><p>Decentralised speed-test which can be used by a “payer” to determine the backhaul capacity of a “prover” with the help of a pool of “challengers” who send the challenge traffic to the prover.</p></td><td></td><td><a href="https://arxiv.org/abs/2210.11546">https://arxiv.org/abs/2210.11546</a></td><td><a href="/files/G7aZd1LNeDQQr6JaDNqO">/files/G7aZd1LNeDQQr6JaDNqO</a></td></tr><tr><td><p><strong>Proof of Location:</strong>  </p><p><em>Byzantine fortified trigonometric proof of location protocol using internet delays</em></p></td><td></td><td>Decentralised protocol to verify the geographical locations of IP addresses using Internet delay measurements, enhancing accuracy and Byzantine resistance.</td><td><a href="https://arxiv.org/abs/2403.13230">https://arxiv.org/abs/2403.13230</a></td><td><a href="/files/AzXOYz7DYcpsqdhGBEAY">/files/AzXOYz7DYcpsqdhGBEAY</a></td></tr><tr><td><p><strong>Proof of Diligence:</strong> <em>Cryptoeconomic security for rollups</em></p><p></p><p>Protocol that requires watchtowers to continuously provide a proof that they have verified L2 assertions and get rewarded for the same.</p></td><td></td><td></td><td><a href="https://arxiv.org/pdf/2402.07241.pdf">https://arxiv.org/pdf/2402.07241.pdf</a></td><td><a href="/files/y6Sx93jFM7ilwktraWy3">/files/y6Sx93jFM7ilwktraWy3</a></td></tr><tr><td><strong>Proof of Service:</strong> <em>Two sided measurements</em></td><td><p></p><p>Applying two sided measurements to enable decentralized slicing marketplace and contract-free roaming</p></td><td></td><td><a href="https://conferences.sigcomm.org/hotnets/2022/papers/hotnets22_anand.pdf">https://conferences.sigcomm.org/hotnets/2022/papers/hotnets22_anand.pdf</a></td><td><a href="/files/PaP7uEnAo8kMCQPZFMYo">/files/PaP7uEnAo8kMCQPZFMYo</a></td></tr></tbody></table>


# Talks and Podcasts

Contains all the talks & podcasts that Witness Chain experts have participated in

### CITP Seminar: Pramod Viswanath - Witness Chain: Proofs of Bandwidth - Trust-Free Wireless Networking

{% embed url="<https://www.youtube.com/watch?v=Btvbly8sFps>" %}
Proofs of Bandwidth
{% endembed %}

### From Wireless to Blockchains

{% embed url="<https://www.youtube.com/watch?v=d6K0XYk7WAU>" %}
Podcast - From Wireless to Blockchains
{% endembed %}


# Community

Learn how to get in touch with the Witness Chain product team community.

| Channel  | Join link                       |
| -------- | ------------------------------- |
| Discord  | <https://discord.gg/2n35sBfCNR> |
| X        | <https://x.com/witnesschain>    |
| Telegram | <https://t.me/WitnessReality>   |


# Smart Contracts

Contains the list of smart contracts and their addresses on Goerli

## Mainnet Addresses

### Ethereum

<table><thead><tr><th width="293">Smart Contract</th><th>Address</th></tr></thead><tbody><tr><td>OperatorRegistry Proxy</td><td><a href="https://etherscan.io/address/0xef1a89841fd189ba28e780a977ca70eb1a5e985d">0xEf1a89841fd189ba28e780A977ca70eb1A5e985D</a></td></tr><tr><td>WitnessHub Proxy</td><td><a href="https://etherscan.io/address/0xd25c2c5802198cb8541987b73a8db4c9bcae5cc7">0xD25c2c5802198CB8541987b73A8db4c9BCaE5cC7</a></td></tr><tr><td>AlertManager Proxy</td><td><a href="https://etherscan.io/address/0xd1b991530d07f03226b0192e0161e1142d3552ee">0xD1b991530D07f03226b0192E0161E1142d3552eE</a></td></tr></tbody></table>

### Witness Chain (Polygon CDK) Mainnet Addresses

| Smart Contract                   | Address                                                                                                                            |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Operator Registry Proxy          | [0xd11e55b821aC8509D2C17f5f76193351252d69aE](https://explorer.witnesschain.com/address/0xd11e55b821aC8509D2C17f5f76193351252d69aE) |
| Operator Registry Implementation | [0xF146Ec17Fae59B597cfC957E0cc7046D10d6f924](https://explorer.witnesschain.com/address/0xF146Ec17Fae59B597cfC957E0cc7046D10d6f924) |
| RequestHandlerProxy              | [0x3105CB54f2708D1c9aA9829BEcE64097206df6C2](https://explorer.witnesschain.com/address/0x3105CB54f2708D1c9aA9829BEcE64097206df6C2) |
| ChallengerRegistryProxy          | [0x49220De1c883D9358e3cCe0aB42304460216Dc2C](https://explorer.witnesschain.com/address/0x49220De1c883D9358e3cCe0aB42304460216Dc2C) |
| ProverRegistryProxy              | [0xCdb30BE21A44fB111A48661ECc755B34a41C4e82](https://explorer.witnesschain.com/address/0xCdb30BE21A44fB111A48661ECc755B34a41C4e82) |
| PoBChallengeCoordinatorProxy     | [0xDdB480842858070263Cf143312309F2196be9A0C](https://explorer.witnesschain.com/address/0xDdB480842858070263Cf143312309F2196be9A0C) |
| PoLChallengeCoordinatorProxy     | [0x0E0DDE77B2C190AE83E5a1Da1A52b34f1EfCa4e4](https://explorer.witnesschain.com/address/0x0E0DDE77B2C190AE83E5a1Da1A52b34f1EfCa4e4) |


# File a bug

File and track a bug seen on the Witness Chain app directly here :&#x20;

<https://github.com/witnesschain-com/bug-beacon>


# Introduction

Introduction to the what, why and how of the Watchtowers

{% hint style="success" %}
**We are live on MAINNET**
{% endhint %}

## What are Witness Chain Diligence Watchtowers?

Diligence watchtowers are the first line of defense for optimistic rollups. They enable incentive compatible and crypto-economically-secure Proof-of-Diligence (PoD) to make sure watchtowers are working in the happy path for optimistic rollups.&#x20;

{% hint style="info" %}
**Rollup Watchtower Network is Witness Chain’s in-house DePIN. It is a network of watchtowers spread in various geographies that will monitor the state of optimistic rollups**
{% endhint %}

## Why Watchtowers?

Optimistic rollups attain their hyper scaling by validating the transactions on another chain and post the transaction data publicly for anyone to view. If faulty transactions are detected, the Ethereum validators can be engaged for arbitration using a fraud proof. Thus, the current premise operates under the assumption that when a fault is detected, validators initiate fraud proofs, engaging in a dispute resolution process. However, the existing incentive system only comes into play after a fault has been identified.&#x20;

But who will look for these faulty transaction consistently ? How will these players be incentivized to be diligently carrying out this task when nothing is going wrong?&#x20;

Witness Chain Watchtower protocol is answer to these problems.&#x20;

It is a programmable, trustfree, and decentralized watchtower service that uses an innovative proof of diligence to incentivize the watchtowers in normal path.

## What next ?

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>How <strong>Watchtower Protocol works</strong></td><td></td><td><mark style="color:blue;"><strong>Click here</strong></mark></td><td><a href="/pages/zkCCVS2kSSznxwgayZjD">/pages/zkCCVS2kSSznxwgayZjD</a></td></tr><tr><td>Run the watchtower client as a <strong>Node Operator</strong></td><td></td><td><mark style="color:blue;"><strong>Click here</strong></mark></td><td><a href="/pages/FtFSQNOpJ2A6n0m8K1YE">/pages/FtFSQNOpJ2A6n0m8K1YE</a></td></tr><tr><td><strong>Frequently Asked Questions (FAQs)</strong></td><td></td><td><mark style="color:blue;"><strong>Click here</strong></mark></td><td><a href="/pages/IWpC6pO0Vh2nmYseX2JH">/pages/IWpC6pO0Vh2nmYseX2JH</a></td></tr><tr><td><strong>Quick Links</strong></td><td></td><td><a href="/pages/s62fzZfSXDdpY96RWDiI"><mark style="color:blue;"><strong>Click here</strong></mark></a></td><td></td></tr></tbody></table>


# Proof of Diligence Watchtower Protocol

This section describes the latest version of the watchtower protocol

{% hint style="success" %}
**We are on MAINNET.**
{% endhint %}

{% hint style="warning" %}
For those, who are familiar with our watchtower protocol,

**tl;dr**

This newer version (v2) is aimed towards reducing the gas expenses for proof of diligence submissions by introducing an aggregator layer. The new version also introduces a proof of inclusion protocol.

If you are new to the protocol, please read the [How it works](/archive/proof-of-diligence-watchtower-protocol/how-it-works) section
{% endhint %}


# How it works

Protocol description for the working of the diligence watchtower

<details>

<summary>Table of Contents</summary>

[Introduction](#introduction)

[Participating Entities](#participants-and-entities)

[Protocol Description](#protocol-description)

[Process Flow](#process-flow)

[Proof of Diligence](#proof-of-diligence)

</details>

## Introduction

Security for optimistic rollups (ORs) is derived from dispute resolution at L1 for suspicious transactions. The first line of defense is offered by parties who first identify suspicious transactions.&#x20;

Currently deployed ORs rely on relatively centralized (and trusted) entities who offer this line of defense; e.g., Arbitrum’s state assertion can only be disputed by a set of 12 whitelisted defensive validator nodes.

The surge in demand for app-specific rollups and platforms to support them (e.g., Base and Eigenlayer) results from increasing value and diversity of transactions relying on L2s. In turn, there is a need for decentralized and trust-free validators who diligently raise the alarm when they detect a suspicious transaction.&#x20;

**Witness Chain Watchtowers provide the first line of defense for rollups, which is:**

1. **Trustfree**: provides [Proof of Diligence](#proof-of-diligence) of watchtowers with *Ethereum trust* (through EigenLayer)
2. **Decentralized**: provides a Proof of Location for verifying the geolocation of watchtowers and enforcing desired *physical decentralization*.
3. **Programmable**: provides *SLA smart contracts* to scale the number/stake of watchtowers and their decentralization properties with the value of vulnerable transactions.

## Participants and Entities

The diagram summarizes the different entities participating in the Watchtower network

####

<figure><img src="/files/sEZtfUDMMDrVj5tyeHHF" alt=""><figcaption><p>Participants in the watchtower network</p></figcaption></figure>

#### Stakers

EigenLayer (re)stakers who stake/delegate on/to EigenLayer operators providing Ethereum's crypto-economic trust to the watchtower network.

#### Operators

EigenLayer operators are a pool of staked node operators who run the watchtower client

#### Users/Dapps

Set of Dapps built on top of the Watchtower networking utilizing it's real-time transaction tracer APIs

#### Watchtower (watchtower client)

Watchtower is the independent validation entity which cross verifies the L2 state assertions made on the L1. These watchtowers are incentivized to watch and validate the assertions made by the L2 proposers (even in a happy path scenario (avoiding the [lazy-validator problem](#lazy-validator-problem))) with the help of [Proof of Diligence](#proof-of-diligence)&#x20;

Watchtowers also watch out for L2 transaction inclusions in a block.

#### L2 nodes

L2 network nodes run by the operators alongside the watchtower client. This is the node which computes the state for L2 and is used by the watchtower client to validate the state assertions on the Layer 1. These are L2 archive nodes.

#### Smart contracts

**L1**

A set of smart contracts deployed by WitnessChain on Layer 1 (Ethereum). Following are the descriptions of the smart contracts:

* `OperatorRegistry`: Register a EigenLayer node operator as a watchtower in the network
* `AlertManager`: Raise alerts in case of identifying an invalid state assertion by an L2

**L2**

A set of smart contracts deployed by WitnessChain on Layer 2 (Ethereum) to aggregate the proof of diligence. Following are the descriptions of the smart contracts:

* `DiligenceProofManager`: Submit diligence proofs / inclusion proofs and get rewarded for watching the network

#### Proofs

The Witness Chain watchtower client runs a system of 2 proofs of diligence

1. State Assertions : Validate the L2 state assertions on Ethereum and generate the proof of diligence
2. Transaction Inclusion: Validate the inclusion of a L2 txn in a Block and generate the proof of inclusion

A Watchtower client register's using the `OperatorRegistry` smart contract

On startup, the watchtower subscribes to an L1 node for the real-time events of the L2 assertions (`OutputProposed` event of L2OO in case of optimism). At the same time, the watchtower is also maintaining the L2 state and executing the transaction from the sequencer commitments on L1. &#x20;

When the watchtower notices a state assertion being made on L1, it quickly validates it against the corresponding L2 state for that block number using the state it has been independently advancing.

Two cases might exist:

* State assertion matches the computed L2 state
* State assertion does not match the computer L2 state
  * In this case, the watchtower raises an alarm via the `AlertManager` contract to let the participants be aware of the misbehavior of the &#x20;

Regardless of the case, the watchtower then prepares the [signed proof of diligence](#proof-of-diligence-pod-construction-and-bounty-mining-go-client) and submits it to the `DiligenceProofManager` smart contract to claim their rewards. We call this the bounty mining process, and this ensures the diligent nature of a watchtower even in case of a happy path.

## Process Flow

The diagram summarizes the sequences of steps involved in the Diligence Proof Submission process

<figure><img src="/files/m2jioDKLHsJoeilClOPi" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Pre-requisites - Witness Chain watchtowers are expected to be registered as EL operators**
{% endhint %}

### Proof of Diligence - State Assertions

* The WitnessChain Admin initiates a Bounty for each L2 Chain designated for monitoring.
* Bounty Miners, running Witness Chain Watchtower (WT) clients, register on the Watchtower network and monitor State Assertions on the L2OO smart contract.
* Upon receiving an event from the L2OO contract, WT clients commence validation by tracing (re-executing) transactions on the L2 Archive Node for the proposed block. (*A Witness Chain Watchtower node runs both the watcher software and L2 Archive node*)
* Upon successful reconciliation between L2OO and L2 Node Tracer Results, the watchtower posts a Proof of Diligence (PoD) on the Witness Chain smart contract, called the *DiligenceProofManager*.&#x20;

{% hint style="warning" %}
In the newer v2 release, the Diligence Proof Manager smart contract is created on a Layer 2 Chain. In the earlier releases, this was on Ethereum. The change is done to save gas costs for the watchtower operators
{% endhint %}

* If reconciliation fails, the Watchtower submits an Alert to an *AlertManager* Contract in addition to providing the PoD.
* The Aggregator, which is a centralized entity for now, aggregates the proofs by listening on the events from the DiligenceProofManager contract, computes the winning watchtower and submits the winner details (points) on the Settlement contract (we call it the EigenTower Contract). The Settlement contract is hosted on Ethereum.

{% hint style="info" %}
The Witness Chain Watchtower client also accumulates the proofs (at the off-chain client side) for a block of period, before posting on the L2 contract. This is applicable for Proof of Transaction Inclusions as it accumulates proofs across multiple blocks before posting it on the L2 contract
{% endhint %}

{% hint style="info" %}
The scope of currently described PoD construction is limited to op-stack based L2 chains only. We monitor Optimism, Base and Zora
{% endhint %}

### Proof of Diligence (PoD) Construction and Bounty Mining (Go Client) <a href="#proof-of-diligence-pod-construction-and-bounty-mining-go-client" id="proof-of-diligence-pod-construction-and-bounty-mining-go-client"></a>

The actual proof of diligence, which is verified on the `DiligenceProofManager` smart contract and is used for rewards is defined as below:

* <mark style="color:blue;">Signed PoD = Sign(Hash(prefix || PSH)), where</mark>
  * <mark style="color:blue;">\`prefix\` is added just for compliance with ethereum chain</mark>&#x20;

    ```
    prefix := []byte("\x19Ethereum Signed Message:\n32")
    ```
  * <mark style="color:blue;">PSH =</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">Hash</mark>*<mark style="color:blue;">(</mark>*<mark style="color:blue;">latestBlockNumber</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">||</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">midPointPenultimateBlock</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">|| midPoint || version\_number)</mark>
    * *<mark style="color:blue;">Hash</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= Keccak256Hash</mark>
    * *<mark style="color:blue;">latestBlockNumber</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= the L2 block number for which the PoD is signed/computed. This is the same L2 blocknumber that is currently proposed on L2OO</mark>
    * *<mark style="color:blue;">midPointPenultimateBlock</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= the state root after the midpoint transaction of the block before the latestBlockNumber (ref.</mark> [<mark style="color:blue;">intermediate state roots</mark>](#the-intermediate-state-roots)<mark style="color:blue;">)</mark>
    * *<mark style="color:blue;">midPoint</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= the state root after the midpoint transaction of the latestBlockNumber’th block</mark>
    * *<mark style="color:blue;">version\_number</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= proof of diligence version number, which is incremented every time there is a protocol update. It is currently set to \`0\`</mark>

The SignedPoD is submitted to the `DiligenceProofManager` smart contract.&#x20;

### Proof of inclusion - Transaction inclusions

* Proof of inclusion is a guarantee provided by the watchtower that it has seen the particular txn (with a given txn hash) being included in a L2 block. This is presented in the form of a signed Txn Receipt received from the watchtower node
  * These receipts can belong to unsafe, safe, or finalized blocks of L2 and the status can be queries via the transaction tracer API
* Many blocks' worth of txn receipts are batched to commit to the contract, and the batch size is configured on the Diligence Proof Manager (DPM) contract
* Proof of inclusion tech workflow:
  * Upon startup, the watchtower subscribes to L2 block head
  * On every new block added, it performs following action(s)
    * Fetch all receipts in the block
    * Prepare Proof of inclusion for the block
    * Add the proof of inclusion of the block (receipt trie root hash) to a [merkle tree](#the-proof-of-inclusion-merkle-tree)
    * Once batch is completed -> post the signed batch to the submission chain
  * The watchtower also caches these receipts for the transaction tracer APIs to query from, reducing the latency for Dapps using the service

### Proof of Inclusion (PoI) Construction <a href="#proof-of-diligence-pod-construction-and-bounty-mining-go-client" id="proof-of-diligence-pod-construction-and-bounty-mining-go-client"></a>

The proof of inclusion , which is submitted to `DiligenceProofManager` smart contract and is used for rewards is defined as below:

<mark style="color:blue;">Signed PoI = Sign(Hash(prefix || PSH)), where</mark>

* <mark style="color:blue;">\`prefix\` is added just for compliance with ethereum chain</mark>&#x20;

  ```
  prefix := []byte("\x19Ethereum Signed Message:\n32")
  ```
* <mark style="color:blue;">PSH =</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">Hash</mark>*<mark style="color:blue;">(blockNumber,inclusionProofMerkleRoot,versionNumber)</mark>
  * *<mark style="color:blue;">Hash</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= Keccak256Hash</mark>
  * <mark style="color:blue;">blockNumber = decimal representation of the block number of last block in the batch</mark>
  * <mark style="color:blue;">inclusionProofMerkleRoot = the hexadecimal encoding of root hash of the</mark> [<mark style="color:blue;">merkle tree</mark>](#the-proof-of-inclusion-merkle-tree)
  * <mark style="color:blue;">versionNumber = the proof of inclusion version number, it is currently set to 0</mark>

## Notes

### The intermediate state roots

* As specified in PoD construction, the protocol requires the watchtower to commit to some of the intermediate states of execution across 2 proposed output roots.&#x20;
* To achieve this we make use of (op-geth in op-stack) geth’s tracer APIs
* In particular, we use the \`debug.intermediateRoots\` by providing it the block hashes
* This works via a re-execution of transaction from an earlier state in the history which is available to the node, which in our case would be the state at latestBlockNumber-2’th block and latestBlockNumber-1’th
* As it re-executes the transaction in those specific blocks, it stores the state roots after each transaction and outputs them in a list for our watchtower client to further process and get the midpoint root alone
* This ensures, that node had the head state after each L2 block and that it actually executed the

### The Proof of Inclusion Merkle tree

<div data-full-width="false"><figure><img src="/files/YqojpuP4NmgmFUtGQAYo" alt=""><figcaption><p>Proof of Inclusion Merkle Tree Example</p></figcaption></figure></div>

* The merkle tree is formed by placing the receipt root hashes of the blocks involved in the batch at the leaf nodes
* As an example if batch size is 4, and 455 happens to be a start block of the batch, then the tree would look something like shown in the example figure above
* 4 consecutive blocks, 455-458 both inclusive, are part of the batch
* Receipt root hash of each of these blocks is placed as leaf node in the merkle tree
* <mark style="color:blue;">node 1,2 hash</mark> forms the <mark style="color:blue;">inclusionProofMerkleRoot</mark> for this example batch

### Lazy Validator Problem

Since watchtowers are also required to execute the entire batch of L2 transactions, they can earn rewards by performing their duties diligently. This role closely resembles that of the asserter in the original optimistic rollup system, who posts computation results in exchange for rewards. As a result, one prominent challenge the watchtower design must confront is the “lazy watchtower” problem. This issue arises because of two main reasons:&#x20;

(1) rational watchtowers may submit arbitrary responses if the results lack verification process

(2) they might opt out of protocol participation if the associated costs outweigh potential rewards.

In essence, the watchtowers must provide a form of evidence for their work and the protocol must offer sufficient incentives to encourage participants to actively and consistently perform tasks.<br>

Read more about the Problem and Solution to it in our [research](https://arxiv.org/pdf/2402.07241.pdf).


# Diligence Watchtower Roadmap

| Testnet Phases     | Deliverables                                                                                                                                                                                                                                 |                        |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| Phase 1 (Dec 2023) | <ul><li>Watchtower client</li></ul><p></p><ul><li>Integration with EigenLayer contracts</li></ul><p></p><ul><li>Onboarding Node Operators</li></ul><p></p><ul><li>OP Stack Chains</li></ul>                                                  | Completed (on Sepolia) |
| Phase 2 (Mar 2024) | <p></p><ul><li>Watchtower client</li><li>Integration with EigenLayer contracts</li><li>Onboarding Node Operators</li><li>OP Stack Chains</li></ul><p></p><ul><li>Aggregator</li></ul><p></p><ul><li>Proof of Transaction Inclusion</li></ul> | Completed (on Holesky) |

| Mainnet Stages           |                                                          |      |
| ------------------------ | -------------------------------------------------------- | ---- |
| Phase 1 (Apr 11)         | <ul><li>Operator Whitelisting and Registration</li></ul> | Done |
| Phase 2 (Apr 22-29)      | <ul><li>Proof Submissions</li></ul>                      | Done |
| Phase 3 (Apr 29 onwards) | <ul><li>Aggregator Settlement</li></ul>                  | Done |


# Watchtower Architecture

Software Architecture - client, APIs and contracts

## Architecture

<figure><img src="/files/fkewKEvlAGCGDONwrAAK" alt=""><figcaption></figcaption></figure>

WitnessChain Watchtowers' software stack comprise of &#x20;

1. Watchtower Client (written in Go)&#x20;
2. On-chain Smart Contracts on Ethereum & on a Layer-2 chain
   1. **Layer 1:** Operator Registry, Settlement (ServiceManager aka EigenTower) & Alert Manager
   2. **Layer 2:** DiligenceProofManager Contract
3. Centralized Aggregator (to submit "batched" bounty settlements (rewards) on Ethereum)

## Watchtower client

### Proof of Diligence

At a high level, the process of L2 state validation in a watchtower node client has 4 stages

1. Output State Root Extraction from L1
2. Output State Root Extraction (Tracer execution) from L2 Node
3. Comparison & generating proofs of diligence
4. Smart Contract integration to publish the proofs

<figure><img src="/files/2jXZLGH5e23VSXTvweMt" alt=""><figcaption><p>Sequence of Steps</p></figcaption></figure>

## List of Key Smart Contracts and their key functions

### 1. OperatorRegistry

This is Registry-type contract for keeping track of operators. It is used for registering and deregistering new operators. Only registered and delegated EigenLayer operators are allowed into the watchtower network

### *<mark style="color:green;">addToOperatorWhitelist(\[OperatorAddress])</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Contract Owner</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">OperatorsWhiteListed(operatorsList, block.number);
</code></pre></td></tr></tbody></table>

* Adds the list of operators to the whitelist mapping

### *<mark style="color:green;">suspend</mark>*<mark style="color:green;">(operator)</mark>

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Contract Owner</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">OperatorSuspended(operatorAddress, block.number);
</code></pre></td></tr></tbody></table>

* Removes the operator from the whitelist mapping

### *<mark style="color:green;">registerWatchtowerAsOperator(watchtower, expiry, signedMessage)</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Node operator</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WatchtowerRegisteredToOperator(msg.sender, _watchtowerAddress, block.number);
</code></pre></td></tr></tbody></table>

* Registers the operator as a watchtower

### *<mark style="color:green;">deRegister(watchtowerAddress)</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Node operator</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WatchtowerDeRegisteredFromOperator(msg.sender, watchtowerAddress, block.number);
</code></pre></td></tr></tbody></table>

* Deregisters the watchtower
* The watchtower client will no longer be able to post any proofs, until the operator registers the watchtower address again

### 2. DiligenceProofManager

The DiligenceProofManager Contract contains functionality for miners (aka Watchtowers) to submit (mine) their Proofs of Diligence for a Bounty Period (which is the period between 2 L2 Txn Batch submissions). After the next L2 output state root is posted on L1, the bounty is rewarded to the miner. Bounties are given for every L2 Output (L2 Block).&#x20;

### *<mark style="color:green;">setPoDClaimBounties(\_chainID, \_claimBounties)</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Owner of the Contract</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">NewPODBountyInitialized(_chainID, _claimBounties);
</code></pre></td></tr></tbody></table>

* The owner of the Contract sets the Bounty Amount.
* Consider PoD bounties are just reward points for now. Lets say 1 point for every L2 block mined successfully by a WatchTower. A detailed Points documentation is in progress.

### *<mark style="color:green;">setPoIClaimBounties(\_chainID, \_claimBounties)</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Owner of the Contract</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">NewPOIBountyInitialized(_chainID, _claimBounties);
</code></pre></td></tr></tbody></table>

* The owner of the Contract sets the Bounty Amount.
* Consider PoI bounties are just reward points for now. Lets say 1 point for every L2 block mined successfully by a WatchTower. A detailed Points documentation is in progress.

### *<mark style="color:green;">submitPoDProof (chainID, l2\_blockNumber, proofOfDiligence, signatureProofOfDiligence)</mark>*

| **Called By** | WatchTower (EigenLayer Node Operator) |
| ------------- | ------------------------------------- |
| **Returns**   | None                                  |
| **Emits**     | NewBountyClaimed event                |

* Watchtower(s) submits/mine a L2 block by submitting the Hash(intermediate state root) and signing the Hash.
* Validations on Contract take care if the right sender is sending this transaction

### *<mark style="color:green;">submitPoIProof (chainID, l2\_blockNumber, proofOfDiligence, signatureProofOfDiligence)</mark>*

| **Called By** | WatchTower (EigenLayer Node Operator) |
| ------------- | ------------------------------------- |
| **Returns**   | None                                  |
| **Emits**     | NewBountyClaimed event                |

* Watchtower(s) submits/mine a L2 block for a PoI proof.
* Validations on Contract take care if the right sender is sending this transaction

### 3. AlertManager

This contract is used for keeping track of alerts raised by watchtowers

### *<mark style="color:green;">raiseAlert(chainID, l2BlockNumber, originalOutputRoot, computedOutputRoot, proofofDiligence)</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Node Operator</td></tr><tr><td><strong>Returns</strong></td><td>None</td></tr><tr><td><strong>Emits</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">NewAlertRaised(msg.sender, _chainID, _l2BlockNumber);
</code></pre></td></tr></tbody></table>

* Raise an alert when there is a mismatch in output root between what is exeucte on L2 Node and asserted on L1 Contract

### *<mark style="color:green;">getAlerts(chainID,L2BlockNumber)</mark>*

<table data-header-hidden><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Called By</strong></td><td>Node Operator</td></tr><tr><td><strong>Returns</strong></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">// chainID => block number => list of alerts raised
<strong>mapping(uint256 => mapping(uint256 => Alert[]))
</strong></code></pre></td></tr><tr><td><strong>Emits</strong></td><td>None</td></tr></tbody></table>

* Get all alerts raised so far a particular chainID and L2BlockNumber

### 4. WitnessHub (AVS ServiceManager Contract)

The WitnessHub Contract enables the aggregator to process settlements for collective submissions of Proofs of Diligence and Proofs of Inclusion provided by watchtowers on a Layer 2 (L2) blockchain. These submissions correspond to a Bounty Period, which is defined as the interval between two transactions on the L2 chain.

### *<mark style="color:green;">updateRewards (</mark>*<mark style="color:green;">chainID, blockNumBegin, blockNumEnd, operatorsList, proofRewards, rewardHash</mark>*<mark style="color:green;">)</mark>*

| **Called By** | Aggregator       |
| ------------- | ---------------- |
| **Returns**   | None             |
| **Emits**     | NewRewardsUpdate |

* Accepts a list of operators and proof rewards, which correspond to the aggregated rewards for the operators across their watchtowers's proof submissions for a particular chain id and a range of blocks. This function may only be called by the aggregator.

## Aggregator

An aggregator, a centralised entity managed by Witness Chain, listens for the PoD and PoI submissions made by the watchtowers on the L2 chain contracts (DiligenceProofManager). It employs a "weighted stake" strategy to determine the winning watchtower for each group of blocks.&#x20;

This approach allows for a fair and transparent winning process. The winning watchtower's information, along with the number of wins and a Proof of Settlement, is then recorded on the WitnessHub settlement contract on Layer 1 (L1).&#x20;

The aggregator has the flexibility to adjust the settlement frequency based on gas costs, optimizing the balance between operational efficiency and cost-effectiveness.


# Chains watched

Chains that are watched by watchtower clients

| L2 Chains Watching                   |
| ------------------------------------ |
| Optimism-Sepolia : Chain ID 11155420 |
| Base-Sepolia : Chain ID 84532        |
|                                      |


# Smart Contracts

Contains the list of smart contracts and their addresses

## Mainnet Addresses

### Ethereum

<table><thead><tr><th width="293">Smart Contract</th><th>Address</th></tr></thead><tbody><tr><td>OperatorRegistry Proxy</td><td><a href="https://etherscan.io/address/0xef1a89841fd189ba28e780a977ca70eb1a5e985d">0xEf1a89841fd189ba28e780A977ca70eb1A5e985D</a></td></tr><tr><td>WitnessHub Proxy</td><td><a href="https://etherscan.io/address/0xd25c2c5802198cb8541987b73a8db4c9bcae5cc7">0xD25c2c5802198CB8541987b73A8db4c9BCaE5cC7</a></td></tr><tr><td>AlertManager Proxy</td><td><a href="https://etherscan.io/address/0xd1b991530d07f03226b0192e0161e1142d3552ee">0xD1b991530D07f03226b0192E0161E1142d3552eE</a></td></tr></tbody></table>

### Witness Chain (Polygon CDK) Mainnet Addresses

| Smart Contract                         | Address                                                                                                                            |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Operator Registry Proxy                | [0xd11e55b821aC8509D2C17f5f76193351252d69aE](https://explorer.witnesschain.com/address/0xd11e55b821aC8509D2C17f5f76193351252d69aE) |
| Operator Registry Implementation       | [0xF146Ec17Fae59B597cfC957E0cc7046D10d6f924](https://explorer.witnesschain.com/address/0xF146Ec17Fae59B597cfC957E0cc7046D10d6f924) |
| Diligence Proof Manager Proxy          | [0x0384E6249E2aF51E58662eBCf70E0C28482C73d4](https://explorer.witnesschain.com/address/0x0384E6249E2aF51E58662eBCf70E0C28482C73d4) |
| Diligence Proof Manager Implementation | [0x63b27c8e6dd823C4eD3855B5056CD82B5AFe5cC2](https://explorer.witnesschain.com/address/0x63b27c8e6dd823C4eD3855B5056CD82B5AFe5cC2) |

## Testnet Addresses

### Holesky Addresses

<table><thead><tr><th width="293">Smart Contract</th><th>Address</th></tr></thead><tbody><tr><td>OperatorRegistry Proxy</td><td><a href="https://holesky.etherscan.io/address/0x708CBDDdab358c1fa8efB82c75bB4a116F316Def">0x708CBDDdab358c1fa8efB82c75bB4a116F316Def</a></td></tr><tr><td>WitnessHub Proxy</td><td><a href="https://holesky.etherscan.io/address/0xa987EC494b13b21A8a124F8Ac03c9F530648C87D">0xa987EC494b13b21A8a124F8Ac03c9F530648C87D</a></td></tr></tbody></table>

### Witness Chain (Polygon CDK) Testnet Addresses

| Smart Contract                         | Address                                                                                                                                                  |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Operator Registry Proxy                | [0x26710e60A36Ace8A44e1C3D7B33dc8B80eAb6cb7](https://blue-orangutan-blockscout.eu-north-2.gateway.fm/address/0x26710e60A36Ace8A44e1C3D7B33dc8B80eAb6cb7) |
| Operator Registry Implementation       | [0x739ff1de5f47826C38f4419e08ea08C6D7707F19](https://blue-orangutan-blockscout.eu-north-2.gateway.fm/address/0x739ff1de5f47826C38f4419e08ea08C6D7707F19) |
| Diligence Proof Manager Proxy          | [0x7AB3b14F3177935d4539d80289906633615393F2](https://blue-orangutan-blockscout.eu-north-2.gateway.fm/address/0x7AB3b14F3177935d4539d80289906633615393F2) |
| Diligence Proof Manager Implementation | [0x0Cccb5A0511Ded6B98f4729c753394f7D1405572](https://blue-orangutan-blockscout.eu-north-2.gateway.fm/address/0x0Cccb5A0511Ded6B98f4729c753394f7D1405572) |


# Quick Links

This page contains the list of quick links for a node operator to get going !

| Want to participate in the watchtower network? | Join us on our [Discord ](https://discord.gg/ZwdnTBAtqV)or put a message on [Contact us](https://www.witnesschain.com/contact)             |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| How to setup a watchtower client ?             | <p><a href="/pages/D8DlZcAnuVxkeernjdrA">Mainnet watchtower</a></p><p><br><a href="/pages/HxHtggHzunuOIqBwbHO5">Holesky watchtower</a></p> |
|                                                |                                                                                                                                            |


# FAQs

Frequently Asked Questions

## What is a Watchtower Address ?

Watchtower address is an Ethereum Wallet (EOA) address and plays a crucial role in the Watchtower client's operations for various reasons:

1. It is employed for signing and submitting transactions specifically related to Watchtower operations, such as submitting Proofs of Diligence.
2. It enhances security measures by avoiding the exposure of the private keys associated with the Operator's Earnings Address (registered on EigenLayer) within the Watchtower client software.
3. The Watchtower address facilitates the management of multiple watchtowers by allowing for distinct tracking, if a node operator runs multiple watchtower nodes.

## How is a Watchtower address different from Operator Address ?

Operator Addresses are the addresses registered on EigenLayer as a node operator role. You can read more about Node operators' Keys at <https://docs.eigenlayer.xyz/operator-guides/operator-installation>&#x20;

{% hint style="info" %}
Witness Chain Watchtowers use Operator Addressses to validate if they are valid EigenLayer Operators.&#x20;

Slashing is not enabled right now. But in further releases, the Operator Address would help to opt-in for slashing purposes
{% endhint %}

## What happens in the case of an Alarm?

Currently, the watchtower submits an Alarm on the AlertManager contract. In the future releases, we expect the following 2 processes to kick in&#x20;

* Other watchtowers can challenge the Alarm through a dispute resolution process, thereby leading to a Slashing situation
* Applications that require the watchtower services can also subscribe to the contract and take corrective action based on these alerts

## Why am I getting a "not found" error when looking out for proposals on L2?

If you face an error which is something like what is shown in this screenshot, most likely, you are running into a "delayed sync" on the L2 node.

<figure><img src="/files/ZeZUn2f59NMjvtKCjT2C" alt=""><figcaption></figcaption></figure>

Please run ./run-estimate.sh to check if the L2 node you are watching is synced completely.

## Why is the operator private key required, TEMPORARILY?

The operator private key is required for the registration of the operator with the Witness Chain AVS. Once the registration process is completed, remove the entry from the config files, until you need it again to interact with the utility for any other registration/deregistration purposes

## Explain how the EL operator and watchtower keys are used

#### During the registration process

1. **registerOperatorToAVS** - EL Operator's Key is used to sign the txn<br>
2. **registerWatchtowerAsOperator** - EL Operator's Key is still used to sign the txn, but the function also takes in a signedMesage field (signature obtained by the watchtower private key signing the operator address)

#### During the proof submission process

1. **submitPoD/PoIProof** - Only the watchtower keys are used for signing.

## Is there a minimum stake required to be restaked on for the operator to run the watchtower?

No. There is no minimum stake required as of now.

However, there's a process in place for whitelisting, which involves thorough checks to prevent spam actors from being approved.

Watching a chain also demands substantial infrastructure, including the setup of L2 Archive nodes, which typically only committed operators undertake. Furthermore, providing proof of due diligence requires operators to incur gas fees.

## What to do I get this error: Registering watchtower as operator failed: insufficient funds for gas \* price + value on the L2 chain?

Please use the [faucet](https://blue-orangutan-faucet.eu-north-2.gateway.fm) to fund you operator and watchtower addresses

{% hint style="info" %}

{% endhint %}


# For the node operators

Guide for setting up a watchtower node

Operating as a watchtower in the WitnessChain Network entails a crucial responsibility of monitoring the accuracy of L2 state assertions made by the proposer. This guide offers information on setting up a watchtower node for the WitnessChain Network


# Node requirements

Node requirements for watchtower nodes

### Who are the watchtower nodes?

WitnessChain watchtowers are nodes running watchtower client software that are watching for discrepancies between state output roots asserted on L1 Chain  (by the L2 Proposers) and the State output Root obtained on a L2 Archive Node (usually running on the same machine as the watchtower client)

{% hint style="info" %}
More configurable security trust levels will be available in the future versions depending on the requirements of the applications. Examples are watching for correctness of the batches submitted on the Inbox contract by the Sequencer.
{% endhint %}

### Pre-requisites

* Nodes seeking membership into the watchtower network need to restake through EigenLayer. The Node operator should already be a registered and delegated operator with EigenLayer

{% hint style="info" %}
Currently, we don't necessitate any minimum thresholds on the stakes delegated to the operator. This can change in the future
{% endhint %}

* Nodes should install an Archive node of the L2 Chain that the watchtower currently supports. There are different types of confirgurations possible. They are discussed in the [Setup for node operators](/archive/for-the-node-operators/watchtower-setup) section. List of L2 chains supported are available [here](/archive/watchtower-protocol-architecture-v1/chains-supported)

{% hint style="info" %}
Currently, the clients don't have the option to choose the L2 chains that they would like to watch.
{% endhint %}

### Supported OS architecture

We officially support the following architectures

* `linux/arm64`
* `linux/x86_64`

Other architectures might work, but they are not fully tested

### Node Hardware requirements

To prepare for the upcoming Testnet, the Watchtower nodes are advised to be prepared with the following minimum recommended hardware requirements:&#x20;

* `4+ cores CPU`
* `16GB+ RAM`
* `SSD - 1TB+ of free space`
* `200+ Mbps Network Bandwidth Performance`

{% hint style="info" %}
The node operator is required to run an Archive Node for the L2 Chain they are monitoring, which increases the hardware demands on the node.

The watchtower docker container that monitors itself is very light. It needs less than 100MB.&#x20;
{% endhint %}

{% hint style="warning" %}
These requirements will continually be tested, benchmarked and revised by the engineering team and community.
{% endhint %}


# Watchtower setup

Watchtower Client Setup for an EigenLayer node operator

Click on one of the cards to setup the watchtower on the respective chain

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>Mainnet setup</strong></td><td><a href="/pages/D8DlZcAnuVxkeernjdrA">Click Here</a></td><td><a href="/pages/D8DlZcAnuVxkeernjdrA">/pages/D8DlZcAnuVxkeernjdrA</a></td></tr><tr><td></td><td><strong>Holesky setup</strong></td><td><a href="/pages/HxHtggHzunuOIqBwbHO5">Click Here</a></td><td><a href="/pages/HxHtggHzunuOIqBwbHO5">/pages/HxHtggHzunuOIqBwbHO5</a></td></tr></tbody></table>


# \[ARCHIVE] Mainnet Setup

Watchtower Client Setup for an EigenLayer node operator

{% hint style="info" %}
**Currently on MAINNET**
{% endhint %}

We have our pre-built binaries in form of container images hosted on docker hub. The following is a quick start guide on running the same for a node operator who is interested to setup a diligence watchtower on the **Ethereum Mainnet chain**

## Stages of Mainnet

| Stage 1 | <ul><li>Operator Whitelisting</li><li>Operator Registration on L1</li><li>Start with Operator Watchtower Client Setup              </li></ul> | From Apr 11 onwards                             |
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Stage 2 | <ul><li>Operator Proof Submissions</li></ul>                                                                                                  | Tentative date : 2 weeks from Stage 1           |
| Stage 3 | <ul><li>Aggregator Settlement</li></ul>                                                                                                       | Tentative date : 1 week from Stage 2 completion |

## Prerequisites

* Read the [Node Requirements](/archive/for-the-node-operators/node-requirements), if you haven't
* Access
  * Watchtower Node Operator should be a registered EigenLayer Node Operator.&#x20;
    * [Formal guide to register](< https://docs.eigenlayer.xyz/operator-guides/operator-introduction>)
  * Registered [EL Operator ](https://docs.eigenlayer.xyz/operator-guides/operator-introduction)needs to be whitelisted on Witness Chain Network. Whitelisting will be done with the help of the Witness Chain team through a whitelisting process.  If you are not sure how, [Steps for setup](#steps-for-setup) will guide you through it.&#x20;
* Software
  * Docker client, engine and container runtime installed (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* Hardware
  * Hardware requirements for the watchtower node can accessed [here](/archive/for-the-node-operators/node-requirements)
  * One of the node configurations as described in the [Node Types](#node-types) section below. Don't worry about how to configure right now ! As long as you have access to one of the configurations, we are good. We have you covered in the [Steps for setup](#steps-for-setup) section !

## Node Types

The node operator is expected to deploy the watchtower container alongside both L1 and L2 Archived nodes in the ideal scenario. But, we offer a few more configurations if you would like to re-use some of your existing infrastructure or setup. The configuration parameters for the L1 and L2 Archived nodes may belong to one of the following distinct categories.

| Configuration Type                                                                                                                        | L1 Node                           | L2 Node                                                            |
| ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------ |
| [Light](/archive/for-the-node-operators/watchtower-setup/holesky-setup/l2-archive-node-setup-guide#light-configuration-for-l2-node-setup) | Use a Hosted L1 Node RPC Provider | Use Witness Chain provided L2 Node snapshot  to bootstrap the node |
| Medium                                                                                                                                    | Use a Hosted L1 Node RPC Provider | Run an L2 Archive Node synced from a public checkpoint             |
| Full                                                                                                                                      | Run an L1 full Node               | Run an L2 Archive Node synced from a public checkpoint             |

## Steps for setup

{% hint style="danger" %}
**Note:** Make sure there aren't any older version of watchtower images or containers. Use the below command to remove older/stale images

`docker rm <stale_container_id>`

`docker rmi -f <stale_image_name>`
{% endhint %}

### **Step 1: Register with EigenLayer as an Operator**&#x20;

{% hint style="info" %}
ONLY If you aren't yet an EigenLayer Operator yet, HOW TO can be found [here](https://docs.eigenlayer.xyz/operator-guides/operator-introduction)
{% endhint %}

### **Step 2: Get whitelisted on the Watchtower Network**.&#x20;

The Witness Chain watchtower network is a permissioned network currently.  Please connect with us on our [Discord](https://discord.gg/7hRNBDeY5e), if you want to become a watchtower operator

### Step 3: Register the operator on the Witness Chain Watchtower Network&#x20;

{% hint style="info" %}
Before you start any activity on this network, ensure your operator address is sufficiently funded to cover the gas costs for registration
{% endhint %}

Register your EL operator address on the  WitnessChain **OperatorRegistry** contract. You can do so with the help of our CLI utility.&#x20;

#### Prerequisites

The CLI tool expects Ubuntu 22.04 (if you are running on linux) or if you are running on Ubuntu 20.04, ensure the glibc version is 2.34+&#x20;

```bash
# Run ldd --version to get the GLIBC version
ldd --version
```

#### Step 3.1 : Installation and Running the CLI

1. Installation:

   ```bash
   curl -sSfL https://witnesschain-com.github.io/install-operator-cli | bash
   ```

2. Running:

   <pre class="language-bash"><code class="lang-bash"><strong>export PATH="$PATH:~/.witnesschain/cli/"
   </strong>watchtower-operator --version

   Expected VERSION:
      v0.3.0 and higher
   </code></pre>

{% hint style="warning" %}
If you are facing the following error, please upgrade to Ubuntu 22.04

$ watchtower-operator --version

watchtower-operator: /lib/x86\_64-linux-gnu/libc.so.6: version \`GLIBC\_2.32' not found (required by watchtower-operator)

watchtower-operator: /lib/x86\_64-linux-gnu/libc.so.6: version \`GLIBC\_2.34' not found (required by watchtower-operator)
{% endhint %}

#### Step 3.2 : Registering the operator and the watchtowers on Ethereum Mainnet (L1)

Once you've ensured the tool is installed correctly, run the below commands to register the operator with our AVS and associate the watchtowers to the operator.

{% hint style="info" %}
**Note:** Refer to our [FAQs](/archive/proof-of-diligence-watchtower-protocol/faqs#how-is-a-watchtower-address-different-from-operator-address) to understand the difference between watchtower addresses and operator addresses
{% endhint %}

**Setup the configuration files for the OPERATOR CLI**

#### operator-config.json

```
# Set of watchtower private keys that will sign the Diligence Proofs. 
# This is used for registration purposes
# Registration will happen both on L1 and L2 simultaneously
```

```json
{
  "watchtower_private_keys": [
    "<raw-watchtower-private-key e.g. 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef>"
  ],
  "operator_private_key": "<raw-watchtower-private-key e.g. 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef>",
  "eth_rpc_url": "https://eth.llamarpc.com", 
  "proof_submission_rpc_url": "https://rpc.witnesschain.com"
}
```

{% hint style="danger" %}

<pre><code>If your operator address is already registered on L1, set

<strong>"eth_rpc_url": ""
</strong>
This will register the Operator EoA only on L2.
</code></pre>

{% endhint %}

```sh
# Registers the Operator to WitnessHub AVS on EigenLayer 
# This is required for the Operator to be listed on EigenLayer's App

# Witnesschain Txns can be monitored via Blockscout at 

# Feel free to skip if this step is already carried out

$ watchtower-operator registerOperatorToAVS --config-file <path to L1 config file>
```

```bash
# Registers the Operator's watchtower to WitnessHub AVS on Layer 1
# This registration is required for operators to be associated with the 
# points awarded as a result of diligently watching the chains.
# To understand what are watchtowers, please read the FAQs

watchtower-operator registerWatchtower --config-file <path to L1 config file>
```

### Step 4: Submitting the bounties

1. Post the registrations are complet&#x65;**, install the watchtower client**, by running the following command.

```sh
curl https://witnesschain-com.github.io/install-watchtower | sh
```

The above command will guide you through the rest of installation process.


# L2 Archive Node Setup guide

Welcome to this guide on setting up rollup nodes (optimism and base) for watchtower clients.

A watchtower client needs a rollup node to locally and independently verify transactions on an optimistic blockchain network. In this guide, we will be using the docker compose utility to setup the L2 archive node(s).

### Clone the setup repository

First, lets clone the[ setup-rollup](https://github.com/witnesschain-com/setup-rollup) repository that contains docker compose YAML file.

{% hint style="info" %}
**Note**: The disk must have at least 2 TB of free disk space.
{% endhint %}

```
git clone https://github.com/witnesschain-com/setup-rollup.git
```

### Step 2: Configure the network parameters

There are two main files (`geth.yml` and `node.yml`) that need to be configure with the rollup network parameters.

In the `geth.yml`, make the following changes:

1. Change the `--network=<value>` with one of the following values: `op-mainnet` for optimism, and `base-mainnet` for base. A full list of network options is available at [Optimism Docs](https://docs.optimism.io/builders/node-operators/management/configuration#network).

In the `node.yml`, file configure the following three parameters:

1. Change the `--network=<value>` to the rollup that you configured in the previous step, i.e. `op-mainnet` or `base-mainnet`.
2. Change the `--l1=<value>` to your L1 (Ethereum Mainnet) node address.&#x20;
3. Change the `--l1.beacon=<value>` to your Ethereum Mainnet beacon node. Rollup node fetch blobs of [EIP-4844: Shard Blob Transactions](https://eips.ethereum.org/EIPS/eip-4844). This transaction type is by rollup's sequencer to reduce transaction costs when posting transactions to mainnet chain.

### Step 3: Generate the secret authentication secret

Generate a secret authentication token which is used by geth and node to authenticate each other.

```
openssl rand -hex 32 | tr -d "\n" | tee jwt.txt
```

### Step 4: Start the geth and node containers

Finally, start the geth and node containers with the following command:-

```
docker compose up
```

The optimistic rollup nodes sync using [snap sync](https://docs.optimism.io/builders/node-operators/management/snap-sync), which takes couple of hours depending on your network bandwidth and peers available for the rollup that you are syncing.

## Keeping track

The sync consists of three stages. First, the beacon headers are downloaded, then chain blocks, and finally chain state is downloaded. During the sync process you will see the following logs.

Initially, you will get the following logs:

```
setup-rollup-geth-1  | INFO [04-24|11:45:14.098] Looking for peers                        peercount=0 tried=111 static=0
```

Once, you are connected to some peers you will get following logs (notice the difference towards end of the log) :

```
setup-rollup-geth-1  | INFO [04-24|11:46:44.530] Looking for peers                        peercount=1 tried=106 static=0
```

After, you are connected to at least one peer, the sync process starts, and you will see the following log messages syncing beacon headers:

```
setup-rollup-geth-1  | INFO [04-24|11:51:45.841] Forkchoice requested sync to new head    number=119,180,364 hash=b65f5a..50e4de
setup-rollup-geth-1  | INFO [04-24|11:51:47.681] Forkchoice requested sync to new head    number=119,180,365 hash=be3cf3..f38a4d
setup-rollup-geth-1  | INFO [04-24|11:51:49.728] Forkchoice requested sync to new head    number=119,180,366 hash=bd6747..87e8ef
setup-rollup-geth-1  | INFO [04-24|11:51:51.734] Forkchoice requested sync to new head    number=119,180,367 hash=6c73be..c084f2
setup-rollup-geth-1  | INFO [04-24|11:49:04.521] Syncing beacon headers                   downloaded=37376 left=118,010,123 eta=1h8m3.072s
```

Log messages during chain download:

```
INFO [04-19|13:35:15.948] Syncing: chain download in progress      synced=3.51% chain=219.92MiB headers=501,760@120.75MiB bodies=469,010@90.74MiB receipts=469,010@8.44MiB eta=1h3m19.777s
```

Log messages during state download:-

```
INFO [04-19|13:35:22.871] Syncing: state download in progress      synced=5.70% state=2.51GiB   accounts=3,857,895@950.66MiB slots=7,098,356@1.46GiB    codes=21063@128.88MiB eta=39m22.074s
```

When the rollup node is fully synced, you will see following messages:

```
setup-rollup-geth-1 | INFO [05-24|11:49:04.521] Imported new potential chain segment     number=13,585,173 hash=a796a3..9d10a9 blocks=1          txs=65          mgas=7.603   elapsed=119.637ms    mgasps=63.552  snapdiffs=3.95MiB    triedirty=0.00B
INFO [04-24|11:54:55.297] Chain head was updated                   number=13,585,173 hash=a796a3..9d10a9 root=899b9c..84fda0 elapsed=2.472614ms
```


# Holesky Setup

Watchtower Client Setup for an EigenLayer node operator

{% hint style="info" %}
Testnet is available on Holesky
{% endhint %}

We have our pre-built binaries in form of container images hosted on docker hub. The following is a quick start guide on running the same for a node operator who is interested to setup a diligence watchtower on the Holesky chain

## Prerequisites

* Read the [Node Requirements](/archive/for-the-node-operators/node-requirements), if you haven't
* Access
  * Watchtower Node Operator should be a registered EigenLayer Node Operator.&#x20;
    * [Formal guide to register](< https://docs.eigenlayer.xyz/operator-guides/operator-introduction>)
  * Registered [EL Operator ](https://docs.eigenlayer.xyz/operator-guides/operator-introduction)needs to be whitelisted on Witness Chain Network. Whitelisting will be done with the help of the Witness Chain team through a whitelisting process.  If you are not sure how, [Steps for setup](#steps-for-setup) will guide you through it.&#x20;
* Software
  * Docker client, engine and container runtime installed (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* Hardware
  * Hardware requirements for the watchtower node can accessed [here](/archive/for-the-node-operators/node-requirements)
  * One of the node configurations as described in the [Node Types](#node-types) section below. Don't worry about how to configure right now ! As long as you have access to one of the configurations, we are good. We have you covered in the [Steps for setup](#steps-for-setup) section !

## Node Types

The node operator is expected to deploy the watchtower container alongside both L1 and L2 Archived nodes in the ideal scenario. But, we offer a few more configurations if you would like to re-use some of your existing infrastructure or setup. The configuration parameters for the L1 and L2 Archived nodes may belong to one of the following distinct categories.

| Configuration Type                                                                                                                        | L1 Node                           | L2 Node                                                            |
| ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------ |
| [Light](/archive/for-the-node-operators/watchtower-setup/holesky-setup/l2-archive-node-setup-guide#light-configuration-for-l2-node-setup) | Use a Hosted L1 Node RPC Provider | Use Witness Chain provided L2 Node snapshot  to bootstrap the node |
| Medium                                                                                                                                    | Use a Hosted L1 Node RPC Provider | Run an L2 Archive Node synced from a public checkpoint             |
| Full                                                                                                                                      | Run an L1 Full Node               | Run an L2 Archive Node synced from a public checkpoint             |

## Steps for setup

{% hint style="danger" %}
**Note:** Make sure there aren't any older version of watchtower images or containers. Use the below command to remove older/stale images

`docker rm <stale_container_id>`

`docker rmi -f <stale_image_name>`
{% endhint %}

### **Step 1: Register with EigenLayer as an Operator**&#x20;

{% hint style="info" %}
ONLY If you aren't yet an EigenLayer Operator yet, HOW TO can be found [here](https://docs.eigenlayer.xyz/operator-guides/operator-introduction)
{% endhint %}

### **Step 2: Get whitelisted on the Watchtower Network**.&#x20;

The Witness Chain watchtower network is a permissioned network currently.  Please connect with us on our [Discord](https://discord.gg/7hRNBDeY5e), if you want to become a watchtower operator

### Step 3: Register the operator on the Witness Chain Watchtower Network&#x20;

{% hint style="danger" %}
Before you start any activity on this network, ensure your operator and watchtower addresses are sufficiently funded to cover the gas costs. Use the [faucet](https://blue-orangutan-faucet.eu-north-2.gateway.fm) to fund it.
{% endhint %}

Register your EL operator address on the  WitnessChain **OperatorRegistry** contract. You can do so with the help of our CLI utility.&#x20;

#### Prerequisites

The CLI tool expects Ubuntu 22.04 (if you are running on linux) or if you are running on Ubuntu 20.04, ensure the glibc version is 2.34+&#x20;

```bash
# Run ldd --version to get the GLIBC version
ldd --version
```

#### Step 3.1 : Installation and Running the CLI

1. Installation:

   ```bash
   curl -sSfL https://witnesschain-com.github.io/install-operator-cli-testnet | bash
   ```
2. Running:

   <pre class="language-bash"><code class="lang-bash"><strong>export PATH="$PATH:~/.witnesschain/cli/"
   </strong>watchtower-operator --version

   Expected VERSION:
      v0.3.0
   </code></pre>

{% hint style="warning" %}
If you are facing the following error, please upgrade to Ubuntu 22.04

$ watchtower-operator --version

watchtower-operator: /lib/x86\_64-linux-gnu/libc.so.6: version \`GLIBC\_2.32' not found (required by watchtower-operator)

watchtower-operator: /lib/x86\_64-linux-gnu/libc.so.6: version \`GLIBC\_2.34' not found (required by watchtower-operator)
{% endhint %}

#### Step 3.2 : Registering the operator and the watchtowers

Once you've ensured the tool is installed correctly, run the below commands  to register the operator with our AVS and associate the watchtowers to the operator.

{% hint style="info" %}
**Note:** Refer to our [FAQs](/archive/proof-of-diligence-watchtower-protocol/faqs#how-is-a-watchtower-address-different-from-operator-address) to understand the difference between watchtower addresses and operator addresses
{% endhint %}

**Setup the configuration files for the OPERATOR CLI**

#### operator-config.json

```
# Set of watchtower private keys that will sign the Diligence Proofs. 
# This is used for registration purposes
# Registration will happen both on L1 and L2 simultaneously
```

```json
{
  "watchtower_private_keys": [
    "<raw-watchtower-private-key e.g. 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef>"
  ],
  "operator_private_key": "<raw-watchtower-private-key e.g. 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef>",
  "eth_rpc_url": "https://ethereum-holesky-rpc.publicnode.com", 
  "proof_submission_rpc_url": "https://blue-orangutan-rpc.eu-north-2.gateway.fm/"
}
```

{% hint style="danger" %}

<pre><code><strong>If you are operating a Smart Contract Wallet as the operator address
</strong><strong>then 
</strong><strong>
</strong><strong>set 
</strong><strong>
</strong><strong>"eth_rpc_url": ""
</strong><strong>
</strong><strong>This will register the Operator EoA only on L2.
</strong><strong>
</strong><strong>
</strong></code></pre>

{% endhint %}

```sh
# Registers the Operator to WitnessHub AVS on EigenLayer 
# This is required for the Operator to be listed on EigenLayer's 
# AVS-Operator Page (https://holesky.eigenlayer.xyz/avs/0xa987ec494b13b21a8a124f8ac03c9f530648c87d)

# Witnesschain Txns can be monitored via Blockscout at 
# https://witnesschain-testnet-blockscout.eu-north-2.gateway.fm

$ watchtower-operator registerOperatorToAVS --config-file <path to operator-config.json file>
```

```bash
# Registers the Operator's watchtower to WitnessHub AVS on Layer 1 
# and Witness Chain's L2 CDK Chain
# This registration is required for operators to be associated with the 
# points awarded as a result of diligently watching the chains.
# To understand what are watchtowers, please read the FAQs

$ watchtower-operator registerWatchtower --config-file <path to operator-config.json file>
```

{% hint style="danger" %}
Mask the operator private-keys or remove it from the config files once the registration process is complete. We don't require it for submitting the bounties in this file
{% endhint %}

### Step 4: Submitting the bounties

1. Post the registrations are complet&#x65;**, install the watchtower client**, by running the following command.

{% hint style="danger" %}
**Note:** Make sure there aren't any older version of watchtower images or containers. Use the below command to remove older/stale images

`docker rm <stale_container_id>`

`docker rmi -f <stale_image_name>`
{% endhint %}

```sh
curl https://witnesschain-com.github.io/install-watchtower-testnet | sh
```

The above command will guide you through the rest of installation process.


# L2 Archive Node Setup guide

Setting up the L2 Archive node for the Watchtower Node

{% hint style="info" %}
If you're an existing operator looking to migrate your your node from goerli to sepolia, skip to [migrating the L2](#migrating-the-l2)
{% endhint %}

## **Step 1: Install Software Dependencies**

Ensure that the following software dependencies are installed and meet the specified version requirements. Use the provided version check commands to confirm:

## **Step 2: Set-up L2 node via set-up script**

{% hint style="info" %}
As of ecotone upgrade, this script is outdated, we're working to update it to support the latest version. Meanwhile please continue with rest of the guide below, skipping Step 2.&#x20;
{% endhint %}

If you want to use a script that will automatically download the snapshot and set-up and start L2 node follow this step and skip steps 3-8. If you want to manually download the snapshot and set-up L2 node, then skip this step and go to step 3.

Download the scripts to set-up L2:

```bash
git clone https://github.com/kaleidoscope-blockchain/l2-set-up.git
```

The folder l2-set-up, will have script run that starts the set-up process. The run script takes two arguments,

1. chain-name - "base" or "optimism". Currently only base and optimism L2 are supported
2. L1\_RPC\_URL - Give the Sepolia RPC URL that you use to connect to L1

For example,

```bash
cd l2-set-up
./run optimism https://eth-sepolia.g.alchemy.com/v2/hhTXZSBtLsbNN-wXWpErThgYi9sNNKTP
```

The script will start a tmux shell with name "set-up-l2" that will download the snapshot. You can connect to tmux shell via the command,&#x20;

```bash
tmux a -t set-up-l2
```

Once the download of snapshot is done, tmux shell is terminated. After download of snapshot, geth and node clients are started in tmux shells with names, "optimism-geth" and "optimism-node" if optimism is selected, else if base is selected the tmux shell names will be "base-geth" and "base-node". To connect to a tmux shell, run the command

```bash
tmux a -t shell-name
```

If you follow step 2, then skip steps 3-8 and go to step 9

## **Step 3: Download the Snapshot**

To initiate the Watchtower environment, begin by downloading the latest available snapshot hosted by WitnessChain as a part of Light configuration for L2 node setup. Use the following commands:

For `op-sepolia:`

```shell
wget $(curl https://witnesschain-l2-snapshots.s3.amazonaws.com/op-latest)
```

For `base-sepolia:`

```shell
wget $(curl https://witnesschain-l2-snapshots.s3.amazonaws.com/base-latest)

```

{% hint style="info" %}
Consider using a download acceleration tool like [aria2c](https://aria2.github.io/) for faster downloads.&#x20;

An example for downloading base snapshot:

&#x20;`aria2c -s16 -x16` $(curl <https://witnesschain-l2-snapshots.s3.amazonaws.com/op-latest>)
{% endhint %}

{% hint style="success" %}

#### Medium **configuration for L2 node setup**

Alternatively operators can consider publicly posted snapshots to start their node syncs. These snapshots are not hosted by WitnessChain, hence their availability and recency is subject to L2 chains publishing it themselves.

`Note that WitnessChain highly encourages operators to utilize the snapshot hosted by us for a faster node setup and save days worth of time and compute on the same. That said, we're committed to keeping the watchtowers as trustless and neutral entities, hence the operators can feel free to choose the source of trust for their snapshot.`
{% endhint %}

## Step 4: Building the Optimism monorepo (Rollup Node/op-node) <a href="#id-3-building-the-optimism-monorepo-rollup-node-op-node" id="id-3-building-the-optimism-monorepo-rollup-node-op-node"></a>

### Clone the optimism monorepo and cd into it

```shell
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
```

### Checkout to the release branch (`op-node/v1.7.0` as of Mar 17, 2024)

```shell
git checkout op-node/v1.7.0
```

### Install nodejs dependencies and build nodejs packages

```shell
pnpm install 
pnpm build
```

### Build op-node

```shell
make op-node
```

## **Step 5: Build Execution Client (op-geth)**

Clone the op-geth repo, switch to the release branch (e.g., `v1.101308.0` as of Feb 24, 2024 ), and build op-geth:

```shell
git clone https://github.com/ethereum-optimism/op-geth.git
cd op-geth
git checkout v1.101308.0
make geth
```

## **Step 6: Create a JWT Secret**

Generate a 32-byte hex string as a shared secret for communication between op-node and op-geth:

```sh
openssl rand -hex 32 > jwt.txt
```

## Step 7: Configure and Start op-geth <a href="#id-6-configure-and-start-op-geth" id="id-6-configure-and-start-op-geth"></a>

{% hint style="info" %}
It's generally easier to start `op-geth` before starting `op-node`. You can still start `op-geth` without yet running `op-node`, but the `op-geth` instance will simply not receive any blocks until `op-node` is started.
{% endhint %}

Navigate to the op-geth directory, copy the JWT secret, and start op-geth:

```shell
# cd to the op-geth directory

cp /path/to/jwt.txt .

```

Unzip snapshot from step 1 in `/datadir/` in the same directory where you built `op-geth`. The final path for snapshot would look something like this

`/path/to/op-geth/datadir/geth`

<pre><code><strong># Unzip the snapshot from Step 1 in /datadir/ into 
</strong><strong># the same directory where you built op-geth
</strong># Example path for snapshot: /path/to/op-geth/datadir/geth
</code></pre>

{% hint style="danger" %}
if your path after snapshot unzipping and moving does not look as above, please either rename any directory required for the same or update the value of `--datadir` flag to point to path of the snapshot in the script below.
{% endhint %}

Create the following scripts in the same directory where you built `op-geth,`based on the L2 chain you would like to setup

* `run-geth-optimism.sh` for `op-sepolia` or&#x20;
* `run-geth-base.sh` for `base-sepolia`

{% hint style="info" %}
chmod +x for all the below mentioned scripts, if you run into permission issues
{% endhint %}

{% code title="run-geth-optimism.sh" %}

```shell
#!/usr/bin/bash

SEQUENCER_URL=https://sepolia-sequencer.optimism.io/


sudo ./build/bin/geth \
  --ws \
  --ws.port=8546 \
  --ws.addr=0.0.0.0 \
  --ws.origins="*" \
  --http \
  --http.port=8545 \
  --http.addr=0.0.0.0 \
  --http.vhosts="*" \
  --http.corsdomain="*" \
  --http.api=web3,debug,eth,net,engine \
  --authrpc.addr=localhost \
  --authrpc.jwtsecret=./jwt.txt \
  --authrpc.port=8551 \
  --authrpc.vhosts="*" \
  --datadir=./datadir \
  --verbosity=3 \
  --rollup.disabletxpoolgossip=true \
  --rollup.sequencerhttp=$SEQUENCER_URL \
  --nodiscover \
  --syncmode=full \
  --gcmode archive \
  --maxpeers=0 \
  --rollup.halt=major \
  --op-network=op-sepolia

```

{% endcode %}

{% code title="run-geth-base.sh" %}

```shell
#!/usr/bin/bash

SEQUENCER_URL=https://sepolia-sequencer.base.org

sudo ./build/bin/geth \
  --ws \
  --ws.port=8546 \
  --ws.addr=0.0.0.0 \
  --ws.origins="*" \
  --ws.api=debug,eth,net,engine \
  --http \
  --http.port=8545 \
  --http.addr=0.0.0.0 \
  --http.vhosts="*" \
  --http.corsdomain="*" \
  --http.api=web3,debug,eth,net,engine \
  --authrpc.addr=localhost \
  --authrpc.jwtsecret=./jwt.txt \
  --authrpc.vhosts="*" \
  --datadir=./datadir \
  --verbosity=3 \
  --rollup.disabletxpoolgossip=true \
  --rollup.sequencerhttp=$SEQUENCER_URL \
  --rollup.halt=major \
  --nodiscover \
  --syncmode=full \
  --gcmode=archive \
  --maxpeers=100 \
  --op-network=base-sepolia

```

{% endcode %}

{% hint style="info" %}
It is recommended you use tmux to run this in a detached background process
{% endhint %}

The following commands will start `op-geth` with our recommended configuration. The JSON-RPC API will become available on port 8545. Refer to the `op-geth` [configuration documentation](https://docs.optimism.io/builders/node-operators/management/configuration#op-geth) for more detailed information about available options.

for `op-sepolia`:

<pre class="language-shell"><code class="lang-shell"><strong>./run-geth-optimism.sh
</strong></code></pre>

for `base-sepolia`:

```shell
./run-geth-base.sh
```

## Step 8: Configure and Start op-node <a href="#id-6-configure-and-start-op-geth" id="id-6-configure-and-start-op-geth"></a>

Navigate to the op-node directory, copy the JWT secret, and start op-node:

```shell
# cd to the op-node directory 

# Both op-geth and op-node need to use the same JWT secret. 
# Copy the JWT secret you generated in a previous step into the op-node directory.

cp /path/to/jwt.txt .

```

Create the relevant script in the same directory where you built `op-node.` Based on your network `run-node-optimism.sh` for `op-sepolia` or `run-node-base.sh` for `base-sepolia`&#x20;

{% hint style="info" %}
chmod +x for all the below mentioned scripts, if you run into permission issues
{% endhint %}

{% code title="run-node-optimism.sh" %}

```shell
#!#!/usr/bin/bash

sudo bin/op-node --l1=<L1_RPC_URL> \
        --l1.beacon=<L1_BEACON_NODE_URL> \
        --l2=ws://localhost:8551 \
        --network=op-sepolia \
        --rollup.halt=major \
        --rollup.load-protocol-versions=true \
        --rpc.addr=0.0.0.0 \
        --rpc.port=9545 \
        --l2.jwt-secret=./jwt.txt

```

{% endcode %}

{% code title="run-node-base.sh" %}

```shell
#!/usr/bin/bash

sudo bin/op-node \
  --l1=<L1_RPC_URL> \
  --l1.beacon=<L1_BEACON_NODE_URL> \
  --l2=ws://localhost:8551 \
  --rpc.addr=0.0.0.0 \
  --rpc.port=9545 \
  --l2.jwt-secret=./jwt.txt \
  --network=base-sepolia \
  --rollup.halt=major \
  --rollup.load-protocol-versions=true

```

{% endcode %}

In the script, replace `<L1_RPC_URL>` with your sepolia (L1) RPC url and `<L1_BEACON_NODE_URL>` with url of corresponding beacon node.

{% hint style="info" %}
If you don't currently have access to a beacon node, you can setup any of the available software for it, including *Lighthouse*, *Prysm* etc. using their docs. One such guide can be found here to setup a P*rysm* node:\
<https://docs.prylabs.network/docs/install/install-with-script>
{% endhint %}

{% hint style="info" %}
Some L1 nodes, like Erigon, do not support the `eth_getProof` RPC method that the `op-node` uses to load L1 data for certain processing steps. If you are using an L1 node that does not support `eth_getProof`, you will need to include the `--l1.trustrpc` flag when starting `op-node`. You’ll have to modify the script with the same. Note that this flag will cause `op-node` to trust the L1 node to provide correct data as it will no longer be able to independently verify the data it receives.
{% endhint %}

{% hint style="info" %}
&#x20;It is recommended you use tmux to run this in a detached background process
{% endhint %}

Use the following command to start `op-node` with the recommended configuration. Refer to the `op-node` [configuration documentation](https://docs.optimism.io/builders/node-operators/management/configuration#op-node) for more detailed information about available options.

for `op-sepolia`:

```shell
./run-node-optimism.sh
```

for `base-sepolia`:

```shell
./run-node-base.sh
```

## 9. Post Setup

### Synchronization <a href="#synchronization" id="synchronization"></a>

Once you've started `op-geth` and `op-node` you should see the two begin to communicate with each other and synchronize the L2 chain. Initial synchronization can take several hours to complete.

During this time, you will initially observe `op-node` deriving blocks from Sepolia without sending these blocks to `op-geth`. This means that `op-node` is requesting blocks from Sepolia one-by-one and determining the corresponding L2 blocks that were published to Sepolia. You should see logs like the following from `op-node`:

```
INFO [06-26|13:31:20.389] Advancing bq origin                      origin=17171d..1bc69b:8300332 originBehind=false

```

Once the `op-node` has derived enough blocks from Sepolia, it will begin sending these blocks to `op-geth`. You should see logs like the following from `op-node`:

```
INFO [06-26|14:00:59.460] Sync progress                            reason="processed safe block derived from L1" l2_finalized=ef93e6..e0f367:4067805 l2_safe=7fe3f6..900127:4068014 l2_unsafe=7fe3f6..900127:4068014 l2_time=1,673,564,096 l1_derived=6079cd..be4231:8301091
INFO [06-26|14:00:59.460] Found next batch                         epoch=8e8a03..11a6de:8301087 batch_epoch=8301087 batch_timestamp=1,673,564,098
INFO [06-26|14:00:59.461] generated attributes in payload queue    txs=1  timestamp=1,673,564,098
INFO [06-26|14:00:59.463] inserted block                           hash=e80dc4..72a759 number=4,068,015 state_root=660ced..043025 timestamp=1,673,564,098 parent=7fe3f6..900127 prev_randao=78e43d..36f07a fee_recipient=0x4200000000000000000000000000000000000011 txs=1  update_safe=true
```

You should then also begin to see logs like the following from `op-geth`:

```
INFO [06-26|14:02:12.974] Imported new potential chain segment     number=4,068,194 hash=a334a0..609a83 blocks=1         txs=1         mgas=0.000  elapsed=1.482ms     mgasps=0.000   age=5mo2w20h dirty=2.31MiB
INFO [06-26|14:02:12.976] Chain head was updated                   number=4,068,194 hash=a334a0..609a83 root=e80f5e..dd06f9 elapsed="188.373µs" age=5mo2w20h
INFO [06-26|14:02:12.982] Starting work on payload                 id=0x5542117d680dbd4e
```

### Tracking the sync progress <a href="#tracking-the-sync-progress" id="tracking-the-sync-progress"></a>

You can run the following script, which will, over a minute, estimate the current sync speed and based on it the expected time for the sync to complete. The result is printed on the terminal, though remember that it is only an estimate.&#x20;

Create a file `run-estimate.sh` and paste the following code in it:

{% hint style="info" %}
chmod +x for all the below mentioned scripts, if you run into permission issues
{% endhint %}

{% code title="run-estimate.sh" %}

```shell
#!/usr/bin/bash

export ETH_RPC_URL=http://localhost:8545
CHAIN_ID=`cast chain-id`
echo Chain ID: $CHAIN_ID
echo Please wait

if [ $CHAIN_ID -eq 11155420 ]; then
  L2_URL=https://sepolia.optimism.io
fi

if [ $CHAIN_ID -eq 84532 ]; then
  L2_URL=https://sepolia.base.org
fi

T0=`cast block-number --rpc-url $ETH_RPC_URL` ; sleep 60 ; T1=`cast block-number --rpc-url $ETH_RPC_URL`
PER_MIN=`expr $T1 - $T0`
echo Blocks per minute: $PER_MIN


if [ $PER_MIN -eq 0 ]; then
    echo Not synching
    exit;
fi

# During that minute the head of the chain progressed by thirty blocks
PROGRESS_PER_MIN=`expr $PER_MIN - 30`
echo Progress per minute: $PROGRESS_PER_MIN


# How many more blocks do we need?
HEAD=`cast block-number --rpc-url $L2_URL`
BEHIND=`expr $HEAD - $T1`
MINUTES=`expr $BEHIND / $PROGRESS_PER_MIN`
HOURS=`expr $MINUTES / 60`
echo Hours until sync completed: $HOURS

if [ $HOURS -gt 24 ] ; then
   DAYS=`expr $HOURS / 24`
   echo Days until sync complete: $DAYS
fi
```

{% endcode %}

Then run `./run-estimate.sh` and wait for about 1 minute to see the sync speed and ETA.

```shell
./run-estimate.sh
```

## Official Reference Documentation <a href="#official-resources-and-other-documentation" id="official-resources-and-other-documentation"></a>

Optimism’s guide to building a node: [<img src="https://docs.optimism.io/img/icons/favicon.ico" alt="" data-size="line">Building a Node from Source | Optimism Docs](https://docs.optimism.io/builders/node-operators/tutorials/node-from-source)

Base’s guide to running a node : [<img src="https://docs.base.org/img/favicon.ico" alt="" data-size="line">Running a Base Node | Base](https://docs.base.org/guides/run-a-base-node/)

## Migrating the L2

1. Stop your current L2 node (both `op-node` and `op-geth`)
2. Delete the old state of the goerli network
   1. navigate to datadir
      1. `cd /home/.../op-geth/datadir/`
   2. remove the old state
      1. `sudo rm -rf ./geth`
3. Download the state snapshot for a sepolia L2 following [Setp 3](#step-3-download-the-snapshot)
4. Configure and Start L2 node following [Step 7](#id-6-configure-and-start-op-geth) and [Step 8](#id-6-configure-and-start-op-geth-1)
   1. ignore the jwt parts of it
   2. just extract the snapshot to the right path and run with the correct config&#x20;
5. Refer [Step 9](#id-9.-post-setup) for post setup help

## Upgrading the L2

upgrading your existing L2 to support Ecotone upgrade

1. Stop your current L2 node (both `op-node` and `op-geth`)
2. Upgrade op-geth
   1. <pre data-full-width="false"><code>cd /&#x3C;path>/&#x3C;to>/&#x3C;op-geth>/op-geth
      git pull
      git checkout v1.101308.0
      make geth
      </code></pre>
   2. `./run-geth-optimism.sh` or `./run-geth-base.sh`
3. Upgrade op-node
   1. ```
      cd /<path>/<to>/<optimism>/optimism
      git pull
      git checkout v1.7.0
      make op-node
      ```
   2. `cd op-node`
   3. add the following flag to your op-node run script\
      `--l1.beacon=<L1_BEACON_NODE_URL>`
      1. refer [#id-6-configure-and-start-op-geth-1](#id-6-configure-and-start-op-geth-1 "mention") for how the final script file should look like
   4. `./run-node-optimism.sh` or `./run-node-base.sh`

{% hint style="info" %}
If you don't currently have access to a beacon node, you can setup any of the available software for it, including *Lighthouse*, *Prysm* etc. using their docs. One such guide can be found here to setup a P*rysm* node:\
<https://docs.prylabs.network/docs/install/install-with-script>
{% endhint %}


# Migration from archive to full node

Describes the steps involved to migrate from archive to full node

Rollup node operators can reduce storage cost by changing the type of rollup node. An `archive` node stores the full state history for each block since genesis block. In contrast, a full node stores the state only for the recent 128 blocks. Therefore, moving from `archive` node to `full` node will significantly reduces the storage needs for running rollup nodes.

To migrate the rollup node from `archive` node to `full` node, take the following steps:

1. Stop the current rollup node. Change current working directory to the root of `setup-rollup` repository.

```
cd setup-rollup
docker compose down
```

2. In `geth.yml`, change `--gcmode` from `archive` to `full` node.

```
--gcmode=full
```

3. Resume the rollup node

```
docker compose up -d
```

Your rollup node should be up now. It will garbage collect the states older than 128 blocks.


# Monitoring

Monitor your container using Grafana and Prmoetheus

In this article, we will be setting up a dashboard to monitor the watchtower, which are deployed as a container image.

<figure><img src="/files/O7Wm43dKjTOcGwcszH7u" alt=""><figcaption></figcaption></figure>

**cAdvisor:**

cAdvisor, or Container Advisor, is an open-source tool tailored for monitoring and analyzing the performance of Docker containers and other containerization platforms. It operates as a live daemon, collecting and exporting information about running containers.

&#x20;

**Prometheus:**

Prometheus is a free and open-source tool that monitors your software systems, collecting essential data about applications and services. It provides alerts for prompt issue detection and resolution.

&#x20;

**Grafana:**

Data visualization tool that helps you to turn complex data into easy-to-understand charts and graphs. It connects to various data sources, like databases or monitoring systems, and allows you to create interactive dashboards.

### Pre-requisites <a href="#pre-requisites" id="pre-requisites"></a>

For the monitoring dashboard to function as expected, make sure you have the following setup

* Docker
* Docker compose plugin
* Watchtower running as a container (any release)

### Getting Started: <a href="#getting-started" id="getting-started"></a>

First, create a workspace to organise the configuration

```
mkdir container_monitoring 
cd container_monitoring
```

&#x20;

Now, download the configutation files, we have this hosted on github.

```
wget https://raw.githubusercontent.com/kaleidoscope-blockchain/config/main/monitoring_files.tar
```

Unarchive the files downloaded,

```
tar -xvf monitoring_files.tar
```

Finally starting up the dashboard, this is done with

```
docker compose up -d
```

Note: you can pass the option -d as exemplified in above command, to run in detached mode

&#x20;

The dashboard can be accessed at your url\
[http://localhost:3000](http://localhost:3000/)&#x20;

```
username: admin 
password: admin
```

&#x20;

And to stop the dashboard, in the same directory

```
docker compose down
```


# Research

This page holds all the papers published by our research team

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><p><strong>Proof of Diligence:</strong> <em>Cryptoeconomic security for rollups</em></p><p></p><p>Protocol that requires watchtowers to continuously provide a proof that they have verified L2 assertions and get rewarded for the same.</p></td><td></td><td></td><td><a href="https://arxiv.org/pdf/2402.07241.pdf">https://arxiv.org/pdf/2402.07241.pdf</a></td><td><a href="/files/y6Sx93jFM7ilwktraWy3">/files/y6Sx93jFM7ilwktraWy3</a></td></tr></tbody></table>


# Keys Management

How Witness Chain's Operator CLI manages Secret Keys

In the world of blockchain and decentralized applications, securing secret keys is paramount. Witness Chain’s Operator Command-Line Interface (CLI) supports several modes for handling secret keys, each catering to different security needs and use cases. This blog explores the available options and their current statuses, including plain text storage, gocryptfs encryption, web3signer utility, and Web3 Secret Storage Format.

{% hint style="info" %}
We support only ECDSA Keys right now. BN254 keys are not supported yet.
{% endhint %}

#### 1. No Encryption (Storing in Plain Text)

The simplest method of handling secret keys is storing them in plain text. While this approach is straightforward, it carries significant risks. Plain text storage means that anyone with access to the file can read the keys, posing a substantial security threat, especially in a production environment.

**Pros:**

* Simple and easy to implement.
* No additional dependencies or setup required.

**Cons:**

* Highly insecure as keys are exposed to anyone with access.

#### 2. Using gocryptfs

{% hint style="info" %}
Available in the [**development**](https://github.com/witnesschain-com/operator-cli/tree/development) branch. Details of How-to are available in the [README](https://github.com/witnesschain-com/operator-cli/blob/development/README.md#how-to-use-the-encrypted-keys) of the development branch
{% endhint %}

[gocryptfs](https://nuetzlich.net/gocryptfs/) is a user-space encrypted file system, which provides a secure layer for encrypting files. By using gocryptfs, secret keys are stored in an encrypted format, protecting them from unauthorized access. This method is currently being tested on the testnet.

**Pros:**

* Adds a layer of encryption, enhancing security.
* Transparent encryption and decryption process for the user.

**Cons:**

* Requires additional setup and configuration.
* Slight performance overhead due to encryption and decryption processes.

#### 3. Using web3signer Utility (Remote Signer)&#x20;

{% hint style="info" %}
Undergoing active testing
{% endhint %}

The web3signer utility allows for the use of a remote signer, offloading the signing operations to a secure remote service. This approach keeps the secret keys off the local system, reducing the risk of local key compromise. It is currently being tested on the testnet.

**Pros:**

* Keeps secret keys off the local system, enhancing security.
* Centralized management of keys, making it easier to enforce security policies.

**Cons:**

* Requires network connectivity to the remote signer.
* Potential latency due to network communication.

#### 4. Using Web3 Secret Storage Format (Keystore)

{% hint style="info" %}
Planned for July 2024
{% endhint %}

The [Web3 Secret Storage](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) Format, is a standardized way to encrypt and store Ethereum private keys. This method ensures that keys are encrypted with a passphrase, providing a secure means of key storage. This feature is currently in development.

**Pros:**

* Standardized and widely adopted format for key storage.
* Provides strong encryption for securing private keys.

**Cons:**

* Requires users to manage and remember their passphrase.

#### Conclusion

Witness Chain’s Operator CLI offers multiple modes for handling secret keys, each with its own advantages and trade-offs. From the simplicity of plain text storage to the advanced security of gocryptfs, web3signer, and Keystore, users can choose the method that best suits their needs. While plain text storage may be adequate for non-critical applications, leveraging encryption and remote signing solutions can significantly enhance security for production environments.

As the development of the Web3 Secret Storage Format integration progresses, Witness Chain continues to prioritize the security and integrity of secret keys, ensuring robust protection for its users’ assets and operations.


# Proof of Bandwidth

## What is Proof-of-Bandwidth?

Proof of Bandwidth is a decentralised proof of "speed test", which can be used to validate the claimed bandwidth of a "prover" device connected to Internet.

## Why is Proof-of-Bandwidth required for DePIN?

A trust-free Proof of Location is beneficial for decentralized physical infrastructure networks that offer services like storage, GPU compute, wireless connectivity, and energy distribution. These networks rely on decentralized nodes to provide essential services without centralized control, making trust and verification critical challenges. Here’s why Witness Chain's trust-free Proof of Bandwidth is helpful in these contexts:

* **Quality Assurance**: DePIN providers often rely on distributed nodes (e.g., routers, servers, hotspots) to deliver network services like internet connectivity, storage, or compute power. Proof-of-Bandwidth ensures that these nodes actually deliver the promised bandwidth and quality of service (QoS) to end-users. It prevents nodes from falsely claiming to provide services without actually doing so.
* **Incentive Alignment**: In decentralized networks, nodes are usually compensated based on their contributions to the network, such as bandwidth or storage provided. PoB is used to verify that nodes genuinely contribute the advertised bandwidth. This mechanism aligns incentives by ensuring that only those who deliver real value receive rewards.
* **Security and Fraud Prevention**: Without PoB, malicious nodes could fake bandwidth reports or exaggerate their contributions to earn rewards unfairly. Proof-of-Bandwidth provides a cryptographic method secured by EigenLayer's crypto economic security to verify the authenticity of bandwidth usage, preventing fraud and maintaining the network's integrity.
* **Network Performance Optimization**: By continuously verifying bandwidth availability and usage, the network can optimize routing and resource allocation, prioritizing nodes that provide the best performance. This improves the overall efficiency and reliability of the decentralized network.
* **Trust in a Trustless Environment**: Decentralized networks operate on the principle of trustless systems, where participants do not need to trust each other or a central authority. Proof-of-Bandwidth acts as a trustless verification mechanism, enabling trust through cryptographic proofs rather than relying on centralized validation.
* **Regulatory Compliance**: For certain DePIN use cases like decentralized ISPs, compliance with local regulations regarding network performance and service quality may be required. Proof-of-Bandwidth can provide a transparent, verifiable way to demonstrate compliance.
* **Data Integrity and Availability**: PoB ensures that data transmitted through the network is handled efficiently and securely, which is critical for applications involving sensitive or high-stakes data, such as IoT networks, edge computing, and other DePIN use cases.
* **Sybil Attack Mitigation**: By requiring a verifiable proof of actual bandwidth usage, PoB helps mitigate Sybil attacks where an adversary might spin up multiple fake nodes to control or manipulate the network.

Overall, Proof-of-Bandwidth is essential for ensuring that DePIN providers maintain a reliable, efficient, and secure network that functions as intended in a decentralized manner.


# Introduction

Introduction to Proof of Backhaul

{% hint style="warning" %}
Currently in Development
{% endhint %}

> Proof of Backhaul is a decentralised speed-test which can be used by a “payer” to determine the backhaul capacity of a “prover” with the help of a pool of “challengers“ who send the challenge traffic to the prover. We are aspiring to build a protocol which is *open* (anyone can be a challenger) and *trust-free* (we need not trust any party). While we get there, the current version works under limited, explicitly stated trust assumptions.

## <mark style="color:blue;">Parties Involved</mark>  <a href="#parties-involved" id="parties-involved"></a>

1. **Payer:** A party who pays for the challenge and starts one
2. **Prover:** The end-point whose backhaul capacity is being measured
3. **Blockchain full-node:** Decentralised ledger for recording all the challenge requests and outcomes
4. **Challengers:** A pool of servers which can send challenge traffic to the prover
5. **Challenge coordinator:** Centralised services for (i) communication between the parties; (ii) computing challenge meta data; and (iii) interacting with the ledger

## <mark style="color:blue;">Functional description</mark>  <a href="#functional-description-of-the-protocol" id="functional-description-of-the-protocol"></a>

A payer wants to verify that a prover has claimed bandwidth. It requests for a challenge to verify the bandwidth claimed by the prover.

### Challenge Request

1. A contract is initialised on-chain with public key of the payer, public key of the prover, and claimed capacity.
2. The payer commits to the contract escrow tokens for the cost of the challenge (depending on the claimed capacity).

### Challenge Setup

1. Challenge coordinator reads the request from the chain and selects appropriate number of challengers from the pool of live challengers.
2. The challenge coordinate informed the provers and the selected challengers about the challenge.

### Challenge Execution

<figure><img src="/files/o3RK2HaufYlSeCZZmqhk" alt=""><figcaption><p>Diagrammatic representation of a Challenge Execution</p></figcaption></figure>

1. Each challengers determines RTT to the prover.
2. The challenge coordinator (CC) informs each challenger about where to send the challenge data and at what time.
3. The challengers send the challenge data.
4. The prover computes a response hash of all the data received and sends it as response to each challenger.
5. Each challenger records the start time and the time at which the response hash is received.
6. The prover sends signed verification data to each challenger, who in turn uses it to compute the transmission time (tt) and number of packets (np) received for its traffic.
7. Challengers forward the response hash, verification data from prover (with prover signature), and its (tt, np) with its signature to the challenge coordinator.
8. The challenge coordinator computes the bandwidth and post all the data (list of challengers and their response) on-chain.
9. The PoB contract is terminated upon verification of the data and the tokens from the escrow are distributed to the challengers.

## <mark style="color:blue;">Trust and Threat Model (current)</mark> <a href="#trust-and-threat-model-for-pob-v1.0" id="trust-and-threat-model-for-pob-v1.0"></a>

### Challenge coordinator

1. Trust assumptions:
   1. The challenge coordinator is trusted to maintain a list of live challengers, handle load-balancing and scheduling for the challengers and randomly select a subset.
   2. The challenge coordinator is trusted to communicate between the parties and read/write to the ledger without censorship.

### **Prover**

1. Rational adversary: The prover can modify its response maliciously to try to inflate the measured capacity.
2. Trust assumptions: The IP stack of the prover is trusted (in many cases this is controlled by the ISP of the prover). So the prover cannot spoof its IP, modify ICMP messages, *etc.*.

### **Challengers**

1. Byzantine faults:
   1. Challengers can withhold the challenge traffic.
   2. Challengers can withhold the verification data in the final step.\
      (What’s the solution for this? Should we allow the challenge coordinator to fetch the missing verification data (local hash for a challenger) from the prover if needed?)
2. Rational adversary:
   1. Challengers can be bribed by the prover to inflate its measured capacity (rushing attack and information sharing attacks).
3. Trust assumptions:
   1. Challengers will not in a DoS attack on their own or using informing an outside party about the challenge timing and details.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Architecture</strong></td><td>Details the Architecture of PoB</td><td></td><td><a href="/pages/b4sVPafVF3LNkyIWUM5k">/pages/b4sVPafVF3LNkyIWUM5k</a></td></tr><tr><td><strong>Demo Videos</strong></td><td>Videos of the PoB product</td><td></td><td><a href="/pages/q4sowr9rj28PPypCKkDN">/pages/q4sowr9rj28PPypCKkDN</a></td></tr><tr><td><strong>API Documentation</strong></td><td>How to use the Challenge Coordinator API</td><td></td><td><a href="/pages/89RMwzv71K33HcNksTW4">/pages/89RMwzv71K33HcNksTW4</a></td></tr><tr><td><strong>Setup your own PoB Client</strong></td><td>How to setup your own PoB Client</td><td></td><td><a href="/pages/P5lJ7JxqQ1nXDzRATint">/pages/P5lJ7JxqQ1nXDzRATint</a></td></tr></tbody></table>


# Architecture

Details the PoB Ecosystem and the technical architecture

The architecture of the PoB ecosystem has 4 layers (from top to bottom):

* Application layer
* Physical Infrastructure Integration Layer
* Infrastructure, Security & Web3 layer
* Specification and Community layer (ecosystem)

<figure><img src="/files/dPXr2tQiUzrIkaEscr7a" alt=""><figcaption><p>PoB Ecosystem </p></figcaption></figure>

## Entities of PoB

<figure><img src="/files/WuIrYXrlQGnwk93R1Wfn" alt=""><figcaption><p>PoB Architecture</p></figcaption></figure>


# For the node operators

Introduction to node operators participating in Witness Chain Proof Challenges

Are you a network enthusiast with bandwidth to spare, or perhaps a tech-savvy individual with a keen interest in decentralized networks? If you've got unused bandwidth and are eager to put it to good use, you're a potential Node Operator who can leverage that extra bandwidth to participate in running decentralized speed test or location challenges

## Become a Node Operator for Bandwidth Proofs

**What You Need**

* **Unused Bandwidth:** Utilize your excess bandwidth to support network challenges.
* **Machine Specification**: A machine comparable to an AWS t2 micro (1 vcpu, 1GB RAM and 5GB harddisk), though we recommend 2 cores, 4 GB RAM and 10 GB of storage.
* **Network Equipment:** Ensure you have reliable networking hardware to participate in the challenge effectively.&#x20;
* **Interest in De-centralized Networks:** A passion for contributing to de-centralized networks and enhancing their security and efficiency.

**How It Works**

1. **Register Your Node:** Sign up as a Node Operator on Witness Chain's DePIN Coordination platform. Provide details about your bandwidth location. Specific details are specified in the next section.
2. **Participate in Challenges:** Your node will participate in network challenges on DePIN provers that require Proof of Bandwidth. These challenges help verify the integrity and reliability of the participating DePIN network's nodes.
3. **Earn Credits (in future):**&#x20;

**The next section details the technical steps in running a Proof of Bandwidth Challenger client**


# Running a PoB Challenger Client

Steps to run a PoB Challenger Client

The PoB Challenger Client Node is a DePIN Challenger node that participates in the PoB (Proof-of-Bandwidth) protocol and measures the bandwidth claims made by a DePIN Prover.

PoB Challenger Client Nodes can be run on community members’ laptops, desktops or even on cloud instances. As long as the node is running, there is a probabilistic algorithm (based on stake in the upcoming releases) that determines if the node will participate in a PoB challenge from the network.&#x20;

#### Prerequisites

Before you begin, ensure you have the following

* **Docker** (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* **Instance** comparable to a t2 micro (1 vcpu, 1GB RAM and 5GB harddisk), though we recommend 2 cores, 4 GB RAM and 10 GB of storage.
* Your operator key being whitelisted by Witness Chain.<br>

## Running your Challenger client

{% hint style="info" %}
Explorer: <https://blue-orangutan-blockscout.eu-north-2.gateway.fm/>&#x20;

Faucet: <https://blue-orangutan-faucet.eu-north-2.gateway.fm/>
{% endhint %}

### <mark style="color:red;">Key Points to consider before proceeding...</mark>

1. If you are an EigenLayer operator on our Witness Chain AVS, your Operator address would be already whitelisted.&#x20;
2. We have 2 sets of keys - Operator Key and Challenger Key.&#x20;
   1. **Operator Key** is the EigenLayer Operator Key that you have been using with our Witness Chain AVS. Continue to use that here too. This key is used for registering the Challenger Key(s).
   2. **Challenger Key** - This is the signing key for the PoB Challenger Client. Create a new Key for the same. **Don't reuse the Operator Key for the Challenger Key**. It has to be a ECDSA Key.&#x20;
3. **Both the Operator and the Challenger Key should be funded**. Please use the following faucet to fund it: <https://blue-orangutan-faucet.eu-north-2.gateway.fm/>
4. **Ports to be opened if using public IP:**&#x20;

```
Incoming ports to be opened (TCP & UDP ):

11112
22223
33334
44445
55556

Outgoing ports: Allow all
```

### 1. Setting up the challenger keys and the config file

{% hint style="success" %}
Use ECDSA Keypairs
{% endhint %}

1. Create a ECDSA private key using Metamask or other utilities that will be used as Challenger Key.&#x20;
2. Store the challenger's private key in the file (Make sure you keep track of the file name and its location, as it would be refered later)

```bash
echo "YOUR_CHALLENGER_PRIVATE_KEY" > my_challenger_private.key
```

4. Prepare a configuration file `my_challenger_config.json` with the following entries

```
{

"// 1" : "----- Please change the values that has TODO -----",

	"claims" : {
		"uplink_bandwidth"	: 100.0,					"// 2" : "Required - uplink_bandwidth is in Mbps",
		"downlink_bandwidth"	: 100.0,					"// 3" : "Required - downlink_bandwidth is in Mbps"
	},

	"walletPublicKey"	: {						"// 4" : "Required - The wallet addresses where your rewards go",
		"ethereum"	: "0x630391b032F444cB40B3603b579064817f312353",	"// 5" : "TODO: Please change this to your wallet address"
	},


"// 6" : "Set below two values to true - ONLY if you have public IP, but due to some issue with ISP the code is unable to detect it",

	"havePublicIPv4Address"	: false,
	"havePublicIPv6Address"	: false,

"// 7" : "CAFEFUL : Set below two values to true - ONLY if you want to force to have private IP",

	"havePrivateIPv4Address": false,
	"havePrivateIPv6Address": false,

"// 8" : "Save the login, session, and challenge related data in a .sqlite file",

	"saveResultsInDatabase" : false,

"// 9" : "Send challenge results to a contract",

	"submitResultsToContract" : true,

"// 10" : "RPC URL of the contract Where the challenger submits results",

	"rpcUrl": "https://blue-orangutan-rpc.eu-north-2.gateway.fm"
}
```

\
**Explanation:**

* The field `claims.uplink_bandwidth` and `claims.downlink_bandwidth`  (a.k.a. upload speeds and download speeds) are the  max limit of bandwidth supported by the challenger during challenges.
* `havePublicIPv4Address` (and `havePublicIPv6Address`) set them to **true** if you have a public IPv4 (or IPv6)&#x20;
* `havePrivateIPv4Address` (and `havePrivateIPv6Address`) set them to **true** if you want to force the use of private IP
* `saveResultsInDatabase` saves the login, session, and challenge related data in a .sqlite file within the container

5. Once you have the `config.json` ready, the challenger client can be started with

```sh
docker run -d \
  --network=host \
  --name pob-challenger \
  -v ./my_challenger_config.json:/app/dart/bin/pob/config/challenger.json \
  -v ./my_challenger_private.key:/root/.config/ethereum/private.key \
  witnesschain/pob-challenger
```

\
you can verify that the challenger is running by looking at the container status

```sh
docker ps 
```

**Explanation**:

1. `docker run -d`: Runs the container in detached mode (in the background).
   * ```
     --network=host
     Uses the host's network stack.
     ```
   * ```
     --name pob-challenger
     Names the container as 'pob-challenger'.
     ```
   * ```
     -v ./my_challenger_config.json:/app/dart/bin/pob/config/challenger.json 
     Mounts your local config file into the container at the specified path.
     ```
   * ```
     -v ./my_challenger_private.key:/root/.config/ethereum/private.key
     Mounts your local private key file folder into the container at the specified path.

     ```
   * ```
     witnesschain/pob-challenger: The name of the Docker image to run.
     ```

{% hint style="danger" %}
You will observe the following errors in the docker container&#x20;

"registration is required on DCL contract. Please register your challenger publicKey:"

Don't worry, this is normal. Once you [COMPLETE STEP 2](#id-2.-registering-the-challenger-key), these logs should disappear
{% endhint %}

### 2. Registering the Challenger Key

{% hint style="warning" %}
If you are already whitelisted on Witness Chain's AVS on EigenLayer's testnet, then you can move forward with registration, else write to us on our [Discord channel](https://discord.gg/Y9Eu2U5s) or Telegram to get whitelisted.&#x20;
{% endhint %}

You can register the challenger key easily with the help of our registration cli, to do so

1. Download our **dcl-operator-cli** <br>

   ```sh
   curl -sSfL https://witnesschain-com.github.io/install-dcl-cli | bash
   ```

   \
   Follow the steps as directed in the output of the script to add the CLI to the shell profile to be able to use the CLI from anywhere.<br>
2. Prepare the [config (challenger registration config)](https://github.com/witnesschain-com/dcl-operator-cli/blob/main/dcl-operator/operator-challenger-config.json.template),&#x20;
   1. The above command also downloads a template which you can refer to.
   2. <mark style="color:red;">Make sure you set the</mark> <mark style="color:red;"></mark><mark style="color:red;">`challenger_private_keys`</mark> <mark style="color:red;"></mark><mark style="color:red;">attribute in the json file with the key, that you provided in</mark> <mark style="color:red;"></mark><mark style="color:red;">`private.key`</mark>
3. Run the following command for registration

   ```sh
   dcl-operator-cli registerChallenger --config-file <path-to-challenger-registration-config.json>
   ```

{% hint style="warning" %}
Ensure the operator address is correctly set in the challenger's `config.json,`as the contributions are attributed to the operator!
{% endhint %}

## Post Setup

Once the setting up and registration is successful, you can check the logs from the challenger client ready for challenges. (`docker logs pob-challenger`). Congratulations, you are now a part of our DePIN family!<br>

{% hint style="info" %}
We publish images (x86 & arm64) with the tag `latest` and by the git tag, the `latest` will always point to the new and up to date image. In order to pull the latest image, make sure you don't have an older release of latest to avoid using cached images.&#x20;

You can remove the older images by

```bash
docker rmi witnesschain/pob-challenger
```

{% endhint %}

## Troubleshooting

As the only prerequisite is docker, make sure you are running atleast version 23.0.0 or above for the commands mentioned in the doc to work. \
\
The days might be rainy or snowy, but we've got umbrellas and sweaters!\
Join our [Discord](https://discord.gg/Y9Eu2U5s) or Telegram—we're happy to help. :D


# Running a PoB Prover Client

Steps to run a PoB Prover Client

#### Prerequisites

Before you begin, ensure you have the following

* **Docker** (version 23.0.0 or above, refer: <https://docs.docker.com/desktop/install/linux-install/>)
* **Instance** comparable to a t2 micro (1 vcpu, 1GB RAM and 1GB harddisk),

## Running your Prover client

There are two aspects in setting up the prover,

* Registration: so the challengers are aware of it
* Running: so the challengers can engage with it

Here's how to get the provers successfully running&#x20;

### <mark style="color:red;">Key Points to consider before proceeding...</mark>

1. **Ports to be opened if using public IP:**&#x20;

```
Incoming ports to be opened (TCP & UDP ):

11112
22223
33334
44445
55556

Outgoing ports: Allow all
```

## Setting up the Prover

You can provide the private key (for example, generated from Metamask) which will be used by the Witnesschain's PoB  Prover client.

{% hint style="success" %}
Use ECDSA Keypairs
{% endhint %}

1. Store the prover's private key in the file (Make sure you keep track of the file name and its location, as it would be refered later) <br>

   ```sh
   echo "YOUR_PROVER_PRIVATE_KEY" > my_prover_private.key
   ```

2. Prepare a configuration file `my_prover_config.json` with the following entries<br>

   ```
   {

   "// 1" : "----- Please change the values that has TODO -----",

   	"claims" : {

   		"uplink_bandwidth"	: 11.0,						"// 2" : "Required, uplink_bandwidth is in Mbps",
   		"downlink_bandwidth"	: 11.0,						"// 3" : "Required, downlink_bandwidth is in Mbps"
   	},

   	"projectName"		: "My-DEPIN-Project-Name",			"// 4" : "Required",

   	"walletPublicKey"	: {						"// 5" : "Required - The wallet addresses where your rewards go",
   		"ethereum"	: "0x630391b032F444cB40B3603b579064817f312353",	"// 6" : "TODO: Please change this to your wallet address"
   	},

   	"maxChallengesPerDay"	: 100,						"// 7" : "The MAX no. of challenges you wish to participate per day",

   "// 8" : "CAREFUL :Set below two values to true - ONLY if you have public IP, but due to some issue with ISP the code is unable to detect it",

   	"havePublicIPv4Address"	: false,
   	"havePublicIPv6Address"	: false,

   "// 9" : "CAREFUL : Set below two values to true - ONLY if you want to force to have private IP",

   	"havePrivateIPv4Address": false,
   	"havePrivateIPv6Address": false,

   "// 10" : "Save the login, session, and challenge related data in a .sqlite file",

   	"saveResultsInDatabase" : false
   }
   ```

   \
   **Note:**

   1. The field `claims.uplink_bandwidth` and `claims.downlink_bandwidth`  are the claimed bandwidth supported by the prover (a.k.a. upload speeds and download speeds).
   2. [`projectName`](#user-content-fn-1)[^1] is the DePIN project with which the Prover is registered to provide infra services.
   3. `walletPublicKey.ethereum` is the wallet address which is used&#x20;
   4. `havePublicIPv4Address` (and `havePublicIPv6Address`) set them to **true** if you have a public IPv4 (or IPv6)&#x20;
   5. `havePrivateIPv4Address` (and `havePrivateIPv6Address`) set them to **true** if you want to force the use of private IP
   6. `saveResultsInDatabase` saves the login, session, and challenge related data in a .sqlite file within the container<br>

3. Once you have the `config.json` ready, the prover client can be started with<br>

   ```sh
   docker run -d \
     --network=host \
     --name pob-prover \
     -v ./my_prover_config.json:/app/dart/bin/pob/config/prover.json \
     -v ./my_prover_private.key:/root/.config/ethereum/private.key \
     witnesschain/pob-prover
   ```

   \
   If you are running a docker engine version < 21.0, you would want to give the full path to `my_prover_config.json` and  `my_prover_private.key`

**Explanation**:

* `docker run -d`: Runs the container in detached mode (in the background).
* ```
  --network=host
  Uses the host's network stack.
  ```
* ```
  --name pob-prover
  Names the container as 'pob-prover'.
  ```
* ```
  -v ./my_prover_config.json:/app/dart/bin/pob/config/prover.json 
  Mounts your local config file into the container at the specified path.
  ```
* ```
  -v ./my_prover_private.key:/root/.config/ethereum/provate.key 
  Mounts your local private key file folder into the container at the specified path.
  ```
* ```
  witnesschain/pob-prover: The name of the Docker image to run.
  ```

\
You can verify that the prover is running by looking at the container status<br>

```sh
docker ps 
```

{% hint style="info" %}
Now the prover is running successfully but not yet registered, you may find the logs stating the same. \
The prover will function as intended as soon as registration is done.
{% endhint %}

## Registering the Prover

You can register the prover easily with the help of our registration cli, to do so

1. Download our **dcl-operator-cli**<br>

   ```sh
   curl -sSfL https://witnesschain-com.github.io/install-dcl-cli | bash
   ```

   \
   Follow the steps as directed in the output of the script to add the CLI to the shell profile to be able to use the CLI from anywhere.<br>
2. Prepare the [config (prover registration config)](https://github.com/witnesschain-com/dcl-operator-cli/blob/main/dcl-operator/operator-prover-config.json.template), (The above command also downloads a template which you can refer to) make sure you set the `prover_private_keys` to the one you provided to the client (Setting the prover Step 2)
3. Run the following command for registration<br>

   ```
   dcl-operator-cli registerProver --config-file <path-to-prover-registration-config.json>
   ```

## Post Setup

Once the setting up and registration is successful, you can check the logs from the prover client ready for challenges. (`docker logs pob-prover`). Congratulations, you are now a part of our DePIN family!<br>

{% hint style="info" %}
We publish images (x86 & arm64) with the tag `latest` and by the git tag, the `latest` will always point to the new and up to date image. In order to pull the latest image, make sure you don't have an older release of latest to avoid using cached images.&#x20;

You can remove the older images by

```bash
docker rmi witnesschain/pob-prover
```

{% endhint %}

## Troubleshooting

As the only prerequisite is docker, make sure you are running atleast version 23.0.0 or above for the commands mentioned in the doc to work. \
\
The days might be rainy or snowy, but we've got umbrellas and sweaters!\
Join our [Discord](https://discord.gg/Y9Eu2U5s) or Telegram—we're happy to help. :D

[^1]:


# Demos

## Proof-of-Bandwidth (PoB) Demo&#x20;

{% embed url="<https://www.loom.com/share/9df74400b3f24a29993c3725dcf9534b?sid=cc7af443-cc8a-4988-834d-9cd4a3d7c6d0>" %}
Proof-of-Bandwidth demo
{% endembed %}


# Research

This page holds all the papers published by our research team on PoB

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Proof of Backhaul:</strong> <em>Decentralized speedtests for backhaul</em></td><td><p><a href="https://www.witnesschain.com/assets/Proof_of_Backhaul-f417e09d.pdf"><img src="https://www.witnesschain.com/assets/speed-test-866c8aaa.png" alt=""></a></p><p>Decentralised speed-test which can be used by a “payer” to determine the backhaul capacity of a “prover” with the help of a pool of “challengers” who send the challenge traffic to the prover.</p></td><td></td><td><a href="https://arxiv.org/pdf/2210.11546.pdf">https://arxiv.org/pdf/2210.11546.pdf</a></td><td><a href="/files/G7aZd1LNeDQQr6JaDNqO">/files/G7aZd1LNeDQQr6JaDNqO</a></td></tr></tbody></table>


# Watchtower Protocol (Architecture v1)


# How it works

Protocol description for the working of the watchtower

<details>

<summary>Table of Contents</summary>

[Introduction](#introduction)

[Participating Entities](#participants-and-entities)

[Protocol Description](#protocol-description)

[Process Flow](#process-flow)

[Proof of Diligence](#proof-of-diligence)

</details>

## Introduction

Security for optimistic rollups (ORs) is derived from dispute resolution at L1 for suspicious transactions. The first line of defense is offered by parties who first identify suspicious transactions.&#x20;

Currently deployed ORs rely on relatively centralized (and trusted) entities who offer this line of defense; e.g., Arbitrum’s state assertion can only be disputed by a set of 12 whitelisted defensive validator nodes.

The surge in demand for app-specific rollups and platforms to support them (e.g., Base and Eigenlayer) results from increasing value and diversity of transactions relying on L2s. In turn, there is a need for decentralized and trust-free validators who diligently raise the alarm when they detect a suspicious transaction.&#x20;

**Witness Chain Watchtowers provide the first line of defense for rollups, which is:**

1. **Trustfree**: provides [Proof of Diligence](#proof-of-diligence) of watchtowers with *Ethereum trust* (through EigenLayer)
2. **Decentralized**: provides a Proof of Location for verifying the geolocation of watchtowers and enforcing desired *physical decentralization*.
3. **Programmable**: provides *SLA smart contracts* to scale the number/stake of watchtowers and their decentralization properties with the value of vulnerable transactions.

## Participants and Entities

The diagram summarizes the different entities participating in the Watchtower network

####

<figure><img src="/files/sEZtfUDMMDrVj5tyeHHF" alt=""><figcaption><p>Participants in the watchtower network</p></figcaption></figure>

#### Stakers

EigenLayer (re)stakers who stake/delegate on/to EigenLayer operators providing Ethereum's crypto-economic trust to the watchtower network.

#### Operators

EigenLayer operators are a pool of staked node operators who run the watchtower client

#### Users/Dapps

Set of Dapps built on top of the Watchtower networking utilizing it's real-time transaction tracer APIs

#### Watchtower (watchtower client)

Watchtower is the independent validation entity which cross verifies the L2 state assertions made on the L1. These watchtowers are incentivized to watch and validate the assertions made by the L2 proposers (even in a happy path scenario (avoiding the lazy-validator problem)) with the help of [Proof of Diligence](#proof-of-diligence)&#x20;

#### L2 nodes

L2 network nodes run by the operators alongside the watchtower client. This is the node which computes the state for L2 and is used by the watchtower client to validate the state assertions on the Layer 1. These are L2 archive nodes.

#### Smart contracts

A set of smart contracts deployed by WitnessChain on Layer 1 (Ethereum). Following are the descriptions of the smart contracts:

* `OperatorRegistry`: Register a EigenLayer node operator as a watchtower in the network
* `DiligenceProofManager`: Submit diligence proofs and get rewarded for watching the network
* `AlertManager`: Raise alerts in case of identifying an invalid state assertion by an L2

## Protocol Description

A Watchtower client register's using the `OperatorRegistry` smart contract

On startup, the watchtower subscribes to an L1 node for the real-time events of the L2 assertions (`OutputProposed` event of L2OO in case of optimism). At the same time, the watchtower is also maintaining the L2 state and executing the transaction from the sequencer commitments on L1. &#x20;

When the watchtower notices a state assertion being made on L1, it quickly validates it against the corresponding L2 state for that block number using the state it has been independently advancing.

Two cases might exist:

* State assertion matches the computed L2 state
* State assertion does not match the computer L2 state
  * In this case, the watchtower raises an alarm via the `AlertManager` contract to let the participants be aware of the misbehavior of the &#x20;

Regardless of the case, the watchtower then prepares the [signed proof of diligence](#proof-of-diligence-pod-construction-and-bounty-mining-go-client) and submits it to the `DiligenceProofManager` smart contract to claim their rewards. We call this the bounty mining process, and this ensures the diligent nature of a watchtower even in case of a happy path.

## Process Flow

The diagram summarizes the sequences of steps involved in the Diligence Proof Submission process&#x20;

<figure><img src="/files/ElnESQuI1EDC6t6P2nti" alt=""><figcaption><p>Process Flow</p></figcaption></figure>

{% hint style="info" %}
**Pre-requisites - Witness Chain watchtowers are expected to be registered as EL operators**
{% endhint %}

1. The WitnessChain Admin initiates a Bounty for each L2 Chain designated for monitoring.
2. Bounty Miners, running Witness Chain Watchtower (WT) clients, register on the Watchtower network and monitor State Assertions on the L2OO smart contract.
3. Upon receiving an event from the L2OO contract, WT clients commence validation by tracing (re-executing) transactions on the L2 Archive Node for the proposed block. (*A Witness Chain Watchtower node runs both the watcher software and L2 Archive node*)
4. Upon successful reconciliation between L2OO and L2 Node Tracer Results, the watchtower posts a Proof of Diligence (PoD) on the Witness Chain smart contract, called the *DiligenceProofManager*.
5. If reconciliation fails, the Watchtower submits an Alert to an *AlertManager* Contract in addition to providing the PoD.
6. The cycle concludes with a call to a *rewardBounty* Smart Contract function, triggered periodically to compensate the watchtower client with a diligence bounty.

## Proof of Diligence

{% hint style="info" %}
The scope of currently described PoD construction is limited to op-stack based L2 chains only
{% endhint %}

### Proof of Diligence (PoD) Construction and Bounty Mining (Go Client) <a href="#proof-of-diligence-pod-construction-and-bounty-mining-go-client" id="proof-of-diligence-pod-construction-and-bounty-mining-go-client"></a>

The actual proof of diligence, which is verified on the `DiligenceProofManager` smart contract and is used for rewards is defined as below:

* <mark style="color:blue;">Signed PoD = Sign(Hash(prefix || PSH)), where</mark>
  * <mark style="color:blue;">\`prefix\` is added just for compliance with ethereum chain</mark>&#x20;

    ```
    prefix := []byte("\x19Ethereum Signed Message:\n32")
    ```
  * <mark style="color:blue;">PSH =</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">Hash</mark>*<mark style="color:blue;">(</mark>*<mark style="color:blue;">latestBlockNumber</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">||</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">midPointPenultimateBlock</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">|| midPoint || version\_number)</mark>
    * *<mark style="color:blue;">Hash</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= Keccak256Hash</mark>
    * *<mark style="color:blue;">latestBlockNumber</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= the L2 block number for which the PoD is signed/computed. This is the same L2 blocknumber that is currently proposed on L2OO</mark>
    * *<mark style="color:blue;">midPointPenultimateBlock</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= the state root after the midpoint transaction of the block before the latestBlockNumber (ref.</mark> [<mark style="color:blue;">intermediate state roots</mark>](#the-intermediate-state-roots)<mark style="color:blue;">)</mark>
    * *<mark style="color:blue;">midPoint</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= the state root after the midpoint transaction of the latestBlockNumber’th block</mark>
    * *<mark style="color:blue;">version\_number</mark>* <mark style="color:blue;"></mark><mark style="color:blue;">= proof of diligence version number, which is incremented every time there is a protocol update. It is currently set to \`0\`</mark>

The SignedPoD is submitted to the `DiligenceProofManager` smart contract.&#x20;

## Notes

#### The intermediate state roots

* As specified in PoD construction, the protocol requires the watchtower to commit to some of the intermediate states of execution across 2 proposed output roots.&#x20;
* To achieve this we make use of (op-geth in op-stack) geth’s tracer APIs
* In particular, we use the \`debug.intermediateRoots\` by providing it the block hashes
* This works via a re-execution of transaction from an earlier state in the history which is available to the node, which in our case would be the state at latestBlockNumber-2’th block and latestBlockNumber-1’th
* As it re-executes the transaction in those specific blocks, it stores the state roots after each transaction and outputs them in a list for our watchtower client to further process and get the midpoint root alone
* This ensures, that node had the head state after each L2 block and that it actually executed the


# Watchtower Roadmap

Planned work

| Testnet Phases     | Deliverables                                                                                                                                       |                               |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| Phase 1 (Dec 2023) | <ul><li>Watchtower client</li><li>Integration with EigenLayer contracts</li><li>Onboarding Node Operators</li><li>OP Stack Chains</li></ul>        | Completed (on goerli testnet) |
| Phase 2 (Q1 2024)  | <ul><li>Increase OR Rollup Coverage ( Arbitrum  Other OP Stack chains )</li><li>Onboarding Node Operators</li><li>Transaction Tracer API</li></ul> | In Progress                   |
| Phase 3 (Q2 2024)  | <ul><li>Onboarding Applications (Bridges, Messaging Apps)</li></ul><p></p>                                                                         | Planned                       |


# Watchtower Architecture

Software Architecture - client, APIs and contracts

<figure><img src="/files/aE5F0P7a5YVStjPLpcsc" alt=""><figcaption><p>Architecture</p></figcaption></figure>

WitnessChain Watchtowers' software stack comprise of &#x20;

1. Node Client (written in Go)&#x20;
2. On-chain Smart Contracts on Ethereum
3. Transaction Tracer APIs (for dApps to consume and configure the status)

## Node client

At a high level, the process of validation in a watchtower node client has 4 stages

1. Output State Root Extraction from L1
2. Output State Root Extraction (Tracer execution) from L2 Node
3. Comparison
4. Smart Contract integration

<figure><img src="/files/2jXZLGH5e23VSXTvweMt" alt=""><figcaption><p>Sequence of Steps</p></figcaption></figure>

## List of Smart Contracts

<figure><img src="/files/TrUYl52QkeVvOvI9ovd1" alt=""><figcaption></figcaption></figure>

### 1. OperatorRegistry

This is Registry-type contract for keeping track of operators. It is used for registering and deregistering new operators. Only registered and delegated EigenLayer operators are allowed into the watchtower network

### *<mark style="color:green;">addToOperatorWhitelist()</mark>*

| **Called By** | Contract Owner |
| ------------- | -------------- |
| **Returns**   | None           |
| **Emits**     | None           |

* Adds the list of operators to the whitelist mapping

### *<mark style="color:green;">removeFromOperatorWhitelist</mark>*<mark style="color:green;">()</mark>

| **Called By** | Contract Owner |
| ------------- | -------------- |
| **Returns**   | None           |
| **Emits**     | None           |

* Removes the list of operators from the whitelist mapping

### *<mark style="color:green;">register</mark>*

| **Called By** | Node operator |
| ------------- | ------------- |
| **Returns**   | None          |
| **Emits**     | None          |

* Registers the operator as a watchtower

### *<mark style="color:green;">deRegister</mark>*

| **Called By** | Node operator |
| ------------- | ------------- |
| **Returns**   | None          |
| **Emits**     | None          |

* Deregisters the operator as a watchtower

### 2. DiligenceProofManager

The DiligenceProofManager Contract contains functionality for miners (aka Watchtowers) to submit (mine) their Proofs of Diligence for a Bounty Period (which is the period between 2 L2 Txn Batch submissions). After the next L2 output state root is posted on L1, the bounty is rewarded to the miner. Bounties are given for every L2 Output (L2 Block).&#x20;

### *<mark style="color:green;">setBounty(chainID, amount)</mark>*

| **Called By** | Owner of the Contract      |
| ------------- | -------------------------- |
| **Returns**   | None                       |
| **Emits**     | NewBountyInitialized event |

* The owner of the Contract sets the Bounty Amount.
* Consider bounties are just reward points for now. Lets say 1 point for every L2 block mined successfully by a WatchTower.

### *<mark style="color:green;">submitProof (chainID, l2\_blockNumber, proofOfDiligence, signedProofOfDiligence)</mark>*

| **Called By** | WatchTower (EigenLayer Node Operator) |
| ------------- | ------------------------------------- |
| **Returns**   | None                                  |
| **Emits**     | NewBountyClaimed event                |

* Watchtower(s) submits/mine a L2 block by submitting the Hash(intermediate state root) and signing the Hash.
* Validations on Contract take care if the right sender is sending this transaction and if the blockNumber is a valid block to be mined.
* If the validations go through, the watchtower’s claim is accepted into the bounty, waiting for the rewardBounty to be called at the end of the mining cycle (which is roughly 60 mins on Optimism)

### *<mark style="color:green;">rewardBounty (chainID, l2\_blockNumber)</mark>*

| **Called By** | Owner                      |
| ------------- | -------------------------- |
| **Returns**   | Winner(WatchTower address) |
| **Emits**     | NewBountyRewarded event    |

* A reward (credit point) is awarded for every L2Block successfully mined by a miner using the **MIN logic**
* When the L2 Block Number moves on to the next one on L2OracleOutput, the bounty is rewarded to the miner (based on minimum submitted hash logic)

### 3. AlertManager

This contract is used for keeping track of alerts raised by watchtowers

### *<mark style="color:green;">raiseAlert()</mark>*

| **Called By** | Node Operator              |
| ------------- | -------------------------- |
| **Returns**   | Winner(WatchTower address) |
| **Emits**     | NewBountyRewarded event    |

* Raise an alert when there is a mismatch in output root between what is exeucte on L2 Node and asserted on L1 Contract

### *<mark style="color:green;">getAlerts(chainID,L2BlockNumber)</mark>*

| **Called By** | Node Operator              |
| ------------- | -------------------------- |
| **Returns**   | Winner(WatchTower address) |
| **Emits**     | NewBountyRewarded event    |

* Get all alerts raised so far a particular chainID and L2BlockNumber

## Assumptions

* Currently, watch Period is defined by the L2 Block Number that is obtained from the L2OutputOracle contract. So, a watchtower has to mine for that L2 block number. Any block numbers in the future or in the past will be rejected in the Contract.
* One WatchTower can mine only 1 bounty during that period for that L2 block number.
* With the current configuration, every WatchTower client runs an archived L2 node.


# Chains supported

Chains that are supported by watchtower clients

| L1 Chain                               | L2 Chains                                    |
| -------------------------------------- | -------------------------------------------- |
| Ethereum (Goerli) : Chain ID 5         | Optimism (OP Stack) op-goerli : Chain ID 420 |
|                                        | Base ( OP Stack ): Chain ID 8453             |
| Ethereum (sepolia) : Chain ID 11155111 | Optimism-Sepolia : Chain ID 11155420         |
|                                        | Base-Sepolia : Chain ID 84532                |


