toecm commited on
Commit
1235463
·
verified ·
1 Parent(s): 5f2b878

Update src/trust_agent.py

Browse files
Files changed (1) hide show
  1. src/trust_agent.py +73 -44
src/trust_agent.py CHANGED
@@ -161,72 +161,101 @@ class AgentTrust:
161
  except: return "IPFS_Fail"
162
 
163
  # --- CORE BLOCKCHAIN LOGIC ---
164
- def stamp_on_chain(self, payload, **kwargs):
165
- """Mints a verified dialect entry to PureChain."""
166
- print(f"⛓️ Attempting to mint to PureChain: {payload.get('original')}")
 
 
 
 
 
 
 
 
 
 
167
 
168
  try:
169
- if not hasattr(self, 'w3') or not self.w3.is_connected():
170
- print("❌ PureChain not connected. Cannot mint.")
 
 
 
 
 
171
  return False
172
 
173
- # 🟢 Use the global CONTRACT_ABI, not self.config.CONTRACT_ABI
174
- contract = self.w3.eth.contract(
175
- address=self.config.PURECHAIN_CONTRACT_ADDRESS,
176
- abi=CONTRACT_ABI
177
- )
178
-
179
- # 2. Extract Data from Payload
180
- phrase = payload.get("original", "Unknown Phrase")
181
- dialect = payload.get("dialect", "General")
182
-
183
- # If you aren't using Pinata/IPFS yet, use a placeholder
184
- ipfs_cid = payload.get("ipfs_cid", "pending_ipfs_hash")
185
- license_type = "Open Research"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
- # 3. Prepare the Wallet Account
188
- account = self.w3.eth.account.from_key(self.config.PRIVATE_KEY)
189
- nonce = self.w3.eth.get_transaction_count(account.address)
190
 
191
- # 4. Build the Transaction targeting 'proposeEntry'
192
  tx = contract.functions.proposeEntry(
193
  phrase,
194
  dialect,
195
- ipfs_cid,
196
  license_type
197
  ).build_transaction({
198
- 'from': account.address,
 
 
199
  'nonce': nonce,
200
- 'gas': 3000000, # Increased gas limit to prevent Out-Of-Gas reverts
201
- 'gasPrice': 0,
202
- 'chainId': self.config.PURECHAIN_ID
203
  })
 
 
 
 
 
204
 
205
- # 5. Sign and Send
206
- print("✍️ Signing transaction...")
207
- signed_tx = self.w3.eth.account.sign_transaction(tx, private_key=self.config.PRIVATE_KEY)
208
- tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
209
-
210
- # 6. Wait for Confirmation
211
- print(f"⏳ Waiting for confirmation on TX: {tx_hash.hex()}...")
212
- receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
213
 
214
- # 7. Check if it Succeeded or Reverted
215
  if receipt.status == 1:
216
- print(f" SUCCESS! Minted to PureChain in Block: {receipt.blockNumber}")
217
-
218
- # 🟢 FIX: Trigger the local history logger and HF sync!
219
- self.log_mint_to_history(phrase, dialect, tx_hash.hex(), receipt.blockNumber, ipfs_cid)
220
 
 
 
 
221
  return True
222
  else:
223
- print(f" REVERTED! The smart contract rejected the transaction.")
224
- print("Make sure your wallet address is registered via 'registerResearcher' first!")
225
  return False
226
-
227
  except Exception as e:
228
- print(f"🚨 Blockchain Error during minting: {e}")
 
 
229
  return False
 
 
230
 
231
  def log_mint_to_history(self, utterance, dialect, tx_hash, block_num, cid):
232
  history_file = "/app/minted_history.csv"
 
161
  except: return "IPFS_Fail"
162
 
163
  # --- CORE BLOCKCHAIN LOGIC ---
164
+ def stamp_on_chain(self, payload):
165
+ """
166
+ Hashes the validated sociolinguistic data and mints it to the Purechain ledger
167
+ using the PureConvo contract's proposeEntry function.
168
+ """
169
+ import json
170
+ import hashlib
171
+ import os
172
+ from web3 import Web3
173
+ from web3.middleware import geth_poa_middleware
174
+
175
+ print("\n" + "="*40)
176
+ print("⛓️ INITIATING PURECHAIN MINTING SEQUENCE")
177
 
