add genesis command to CLI
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 3s
Documentation Validation / validate-docs (push) Successful in 5s
Documentation Validation / validate-policies-strict (push) Successful in 3s
Integration Tests / test-service-integration (push) Successful in 1m10s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 2s
P2P Network Verification / p2p-verification (push) Successful in 1s
Python Tests / test-python (push) Failing after 10s
Security Scanning / security-scan (push) Successful in 1m10s
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 3s
Documentation Validation / validate-docs (push) Successful in 5s
Documentation Validation / validate-policies-strict (push) Successful in 3s
Integration Tests / test-service-integration (push) Successful in 1m10s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 2s
P2P Network Verification / p2p-verification (push) Successful in 1s
Python Tests / test-python (push) Failing after 10s
Security Scanning / security-scan (push) Successful in 1m10s
Imported genesis command module and registered it with the CLI command group.
This commit is contained in:
111
apps/blockchain-node/scripts/create_genesis_wallet.py
Normal file
111
apps/blockchain-node/scripts/create_genesis_wallet.py
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Create a new genesis wallet with secure random private key"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from datetime import datetime
|
||||||
|
import secrets
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||||
|
|
||||||
|
def derive_address_from_public_key(pub_key_bytes: bytes) -> str:
|
||||||
|
"""Derive AITBC address from public key"""
|
||||||
|
# Hash the public key
|
||||||
|
digest = hashlib.sha256(pub_key_bytes).digest()
|
||||||
|
# Take first 20 bytes and encode as hex
|
||||||
|
address_hash = digest[:20].hex()
|
||||||
|
# Return with aitbc1 prefix
|
||||||
|
return f"aitbc1{address_hash}"
|
||||||
|
|
||||||
|
def create_genesis_wallet(password: str = None):
|
||||||
|
"""Create genesis wallet with secure random private key"""
|
||||||
|
# Generate cryptographically secure random private key (32 bytes)
|
||||||
|
private_key_bytes = secrets.token_bytes(32)
|
||||||
|
|
||||||
|
# Generate Ed25519 key pair from private key
|
||||||
|
private_key = ed25519.Ed25519PrivateKey.from_private_bytes(private_key_bytes)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
|
||||||
|
# Get public key bytes
|
||||||
|
pub_key_bytes = public_key.public_bytes(
|
||||||
|
encoding=serialization.Encoding.Raw,
|
||||||
|
format=serialization.PublicFormat.Raw
|
||||||
|
)
|
||||||
|
|
||||||
|
# Derive address
|
||||||
|
address = derive_address_from_public_key(pub_key_bytes)
|
||||||
|
|
||||||
|
# Convert to ait1 prefix format (matching genesis.json format)
|
||||||
|
ait_address = address.replace("aitbc1", "ait1")
|
||||||
|
|
||||||
|
# Generate password if not provided
|
||||||
|
if not password:
|
||||||
|
password = secrets.token_urlsafe(32)
|
||||||
|
|
||||||
|
# Encrypt private key with password
|
||||||
|
salt = secrets.token_bytes(16)
|
||||||
|
kdf = PBKDF2HMAC(
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
length=32,
|
||||||
|
salt=salt,
|
||||||
|
iterations=100000,
|
||||||
|
)
|
||||||
|
key = kdf.derive(password.encode())
|
||||||
|
|
||||||
|
# Encrypt using AES-GCM
|
||||||
|
aesgcm = AESGCM(key)
|
||||||
|
nonce = secrets.token_bytes(12)
|
||||||
|
ciphertext = aesgcm.encrypt(nonce, private_key_bytes, None)
|
||||||
|
|
||||||
|
# Create wallet data
|
||||||
|
wallet_data = {
|
||||||
|
"address": ait_address,
|
||||||
|
"public_key": pub_key_bytes.hex(),
|
||||||
|
"crypto": {
|
||||||
|
"kdf": "pbkdf2",
|
||||||
|
"kdfparams": {
|
||||||
|
"salt": salt.hex(),
|
||||||
|
"c": 100000,
|
||||||
|
"dklen": 32,
|
||||||
|
"prf": "hmac-sha256"
|
||||||
|
},
|
||||||
|
"cipher": "aes-256-gcm",
|
||||||
|
"cipherparams": {
|
||||||
|
"nonce": nonce.hex()
|
||||||
|
},
|
||||||
|
"ciphertext": ciphertext.hex()
|
||||||
|
},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write to keystore
|
||||||
|
keystore_path = Path("/var/lib/aitbc/keystore/genesis.json")
|
||||||
|
with open(keystore_path, 'w') as f:
|
||||||
|
json.dump(wallet_data, f, indent=2)
|
||||||
|
|
||||||
|
# Save password to secure file
|
||||||
|
password_path = Path("/var/lib/aitbc/keystore/.genesis_password")
|
||||||
|
with open(password_path, 'w') as f:
|
||||||
|
f.write(password)
|
||||||
|
os.chmod(password_path, 0o600)
|
||||||
|
|
||||||
|
print(f"✅ Created new genesis wallet with secure random private key")
|
||||||
|
print(f"Address: {ait_address}")
|
||||||
|
print(f"Public key: {pub_key_bytes.hex()}")
|
||||||
|
print(f"Private key: {private_key_bytes.hex()}")
|
||||||
|
print(f"Password: {password}")
|
||||||
|
print(f"Wallet saved to: {keystore_path}")
|
||||||
|
print(f"Password saved to: {password_path}")
|
||||||
|
print(f"⚠️ IMPORTANT: Store the password securely!")
|
||||||
|
|
||||||
|
return ait_address, pub_key_bytes.hex(), private_key_bytes.hex(), password
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
create_genesis_wallet()
|
||||||
350
apps/blockchain-node/scripts/unified_genesis.py
Normal file
350
apps/blockchain-node/scripts/unified_genesis.py
Normal file
@@ -0,0 +1,350 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Unified Genesis Block and Wallet Generation
|
||||||
|
|
||||||
|
This script combines genesis block creation with genesis wallet generation,
|
||||||
|
connected to the wallet service for proper key management and storage.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 unified_genesis.py --chain-id ait-mainnet --create-wallet
|
||||||
|
python3 unified_genesis.py --chain-id ait-mainnet --force
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import argparse
|
||||||
|
import secrets
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Dict, List, Any, Optional
|
||||||
|
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||||
|
|
||||||
|
# Add project paths
|
||||||
|
sys.path.insert(0, '/opt/aitbc')
|
||||||
|
sys.path.insert(0, '/opt/aitbc/apps/blockchain-node/src')
|
||||||
|
|
||||||
|
try:
|
||||||
|
from aitbc_chain.config import BlockchainConfig
|
||||||
|
from aitbc_chain.models import Block, Account
|
||||||
|
from sqlmodel import Session, create_engine, select
|
||||||
|
except ImportError:
|
||||||
|
print("Warning: Could not import blockchain modules, running in wallet-only mode")
|
||||||
|
|
||||||
|
|
||||||
|
def derive_address_from_public_key(pub_key_bytes: bytes) -> str:
|
||||||
|
"""Derive AITBC address from public key"""
|
||||||
|
digest = hashlib.sha256(pub_key_bytes).digest()
|
||||||
|
address_hash = digest[:20].hex()
|
||||||
|
return f"aitbc1{address_hash}"
|
||||||
|
|
||||||
|
|
||||||
|
def compute_block_hash(height: int, parent_hash: str, timestamp: datetime, chain_id: str = "ait-mainnet") -> str:
|
||||||
|
"""Compute block hash"""
|
||||||
|
hash_input = f"{height}{parent_hash}{timestamp.isoformat()}{chain_id}".encode()
|
||||||
|
return hashlib.sha256(hash_input).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def create_genesis_wallet(password: str = None, chain_id: str = "ait-mainnet") -> Dict[str, str]:
|
||||||
|
"""Create genesis wallet with secure random private key"""
|
||||||
|
# Generate cryptographically secure random private key
|
||||||
|
private_key_bytes = secrets.token_bytes(32)
|
||||||
|
|
||||||
|
# Generate Ed25519 key pair
|
||||||
|
private_key = ed25519.Ed25519PrivateKey.from_private_bytes(private_key_bytes)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
|
||||||
|
# Get public key bytes
|
||||||
|
pub_key_bytes = public_key.public_bytes(
|
||||||
|
encoding=serialization.Encoding.Raw,
|
||||||
|
format=serialization.PublicFormat.Raw
|
||||||
|
)
|
||||||
|
|
||||||
|
# Derive address
|
||||||
|
address = derive_address_from_public_key(pub_key_bytes)
|
||||||
|
ait_address = address.replace("aitbc1", "ait1")
|
||||||
|
|
||||||
|
# Generate password if not provided
|
||||||
|
if not password:
|
||||||
|
password = secrets.token_urlsafe(32)
|
||||||
|
|
||||||
|
# Encrypt private key with password
|
||||||
|
salt = secrets.token_bytes(16)
|
||||||
|
kdf = PBKDF2HMAC(
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
length=32,
|
||||||
|
salt=salt,
|
||||||
|
iterations=100000,
|
||||||
|
)
|
||||||
|
key = kdf.derive(password.encode())
|
||||||
|
|
||||||
|
# Encrypt using AES-GCM
|
||||||
|
aesgcm = AESGCM(key)
|
||||||
|
nonce = secrets.token_bytes(12)
|
||||||
|
ciphertext = aesgcm.encrypt(nonce, private_key_bytes, None)
|
||||||
|
|
||||||
|
# Create wallet data
|
||||||
|
wallet_data = {
|
||||||
|
"address": ait_address,
|
||||||
|
"public_key": pub_key_bytes.hex(),
|
||||||
|
"crypto": {
|
||||||
|
"kdf": "pbkdf2",
|
||||||
|
"kdfparams": {
|
||||||
|
"salt": salt.hex(),
|
||||||
|
"c": 100000,
|
||||||
|
"dklen": 32,
|
||||||
|
"prf": "hmac-sha256"
|
||||||
|
},
|
||||||
|
"cipher": "aes-256-gcm",
|
||||||
|
"cipherparams": {
|
||||||
|
"nonce": nonce.hex()
|
||||||
|
},
|
||||||
|
"ciphertext": ciphertext.hex()
|
||||||
|
},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"wallet": wallet_data,
|
||||||
|
"address": ait_address,
|
||||||
|
"public_key": pub_key_bytes.hex(),
|
||||||
|
"private_key": private_key_bytes.hex(),
|
||||||
|
"password": password
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def create_genesis_block(chain_id: str, proposer: str, timestamp: datetime = None) -> Dict[str, Any]:
|
||||||
|
"""Create genesis block"""
|
||||||
|
if not timestamp:
|
||||||
|
timestamp = datetime.fromisoformat("2025-01-01 00:00:00")
|
||||||
|
|
||||||
|
parent_hash = "0x00"
|
||||||
|
genesis_hash = compute_block_hash(0, parent_hash, timestamp, chain_id)
|
||||||
|
|
||||||
|
genesis_block = {
|
||||||
|
"height": 0,
|
||||||
|
"hash": genesis_hash,
|
||||||
|
"parent_hash": parent_hash,
|
||||||
|
"proposer": proposer,
|
||||||
|
"timestamp": timestamp.isoformat(),
|
||||||
|
"tx_count": 0,
|
||||||
|
"chain_id": chain_id,
|
||||||
|
"state_root": "0x00",
|
||||||
|
"metadata": {
|
||||||
|
"chain_type": "mainnet",
|
||||||
|
"purpose": "production",
|
||||||
|
"consensus_algorithm": "poa"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return genesis_block
|
||||||
|
|
||||||
|
|
||||||
|
def create_genesis_allocations(genesis_address: str, additional_allocations: List[Dict] = None) -> List[Dict]:
|
||||||
|
"""Create genesis allocations including genesis wallet"""
|
||||||
|
allocations = [
|
||||||
|
{
|
||||||
|
"address": genesis_address,
|
||||||
|
"balance": 1000000000, # 1 billion AIT for genesis
|
||||||
|
"nonce": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
if additional_allocations:
|
||||||
|
allocations.extend(additional_allocations)
|
||||||
|
|
||||||
|
return allocations
|
||||||
|
|
||||||
|
|
||||||
|
def save_genesis_wallet(wallet_data: Dict, keystore_path: Path, password: str):
|
||||||
|
"""Save genesis wallet to keystore"""
|
||||||
|
keystore_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
with open(keystore_path, 'w') as f:
|
||||||
|
json.dump(wallet_data, f, indent=2)
|
||||||
|
|
||||||
|
# Save password securely
|
||||||
|
password_path = keystore_path.parent / ".genesis_password"
|
||||||
|
with open(password_path, 'w') as f:
|
||||||
|
f.write(password)
|
||||||
|
os.chmod(password_path, 0o600)
|
||||||
|
|
||||||
|
|
||||||
|
def save_genesis_json(genesis_block: Dict, allocations: List[Dict], genesis_path: Path):
|
||||||
|
"""Save genesis configuration to JSON file"""
|
||||||
|
genesis_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
genesis_config = {
|
||||||
|
"chain_id": genesis_block["chain_id"],
|
||||||
|
"block": genesis_block,
|
||||||
|
"allocations": allocations
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(genesis_path, 'w') as f:
|
||||||
|
json.dump(genesis_config, f, indent=2)
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_genesis_database(genesis_block: Dict, allocations: List[Dict], db_path: Path):
|
||||||
|
"""Initialize blockchain database with genesis data"""
|
||||||
|
try:
|
||||||
|
engine = create_engine(f"sqlite:///{db_path}")
|
||||||
|
with Session(engine) as session:
|
||||||
|
# Check if genesis already exists
|
||||||
|
existing = session.exec(
|
||||||
|
select(Block).where(Block.height == 0).where(Block.chain_id == genesis_block["chain_id"])
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if existing:
|
||||||
|
print(f"⚠️ Genesis block already exists in database")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Create genesis block
|
||||||
|
block = Block(
|
||||||
|
height=genesis_block["height"],
|
||||||
|
hash=genesis_block["hash"],
|
||||||
|
parent_hash=genesis_block["parent_hash"],
|
||||||
|
proposer=genesis_block["proposer"],
|
||||||
|
timestamp=datetime.fromisoformat(genesis_block["timestamp"]),
|
||||||
|
tx_count=genesis_block["tx_count"],
|
||||||
|
chain_id=genesis_block["chain_id"],
|
||||||
|
state_root=genesis_block["state_root"]
|
||||||
|
)
|
||||||
|
session.add(block)
|
||||||
|
|
||||||
|
# Create genesis accounts
|
||||||
|
for alloc in allocations:
|
||||||
|
account = Account(
|
||||||
|
chain_id=genesis_block["chain_id"],
|
||||||
|
address=alloc["address"],
|
||||||
|
balance=alloc["balance"],
|
||||||
|
nonce=alloc["nonce"],
|
||||||
|
updated_at=datetime.utcnow()
|
||||||
|
)
|
||||||
|
session.add(account)
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
print(f"✅ Genesis initialized in database: {db_path}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error initializing genesis in database: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def register_wallet_with_service(wallet_address: str, wallet_data: Dict, service_url: str = "http://localhost:8003"):
|
||||||
|
"""Register genesis wallet with wallet daemon service"""
|
||||||
|
try:
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
response = httpx.post(
|
||||||
|
f"{service_url}/api/wallet",
|
||||||
|
json={
|
||||||
|
"address": wallet_address,
|
||||||
|
"public_key": wallet_data["public_key"],
|
||||||
|
"wallet_type": "genesis"
|
||||||
|
},
|
||||||
|
timeout=5
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code in (200, 201):
|
||||||
|
print(f"✅ Genesis wallet registered with wallet service")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Failed to register with wallet service: {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Could not connect to wallet service: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Unified Genesis Block and Wallet Generation")
|
||||||
|
parser.add_argument("--chain-id", default="ait-mainnet", help="Chain ID")
|
||||||
|
parser.add_argument("--proposer", help="Proposer address (defaults to genesis wallet)")
|
||||||
|
parser.add_argument("--create-wallet", action="store_true", help="Create genesis wallet")
|
||||||
|
parser.add_argument("--password", help="Wallet password (auto-generated if not provided)")
|
||||||
|
parser.add_argument("--db-path", default="/var/lib/aitbc/data/chain.db", help="Database path")
|
||||||
|
parser.add_argument("--keystore-path", default="/var/lib/aitbc/keystore/genesis.json", help="Keystore path")
|
||||||
|
parser.add_argument("--genesis-path", default="/var/lib/aitbc/data/ait-mainnet/genesis.json", help="Genesis config path")
|
||||||
|
parser.add_argument("--force", action="store_true", help="Force overwrite existing genesis")
|
||||||
|
parser.add_argument("--register-service", action="store_true", help="Register with wallet service")
|
||||||
|
parser.add_argument("--service-url", default="http://localhost:8003", help="Wallet service URL")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print(f"🌟 Unified Genesis Generation for {args.chain_id}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Create genesis wallet
|
||||||
|
if args.create_wallet:
|
||||||
|
print(f"\n📝 Creating Genesis Wallet...")
|
||||||
|
wallet_result = create_genesis_wallet(args.password, args.chain_id)
|
||||||
|
|
||||||
|
print(f"Address: {wallet_result['address']}")
|
||||||
|
print(f"Public key: {wallet_result['public_key']}")
|
||||||
|
print(f"Private key: {wallet_result['private_key']}")
|
||||||
|
print(f"Password: {wallet_result['password']}")
|
||||||
|
|
||||||
|
save_genesis_wallet(wallet_result['wallet'], Path(args.keystore_path), wallet_result['password'])
|
||||||
|
print(f"Wallet saved to: {args.keystore_path}")
|
||||||
|
|
||||||
|
proposer = args.proposer or wallet_result['address']
|
||||||
|
else:
|
||||||
|
proposer = args.proposer or "genesis"
|
||||||
|
wallet_result = None
|
||||||
|
|
||||||
|
# Create genesis block
|
||||||
|
print(f"\n📦 Creating Genesis Block...")
|
||||||
|
genesis_block = create_genesis_block(args.chain_id, proposer)
|
||||||
|
print(f"Height: {genesis_block['height']}")
|
||||||
|
print(f"Hash: {genesis_block['hash']}")
|
||||||
|
print(f"Proposer: {genesis_block['proposer']}")
|
||||||
|
|
||||||
|
# Create allocations
|
||||||
|
print(f"\n💰 Creating Genesis Allocations...")
|
||||||
|
if wallet_result:
|
||||||
|
allocations = create_genesis_allocations(wallet_result['address'])
|
||||||
|
else:
|
||||||
|
allocations = create_genesis_allocations(proposer)
|
||||||
|
|
||||||
|
print(f"Total allocations: {len(allocations)}")
|
||||||
|
for alloc in allocations[:3]: # Show first 3
|
||||||
|
print(f" - {alloc['address']}: {alloc['balance']} AIT")
|
||||||
|
|
||||||
|
# Save genesis configuration
|
||||||
|
print(f"\n💾 Saving Genesis Configuration...")
|
||||||
|
save_genesis_json(genesis_block, allocations, Path(args.genesis_path))
|
||||||
|
print(f"Genesis config saved to: {args.genesis_path}")
|
||||||
|
|
||||||
|
# Initialize database
|
||||||
|
print(f"\n🗄️ Initializing Database...")
|
||||||
|
if initialize_genesis_database(genesis_block, allocations, Path(args.db_path)):
|
||||||
|
print(f"Database initialized: {args.db_path}")
|
||||||
|
|
||||||
|
# Register with wallet service
|
||||||
|
if args.register_service and wallet_result:
|
||||||
|
print(f"\n🔗 Registering with Wallet Service...")
|
||||||
|
register_wallet_with_service(wallet_result['address'], wallet_result['wallet'], args.service_url)
|
||||||
|
|
||||||
|
print(f"\n✅ Unified Genesis Generation Complete!")
|
||||||
|
print(f"\n📋 Summary:")
|
||||||
|
print(f" Chain ID: {args.chain_id}")
|
||||||
|
print(f" Genesis Block: {genesis_block['hash']}")
|
||||||
|
if wallet_result:
|
||||||
|
print(f" Genesis Wallet: {wallet_result['address']}")
|
||||||
|
print(f" Wallet Password: {wallet_result['password']}")
|
||||||
|
print(f" ⚠️ IMPORTANT: Store the password securely!")
|
||||||
|
print(f" Database: {args.db_path}")
|
||||||
|
print(f" Config: {args.genesis_path}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
194
cli/aitbc_cli/commands/genesis.py
Normal file
194
cli/aitbc_cli/commands/genesis.py
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
"""Genesis block and wallet generation commands for AITBC CLI"""
|
||||||
|
|
||||||
|
import click
|
||||||
|
from typing import Optional
|
||||||
|
from ..utils import output, error, success
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
@click.group()
|
||||||
|
def genesis():
|
||||||
|
"""Genesis block and wallet generation commands"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@genesis.command()
|
||||||
|
@click.option("--chain-id", default="ait-mainnet", help="Chain ID for genesis")
|
||||||
|
@click.option("--create-wallet", is_flag=True, help="Create genesis wallet with secure random key")
|
||||||
|
@click.option("--password", help="Wallet password (auto-generated if not provided)")
|
||||||
|
@click.option("--proposer", help="Proposer address (defaults to genesis wallet)")
|
||||||
|
@click.option("--force", is_flag=True, help="Force overwrite existing genesis")
|
||||||
|
@click.option("--register-service", is_flag=True, help="Register genesis wallet with wallet service")
|
||||||
|
@click.option("--service-url", default="http://localhost:8003", help="Wallet service URL")
|
||||||
|
@click.pass_context
|
||||||
|
def init(ctx, chain_id: str, create_wallet: bool, password: Optional[str], proposer: Optional[str],
|
||||||
|
force: bool, register_service: bool, service_url: str):
|
||||||
|
"""Initialize genesis block and wallet for a blockchain"""
|
||||||
|
script_path = Path("/opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py")
|
||||||
|
|
||||||
|
if not script_path.exists():
|
||||||
|
error(f"Genesis generation script not found: {script_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Build command
|
||||||
|
cmd = [
|
||||||
|
sys.executable,
|
||||||
|
str(script_path),
|
||||||
|
"--chain-id", chain_id
|
||||||
|
]
|
||||||
|
|
||||||
|
if create_wallet:
|
||||||
|
cmd.append("--create-wallet")
|
||||||
|
|
||||||
|
if password:
|
||||||
|
cmd.extend(["--password", password])
|
||||||
|
|
||||||
|
if proposer:
|
||||||
|
cmd.extend(["--proposer", proposer])
|
||||||
|
|
||||||
|
if force:
|
||||||
|
cmd.append("--force")
|
||||||
|
|
||||||
|
if register_service:
|
||||||
|
cmd.append("--register-service")
|
||||||
|
cmd.extend(["--service-url", service_url])
|
||||||
|
|
||||||
|
try:
|
||||||
|
success(f"Running genesis generation for {chain_id}...")
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||||
|
output(result.stdout, ctx.obj.get("output_format", "table"))
|
||||||
|
success(f"Genesis generation completed successfully")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
error(f"Genesis generation failed: {e.stderr}")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@genesis.command()
|
||||||
|
@click.option("--chain-id", default="ait-mainnet", help="Chain ID to verify")
|
||||||
|
@click.pass_context
|
||||||
|
def verify(ctx, chain_id: str):
|
||||||
|
"""Verify genesis block and wallet configuration"""
|
||||||
|
import json
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
# Check genesis config file
|
||||||
|
genesis_path = Path(f"/var/lib/aitbc/data/{chain_id}/genesis.json")
|
||||||
|
if not genesis_path.exists():
|
||||||
|
error(f"Genesis config not found: {genesis_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(genesis_path) as f:
|
||||||
|
genesis_data = json.load(f)
|
||||||
|
|
||||||
|
success(f"✓ Genesis config found: {genesis_path}")
|
||||||
|
output({
|
||||||
|
"chain_id": genesis_data.get("chain_id"),
|
||||||
|
"genesis_hash": genesis_data.get("block", {}).get("hash"),
|
||||||
|
"proposer": genesis_data.get("block", {}).get("proposer"),
|
||||||
|
"allocations_count": len(genesis_data.get("allocations", []))
|
||||||
|
}, ctx.obj.get("output_format", "table"))
|
||||||
|
except Exception as e:
|
||||||
|
error(f"Failed to read genesis config: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check database
|
||||||
|
db_path = Path("/var/lib/aitbc/data/chain.db")
|
||||||
|
if not db_path.exists():
|
||||||
|
error(f"Database not found: {db_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect(str(db_path))
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Check genesis block
|
||||||
|
cursor.execute("SELECT * FROM block WHERE height=0 AND chain_id=?", (chain_id,))
|
||||||
|
genesis_block = cursor.fetchone()
|
||||||
|
|
||||||
|
if genesis_block:
|
||||||
|
success(f"✓ Genesis block found in database")
|
||||||
|
output({
|
||||||
|
"height": genesis_block[1],
|
||||||
|
"hash": genesis_block[2],
|
||||||
|
"proposer": genesis_block[4]
|
||||||
|
}, ctx.obj.get("output_format", "table"))
|
||||||
|
else:
|
||||||
|
error(f"Genesis block not found in database for chain {chain_id}")
|
||||||
|
|
||||||
|
# Check genesis accounts
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM account WHERE chain_id=?", (chain_id,))
|
||||||
|
account_count = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
if account_count > 0:
|
||||||
|
success(f"✓ Found {account_count} accounts in database")
|
||||||
|
else:
|
||||||
|
error(f"No accounts found in database for chain {chain_id}")
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
except Exception as e:
|
||||||
|
error(f"Failed to verify database: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check genesis wallet
|
||||||
|
wallet_path = Path("/var/lib/aitbc/keystore/genesis.json")
|
||||||
|
if wallet_path.exists():
|
||||||
|
success(f"✓ Genesis wallet found: {wallet_path}")
|
||||||
|
try:
|
||||||
|
with open(wallet_path) as f:
|
||||||
|
wallet_data = json.load(f)
|
||||||
|
output({
|
||||||
|
"address": wallet_data.get("address"),
|
||||||
|
"public_key": wallet_data.get("public_key")[:16] + "..." if wallet_data.get("public_key") else None
|
||||||
|
}, ctx.obj.get("output_format", "table"))
|
||||||
|
except Exception as e:
|
||||||
|
error(f"Failed to read genesis wallet: {e}")
|
||||||
|
else:
|
||||||
|
error(f"Genesis wallet not found: {wallet_path}")
|
||||||
|
|
||||||
|
|
||||||
|
@genesis.command()
|
||||||
|
@click.option("--chain-id", default="ait-mainnet", help="Chain ID to show info for")
|
||||||
|
@click.pass_context
|
||||||
|
def info(ctx, chain_id: str):
|
||||||
|
"""Show genesis block information"""
|
||||||
|
import json
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
genesis_path = Path(f"/var/lib/aitbc/data/{chain_id}/genesis.json")
|
||||||
|
if not genesis_path.exists():
|
||||||
|
error(f"Genesis config not found: {genesis_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(genesis_path) as f:
|
||||||
|
genesis_data = json.load(f)
|
||||||
|
|
||||||
|
block = genesis_data.get("block", {})
|
||||||
|
allocations = genesis_data.get("allocations", [])
|
||||||
|
|
||||||
|
output({
|
||||||
|
"chain_id": genesis_data.get("chain_id"),
|
||||||
|
"genesis_block": {
|
||||||
|
"height": block.get("height"),
|
||||||
|
"hash": block.get("hash"),
|
||||||
|
"parent_hash": block.get("parent_hash"),
|
||||||
|
"proposer": block.get("proposer"),
|
||||||
|
"timestamp": block.get("timestamp"),
|
||||||
|
"tx_count": block.get("tx_count")
|
||||||
|
},
|
||||||
|
"allocations": [
|
||||||
|
{
|
||||||
|
"address": alloc.get("address"),
|
||||||
|
"balance": alloc.get("balance"),
|
||||||
|
"nonce": alloc.get("nonce")
|
||||||
|
}
|
||||||
|
for alloc in allocations[:5] # Show first 5
|
||||||
|
],
|
||||||
|
"total_allocations": len(allocations)
|
||||||
|
}, ctx.obj.get("output_format", "table"))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error(f"Failed to read genesis info: {e}")
|
||||||
@@ -11,6 +11,7 @@ from pathlib import Path
|
|||||||
from aitbc_cli.commands.gpu_marketplace import gpu
|
from aitbc_cli.commands.gpu_marketplace import gpu
|
||||||
from aitbc_cli.commands.exchange_island import exchange_island
|
from aitbc_cli.commands.exchange_island import exchange_island
|
||||||
from aitbc_cli.commands.wallet import wallet
|
from aitbc_cli.commands.wallet import wallet
|
||||||
|
from aitbc_cli.commands.genesis import genesis
|
||||||
|
|
||||||
# Force version to 0.2.2
|
# Force version to 0.2.2
|
||||||
__version__ = "0.2.2"
|
__version__ = "0.2.2"
|
||||||
@@ -159,6 +160,7 @@ cli.add_command(version)
|
|||||||
cli.add_command(gpu)
|
cli.add_command(gpu)
|
||||||
cli.add_command(exchange_island)
|
cli.add_command(exchange_island)
|
||||||
cli.add_command(wallet)
|
cli.add_command(wallet)
|
||||||
|
cli.add_command(genesis)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
cli()
|
cli()
|
||||||
|
|||||||
322
docs/genesis_generation.md
Normal file
322
docs/genesis_generation.md
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
# Genesis Block and Wallet Generation Guide
|
||||||
|
|
||||||
|
This guide explains how to use the unified genesis generation system for AITBC blockchain initialization.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The unified genesis generation system combines:
|
||||||
|
- **Genesis Block Creation**: Creates the initial block for a blockchain
|
||||||
|
- **Genesis Wallet Creation**: Generates a secure genesis wallet with known private key
|
||||||
|
- **Wallet Service Integration**: Registers the genesis wallet with the wallet daemon service
|
||||||
|
- **Database Initialization**: Sets up the blockchain database with genesis data
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Python 3.13+
|
||||||
|
- AITBC blockchain node installed
|
||||||
|
- Wallet daemon service running (optional, for service integration)
|
||||||
|
- Database directory: `/var/lib/aitbc/data/`
|
||||||
|
- Keystore directory: `/var/lib/aitbc/keystore/`
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The unified genesis script is located at:
|
||||||
|
```
|
||||||
|
/opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Make it executable:
|
||||||
|
```bash
|
||||||
|
chmod +x /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
Create genesis block and wallet for mainnet:
|
||||||
|
```bash
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Options
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet \
|
||||||
|
--password "your_secure_password" \
|
||||||
|
--proposer "custom_proposer_address" \
|
||||||
|
--db-path /var/lib/aitbc/data/chain.db \
|
||||||
|
--keystore-path /var/lib/aitbc/keystore/genesis.json \
|
||||||
|
--genesis-path /var/lib/aitbc/data/ait-mainnet/genesis.json \
|
||||||
|
--force \
|
||||||
|
--register-service \
|
||||||
|
--service-url http://localhost:8003
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command-Line Options
|
||||||
|
|
||||||
|
| Option | Description | Default |
|
||||||
|
|--------|-------------|---------|
|
||||||
|
| `--chain-id` | Chain ID for genesis | `ait-mainnet` |
|
||||||
|
| `--proposer` | Proposer address (defaults to genesis wallet) | `genesis` |
|
||||||
|
| `--create-wallet` | Create genesis wallet with secure random key | `False` |
|
||||||
|
| `--password` | Wallet password (auto-generated if not provided) | auto-generated |
|
||||||
|
| `--db-path` | Database file path | `/var/lib/aitbc/data/chain.db` |
|
||||||
|
| `--keystore-path` | Keystore file path | `/var/lib/aitbc/keystore/genesis.json` |
|
||||||
|
| `--genesis-path` | Genesis config file path | `/var/lib/aitbc/data/ait-mainnet/genesis.json` |
|
||||||
|
| `--force` | Force overwrite existing genesis | `False` |
|
||||||
|
| `--register-service` | Register genesis wallet with wallet service | `False` |
|
||||||
|
| `--service-url` | Wallet service URL | `http://localhost:8003` |
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### Step 1: Create Genesis Wallet and Block
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop blockchain node if running
|
||||||
|
systemctl stop aitbc-blockchain-node.service
|
||||||
|
|
||||||
|
# Generate genesis
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet \
|
||||||
|
--force
|
||||||
|
|
||||||
|
# Start blockchain node
|
||||||
|
systemctl start aitbc-blockchain-node.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Verify Genesis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check genesis block
|
||||||
|
curl http://localhost:8006/rpc/block/0
|
||||||
|
|
||||||
|
# Check genesis wallet balance
|
||||||
|
/opt/aitbc/aitbc-cli wallet balance genesis --chain-id ait-mainnet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Register with Wallet Service (Optional)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ensure wallet daemon is running
|
||||||
|
systemctl status aitbc-wallet-daemon.service
|
||||||
|
|
||||||
|
# Register genesis wallet
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--register-service \
|
||||||
|
--service-url http://localhost:8003
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Private Key Security
|
||||||
|
|
||||||
|
- The script generates a cryptographically secure random private key
|
||||||
|
- Private key is encrypted with AES-256-GCM
|
||||||
|
- Password is derived using PBKDF2 with 100,000 iterations
|
||||||
|
- Password is saved to `/var/lib/aitbc/keystore/.genesis_password` with 0600 permissions
|
||||||
|
|
||||||
|
### Important Security Notes
|
||||||
|
|
||||||
|
1. **Store the password securely**: The password is saved to `.genesis_password` but should be backed up to a secure location
|
||||||
|
2. **Never share the private key**: The private key should only be known by authorized personnel
|
||||||
|
3. **Use strong passwords**: If providing a custom password, use a strong, unique password
|
||||||
|
4. **Backup the keystore**: The genesis wallet file should be backed up securely
|
||||||
|
5. **Rotate keys periodically**: For production, consider key rotation policies
|
||||||
|
|
||||||
|
## Multi-Chain Support
|
||||||
|
|
||||||
|
The script supports multiple chains:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Mainnet
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet
|
||||||
|
|
||||||
|
# Devnet
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-devnet \
|
||||||
|
--create-wallet \
|
||||||
|
--db-path /var/lib/aitbc/data/ait-devnet/chain.db \
|
||||||
|
--genesis-path /var/lib/aitbc/data/ait-devnet/genesis.json
|
||||||
|
|
||||||
|
# Testnet
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-testnet \
|
||||||
|
--create-wallet \
|
||||||
|
--db-path /var/lib/aitbc/data/ait-testnet/chain.db \
|
||||||
|
--genesis-path /var/lib/aitbc/data/ait-testnet/genesis.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Database Locked Error
|
||||||
|
|
||||||
|
If you get a database locked error:
|
||||||
|
```bash
|
||||||
|
# Stop the blockchain node
|
||||||
|
systemctl stop aitbc-blockchain-node.service
|
||||||
|
|
||||||
|
# Run genesis generation
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet
|
||||||
|
|
||||||
|
# Start the blockchain node
|
||||||
|
systemctl start aitbc-blockchain-node.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Genesis Already Exists
|
||||||
|
|
||||||
|
If genesis already exists in the database:
|
||||||
|
```bash
|
||||||
|
# Use --force to overwrite
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet \
|
||||||
|
--force
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wallet Service Connection Failed
|
||||||
|
|
||||||
|
If wallet service registration fails:
|
||||||
|
```bash
|
||||||
|
# Check if wallet daemon is running
|
||||||
|
systemctl status aitbc-wallet-daemon.service
|
||||||
|
|
||||||
|
# Start wallet daemon if not running
|
||||||
|
systemctl start aitbc-wallet-daemon.service
|
||||||
|
|
||||||
|
# Verify service URL
|
||||||
|
curl http://localhost:8003/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with Wallet Service
|
||||||
|
|
||||||
|
The unified genesis script can register the genesis wallet with the wallet daemon service for enhanced wallet management capabilities:
|
||||||
|
|
||||||
|
### Benefits of Wallet Service Integration
|
||||||
|
|
||||||
|
- Centralized wallet management
|
||||||
|
- Automatic wallet synchronization
|
||||||
|
- Enhanced security features
|
||||||
|
- Transaction signing delegation
|
||||||
|
- Multi-wallet support
|
||||||
|
|
||||||
|
### Registration Process
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet \
|
||||||
|
--register-service \
|
||||||
|
--service-url http://localhost:8003
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will:
|
||||||
|
1. Create the genesis wallet
|
||||||
|
2. Register it with the wallet service
|
||||||
|
3. Store the wallet credentials securely
|
||||||
|
4. Enable wallet service operations
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Example 1: Fresh Mainnet Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Complete fresh setup for mainnet
|
||||||
|
systemctl stop aitbc-blockchain-node.service
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--create-wallet \
|
||||||
|
--force
|
||||||
|
systemctl start aitbc-blockchain-node.service
|
||||||
|
/opt/aitbc/aitbc-cli wallet balance genesis --chain-id ait-mainnet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Devnet with Custom Password
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Devnet setup with custom password
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-devnet \
|
||||||
|
--create-wallet \
|
||||||
|
--password "my_secure_devnet_password" \
|
||||||
|
--db-path /var/lib/aitbc/data/ait-devnet/chain.db \
|
||||||
|
--genesis-path /var/lib/aitbc/data/ait-devnet/genesis.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Register Existing Genesis with Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Register existing genesis wallet with service
|
||||||
|
python3 /opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py \
|
||||||
|
--chain-id ait-mainnet \
|
||||||
|
--register-service \
|
||||||
|
--service-url http://localhost:8003
|
||||||
|
```
|
||||||
|
|
||||||
|
## Output Files
|
||||||
|
|
||||||
|
After running the script, the following files are created:
|
||||||
|
|
||||||
|
1. **Genesis Wallet**: `/var/lib/aitbc/keystore/genesis.json`
|
||||||
|
- Encrypted wallet file with genesis credentials
|
||||||
|
- Contains address, public key, encrypted private key
|
||||||
|
|
||||||
|
2. **Password File**: `/var/lib/aitbc/keystore/.genesis_password`
|
||||||
|
- Plain text password file (0600 permissions)
|
||||||
|
- Should be backed up securely
|
||||||
|
|
||||||
|
3. **Genesis Config**: `/var/lib/aitbc/data/{chain_id}/genesis.json`
|
||||||
|
- Genesis block configuration
|
||||||
|
- Account allocations
|
||||||
|
- Chain metadata
|
||||||
|
|
||||||
|
4. **Database**: `/var/lib/aitbc/data/chain.db`
|
||||||
|
- Blockchain database with genesis block
|
||||||
|
- Genesis accounts
|
||||||
|
- Chain state
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
After genesis generation, verify the setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check genesis block in database
|
||||||
|
sqlite3 /var/lib/aitbc/data/chain.db "SELECT * FROM block WHERE height=0;"
|
||||||
|
|
||||||
|
# Check genesis accounts
|
||||||
|
sqlite3 /var/lib/aitbc/data/chain.db "SELECT address, balance FROM account WHERE chain_id='ait-mainnet';"
|
||||||
|
|
||||||
|
# Check wallet balance via CLI
|
||||||
|
/opt/aitbc/aitbc-cli wallet balance genesis --chain-id ait-mainnet
|
||||||
|
|
||||||
|
# Check blockchain node status
|
||||||
|
curl http://localhost:8006/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Always backup** the genesis wallet and password before running
|
||||||
|
2. **Use --force** only when necessary, as it overwrites existing genesis
|
||||||
|
3. **Test on devnet** before applying to mainnet
|
||||||
|
4. **Document** the genesis password in a secure location
|
||||||
|
5. **Monitor** the blockchain node after genesis initialization
|
||||||
|
6. **Verify** all services are running after genesis setup
|
||||||
|
7. **Keep** the genesis script updated with the latest blockchain changes
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues or questions:
|
||||||
|
- Check the blockchain node logs: `journalctl -u aitbc-blockchain-node.service -f`
|
||||||
|
- Check the wallet daemon logs: `journalctl -u aitbc-wallet-daemon.service -f`
|
||||||
|
- Review the script output for error messages
|
||||||
|
- Consult the AITBC documentation for additional guidance
|
||||||
Reference in New Issue
Block a user