diff --git a/docker/dogecoin/Dockerfile b/docker/dogecoin/Dockerfile new file mode 100644 index 0000000000..80f4ffbb2a --- /dev/null +++ b/docker/dogecoin/Dockerfile @@ -0,0 +1,44 @@ +# Stage 1: Download and prepare Dogecoin Core binary +FROM debian:12-slim AS builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +ENV DOGECOIN_VERSION=1.14.8 + +RUN wget https://github.com/dogecoin/dogecoin/releases/download/v${DOGECOIN_VERSION}/dogecoin-${DOGECOIN_VERSION}-x86_64-linux-gnu.tar.gz \ + && tar -xzvf dogecoin-${DOGECOIN_VERSION}-x86_64-linux-gnu.tar.gz \ + && mv dogecoin-${DOGECOIN_VERSION}/bin/dogecoind /usr/local/bin/ \ + && mv dogecoin-${DOGECOIN_VERSION}/bin/dogecoin-cli /usr/local/bin/ + +# Stage 2: Optimized production runner +FROM debian:12-slim AS runner + +# Create dedicated non-root user and group +RUN groupadd -r dogecoin && useradd -r -m -g dogecoin dogecoin + +# Copy binaries from builder +COPY --from=builder /usr/local/bin/dogecoind /usr/local/bin/dogecoind +COPY --from=builder /usr/local/bin/dogecoin-cli /usr/local/bin/dogecoin-cli + +# Run as non-root user +USER dogecoin +WORKDIR /home/dogecoin + +# Set up configuration and data directories +RUN mkdir -p /home/dogecoin/.dogecoin + +# Expose standard P2P and RPC ports +EXPOSE 22555 22556 44555 44556 + +# Copy configuration template +COPY dogecoin.conf.template /home/dogecoin/.dogecoin/dogecoin.conf + +# Health check utilizing dogecoin-cli +HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ + CMD dogecoin-cli getblockchaininfo || exit 1 + +ENTRYPOINT ["dogecoind"] +CMD ["-printtoconsole"] diff --git a/docker/dogecoin/dogecoin.conf.template b/docker/dogecoin/dogecoin.conf.template new file mode 100644 index 0000000000..7c64c14394 --- /dev/null +++ b/docker/dogecoin/dogecoin.conf.template @@ -0,0 +1,24 @@ +# dogecoin.conf template for staging & production node deployments +server=1 +txindex=1 +# For security in staging & production, do not hardcode rpcuser and rpcpassword here. +# Instead, pass them as command-line arguments when starting the container, e.g.: +# dogecoind -rpcuser=YOUR_RPC_USER -rpcpassword=YOUR_RPC_PASSWORD +# Or configure rpcauth=user:salt$hashedpassword. +# Local CLI commands will automatically authenticate using cookie auth. + +# Allow connections from Docker networks and localhost +rpcallowip=127.0.0.1 +rpcallowip=10.0.0.0/8 +rpcallowip=172.16.0.0/12 +rpcallowip=192.168.0.0/16 + +# Mainnet Settings (standard Dogecoin ports) +[main] +rpcport=22555 +port=22556 + +# Testnet Settings (standard Dogecoin ports) +[test] +rpcport=44555 +port=44556 diff --git a/docs/compliance-multichain.md b/docs/compliance-multichain.md new file mode 100644 index 0000000000..78e2680409 --- /dev/null +++ b/docs/compliance-multichain.md @@ -0,0 +1,44 @@ +# Multi-Chain Deployment Compliance & Regulatory Review + +This document provides a regulatory compliance analysis and technical integration guidelines for deploying Dogecoin nodes and Fantom integrations. + +--- + +## 1. Regulatory Context & Asset Classification + +Following the conclusion of the **SEC v. Ripple Labs** lawsuit, the classification of digital assets has become clearer: +- **Programmatic Sales & Secondary Markets:** The court ruled that programmatic sales of digital assets to retail buyers on secondary exchanges do not constitute investment contracts (securities). +- **Institutional Sales:** Direct, structured sales to institutional investors were ruled as securities offerings under the Howey Test. +- **Dogecoin (DOGE) Status:** Dogecoin is a pure proof-of-work cryptocurrency operating solely as a medium of exchange. It behaves identically to Bitcoin and is classified as a commodity rather than a security. Deploying and managing a local Dogecoin node carries low regulatory risk. +- **Fantom (FTM) Status:** Fantom uses a Proof-of-Stake (Lachesis consensus) mechanism. Due to its staking mechanics, developers must monitor potential SEC updates regarding PoS protocols. Staging interactions via private RPC endpoints (rather than public validator hosting) minimizes direct regulatory exposure. + +--- + +## 2. Dogecoin Node Configuration & Health Checks + +We run Dogecoin Core (`dogecoind`) in Docker using the configuration at `docker/dogecoin/Dockerfile`. + +### Node CLI Commands +To check block sync status: +```bash +dogecoin-cli getblockchaininfo +``` + +To list peer connections: +```bash +dogecoin-cli getpeerinfo +``` + +--- + +## 3. Fantom RPC Integration Example + +For interacting with Fantom Opera Mainnet, use `examples/fantom_integration.py` which wraps basic JSON-RPC operations. + +```python +from examples.fantom_integration import FantomClient + +client = FantomClient() +block = client.get_block_number() +print(f"Current block: {block}") +``` diff --git a/examples/fantom_integration.py b/examples/fantom_integration.py new file mode 100644 index 0000000000..ec58f5a8b8 --- /dev/null +++ b/examples/fantom_integration.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +""" +Fantom Blockchain RPC Client and Utilities Example. +Exposes tools for smart contract interactions, gas estimation, log parsing, +and transaction preparation. +""" + +import httpx +import sys + +# Official Fantom Opera Mainnet and Testnet public RPC endpoints +FANTOM_MAINNET_RPC = "https://rpc.ankr.com/fantom/" +FANTOM_TESTNET_RPC = "https://rpc.ankr.com/fantom_testnet/" + +class FantomClient: + def __init__(self, rpc_url: str = FANTOM_MAINNET_RPC): + self.rpc_url = rpc_url + self.headers = {"Content-Type": "application/json"} + + def _call_rpc(self, method: str, params: list) -> dict: + payload = { + "jsonrpc": "2.0", + "method": method, + "params": params, + "id": 1 + } + with httpx.Client() as client: + response = client.post(self.rpc_url, json=payload, headers=self.headers) + response.raise_for_status() + res_json = response.json() + if "error" in res_json: + raise Exception(f"RPC Error: {res_json['error']}") + return res_json.get("result") + + def get_block_number(self) -> int: + """Returns the current block height on the Fantom network.""" + result = self._call_rpc("eth_blockNumber", []) + return int(result, 16) + + def get_balance(self, address: str) -> float: + """Returns the FTM balance of an address (in Wei converted to FTM).""" + result = self._call_rpc("eth_getBalance", [address, "latest"]) + wei = int(result, 16) + return wei / 1e18 + + def estimate_gas(self, from_addr: str, to_addr: str, data: str = "0x") -> int: + """Estimates gas needed for a transaction.""" + transaction = { + "from": from_addr, + "to": to_addr, + "data": data + } + result = self._call_rpc("eth_estimateGas", [transaction]) + return int(result, 16) + + def get_gas_price(self) -> int: + """Returns the current gas price in Wei.""" + result = self._call_rpc("eth_gasPrice", []) + return int(result, 16) + + def call_contract(self, contract_address: str, data: str) -> str: + """Calls a constant/pure contract function (read-only eth_call).""" + transaction = { + "to": contract_address, + "data": data + } + return self._call_rpc("eth_call", [transaction, "latest"]) + +def main(): + print("Initializing Fantom RPC Client...") + # Initialize pointing to the mainnet (or testnet if desired) + client = FantomClient(FANTOM_MAINNET_RPC) + + try: + # 1. Fetch current block number + block = client.get_block_number() + print(f"Current Fantom Block: {block}") + + # 2. Get balance of a test address + test_address = "0x6B175474E89094C44Da98b954EedeAC495271d0F" # Sample address + balance = client.get_balance(test_address) + print(f"FTM Balance of {test_address}: {balance:.4f} FTM") + + # 3. Get current gas price + gas_price = client.get_gas_price() + print(f"Current Gas Price: {gas_price / 1e9:.2f} Gwei") + + except Exception as e: + print(f"Error communicating with Fantom RPC: {e}", file=sys.stderr) + +if __name__ == '__main__': + main()