178
  try:
179
+ # 1. Load Environment Variables (Updated to match your secrets)
180
+ rpc_url = os.environ.get("PURECHAIN_RPC_URL")
181
+ private_key = os.environ.get("PRIVATE_KEY")
182
+ contract_address = os.environ.get("PURECHAIN_CONTRACT_ADDRESS")
183
+
184
+ if not all([rpc_url, private_key, contract_address]):
185
+ print("⚠️ Purechain skipped: Missing RPC_URL, PRIVATE_KEY, or PURECHAIN_CONTRACT_ADDRESS.")
186
  return False
187
 
188
+ # 2. Establish Network Connection
189
+ w3 = Web3(Web3.HTTPProvider(rpc_url))
190
+ w3.middleware_onion.inject(geth_poa_middleware, layer=0) # PoA compatibility
191
+
192
+ if not w3.is_connected():
193
+ print("🔴 Purechain connection failed. Network may be offline.")
194
+ return False
195
+
196
+ account = w3.eth.account.from_key(private_key)
197
+ wallet_address = account.address
198
+ print(f"✅ Authenticated as Operator: {wallet_address}")
199
+
200
+ # 3. Cryptographic Hashing of the Data
201
+ # We hash the full JSON payload to use as our "IPFS CID" / Data Hash proof
202
+ payload_str = json.dumps(payload, sort_keys=True)
203
+ data_hash = hashlib.sha256(payload_str.encode('utf-8')).hexdigest()
204
+ print(f"🔒 Payload SHA-256 Proof: {data_hash}")
205
+
206
+ # 4. Load the Smart Contract using your config.py ABI
207
+ # Ensure your config is imported/available in trust_agent.py
208
+ contract = w3.eth.contract(address=contract_address, abi=self.config.CONTRACT_ABI)
209
+
210
+ # 5. Extract values for the proposeEntry parameters
211
+ # function proposeEntry(string _phrase, string _dialect, string _ipfsCid, string _license)
212
+ phrase = payload.get("original", "Unknown Utterance")
213
+ dialect = payload.get("dialect", "Unknown Dialect")
214
+ license_type = "CC-BY-4.0 (Open Research)" # Academic open data license
215
 
216
+ # 6. Build the Transaction
217
+ nonce = w3.eth.get_transaction_count(wallet_address)
 
218
 
 
219
  tx = contract.functions.proposeEntry(
220
  phrase,
221
  dialect,
222
+ data_hash,
223
  license_type
224
  ).build_transaction({
225
+ 'chainId': w3.eth.chain_id,
226
+ 'gas': 2000000,
227
+ 'gasPrice': w3.eth.gas_price,
228
  'nonce': nonce,
 
 
 
229
  })
230
+
231
+ # 7. Sign and Broadcast
232
+ signed_tx = w3.eth.account.sign_transaction(tx, private_key)
233
+ tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
234
+ hex_hash = w3.to_hex(tx_hash)
235
 
236
+ print(f"🚀 Transaction Broadcasted! TX Hash: {hex_hash}")
237
+
238
+ # 8. Wait for Confirmation
239
+ receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
 
 
 
 
240
 
 
241
  if receipt.status == 1:
242
+ print(f"💎 SUCCESS: Entry '{phrase[:15]}...' irreversibly minted in Block {receipt.blockNumber}")
 
 
 
243
 
244
+ # OPTIONAL: Save the receipt to your Gradio Transaction History tab
245
+ if hasattr(self, '_log_transaction_history'):
246
+ self._log_transaction_history(payload, hex_hash, receipt.blockNumber)
247
  return True
248
  else:
249
+ print("⚠️ Transaction reverted by the EVM. (Check if wallet is registered)")
 
250
  return False
251
+
252
  except Exception as e:
253
+ import traceback
254
+ print(f"\n❌ SMART CONTRACT ERROR ❌\n{e}")
255
+ traceback.print_exc()
256
  return False
257
+ finally:
258
+ print("="*40 + "\n")
259
 
260
  def log_mint_to_history(self, utterance, dialect, tx_hash, block_num, cid):
261
  history_file = "/app/minted_history.csv"