Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 2c33ecdf94c8d90b421cc222b310e1e2d179f062 139 lines 4.9 kB view raw
1""" 2Deploy FA2 contract to Ghostnet using PyTezos (pure Python, no octez-client needed) 3""" 4 5import sys 6from pathlib import Path 7from pytezos import pytezos, Key 8 9# Load kidlisp wallet credentials 10vault_dir = Path(__file__).parent.parent / "aesthetic-computer-vault" / "tezos" / "kidlisp" 11env_file = vault_dir / ".env" 12 13KIDLISP_ADDRESS = None 14KIDLISP_KEY = None 15 16if env_file.exists(): 17 with open(env_file) as f: 18 for line in f: 19 if line.startswith('KIDLISP_ADDRESS='): 20 KIDLISP_ADDRESS = line.split('=')[1].strip().strip('"') 21 elif line.startswith('KIDLISP_KEY='): 22 KIDLISP_KEY = line.split('=')[1].strip().strip('"') 23 24if not KIDLISP_ADDRESS or not KIDLISP_KEY: 25 print("❌ Error: KIDLISP credentials not found in vault/tezos/kidlisp/.env") 26 sys.exit(1) 27 28# Ghostnet configuration 29GHOSTNET_RPC = "https://ghostnet.ecadinfra.com" 30 31 32def deploy_contract(): 33 print("=" * 70) 34 print("🚀 Deploying FA2 Contract to Ghostnet (PyTezos)") 35 print("=" * 70) 36 print() 37 38 # Connect to Ghostnet with kidlisp key 39 print("🔧 Connecting to Ghostnet...") 40 ptz = pytezos.using(shell=GHOSTNET_RPC, key=Key.from_encoded_key(KIDLISP_KEY)) 41 42 print(f" ✓ RPC: {GHOSTNET_RPC}") 43 print(f" ✓ Address: {ptz.key.public_key_hash()}") 44 45 # Check balance 46 print("\n💰 Checking balance...") 47 balance = ptz.balance() 48 balance_xtz = balance / 1_000_000 49 print(f" ✓ Balance: {balance_xtz:.6f} XTZ") 50 51 if balance_xtz < 1: 52 print(" ⚠️ Low balance! Get testnet tez from: https://faucet.ghostnet.teztnets.com/") 53 54 # Load contract 55 print("\n📄 Loading contract...") 56 contract_file = Path(__file__).parent / "michelson-lib" / "keeps-fa2-complete.tz" 57 58 if not contract_file.exists(): 59 print(f"❌ Contract file not found: {contract_file}") 60 sys.exit(1) 61 62 contract_code = contract_file.read_text() 63 print(f" ✓ Loaded: {contract_file.name}") 64 65 # Initial storage (Michelson format) 66 # Structure: (pair (pair address ledger) (pair next_token_id (pair operators token_metadata))) 67 admin_address = ptz.key.public_key_hash() 68 initial_storage = f'(Pair (Pair "{admin_address}" {{}}) (Pair 0 (Pair {{}} {{}})))' 69 70 print(f"\n💾 Initial storage:") 71 print(f" ✓ Administrator: {admin_address}") 72 print(f" ✓ Next token ID: 0") 73 74 # Deploy 75 print("\n📤 Deploying contract...") 76 print(" (This may take 1-2 minutes...)") 77 78 try: 79 # Originate 80 op = ptz.origination(script={ 81 'code': contract_code, 82 'storage': initial_storage 83 }).autofill().sign() 84 85 print(f" ⏳ Operation: {op.hash}") 86 print(" ⏳ Waiting for confirmation...") 87 88 # Inject and wait 89 result = op.inject(_async=False) 90 91 # Get contract address from result 92 contract_address = None 93 if hasattr(result, 'contents'): 94 for content in result.contents: 95 if hasattr(content, 'metadata') and content.metadata: 96 results = content.metadata.get('operation_result', {}).get('originated_contracts', []) 97 if results: 98 contract_address = results[0] 99 break 100 101 if not contract_address: 102 # Try to find from operation receipt 103 print("\n⚠️ Looking for contract address in operation receipt...") 104 op_result = ptz.shell.blocks['head'].operations[3][op.hash].get() 105 for content in op_result: 106 if 'metadata' in content: 107 results = content['metadata'].get('operation_result', {}).get('originated_contracts', []) 108 if results: 109 contract_address = results[0] 110 break 111 112 if contract_address: 113 print("\n" + "=" * 70) 114 print("✅ Contract Deployed Successfully!") 115 print("=" * 70) 116 print() 117 print(f"📍 Contract Address: {contract_address}") 118 print(f"🔍 View on TzKT: https://ghostnet.tzkt.io/{contract_address}") 119 print() 120 121 # Save contract address 122 address_file = Path(__file__).parent / "contract-address.txt" 123 address_file.write_text(contract_address) 124 print(f"💾 Saved to: {address_file}") 125 126 return contract_address 127 else: 128 print("\n⚠️ Deployment succeeded but couldn't extract contract address") 129 print(f" Check operation: https://ghostnet.tzkt.io/{op.hash}") 130 131 except Exception as e: 132 print(f"\n❌ Deployment failed: {e}") 133 import traceback 134 traceback.print_exc() 135 sys.exit(1) 136 137 138if __name__ == "__main__": 139 deploy_contract()