-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython_oracle_submit.py
More file actions
171 lines (143 loc) Β· 6.12 KB
/
python_oracle_submit.py
File metadata and controls
171 lines (143 loc) Β· 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python3
"""
Python Oracle Submission Script for AIPredictionMultisig Contract
Alternative to oracle_submit.js for cases where Node.js has network connectivity issues
"""
import os
import sys
from web3 import Web3
from dotenv import load_dotenv
import json
# Load environment variables
load_dotenv()
# Contract configuration
CONTRACT_ADDRESS = os.getenv('SMART_CONTRACT_ADDRESS', '0x13f8C985c4791c811035E36AFb2D49Cfe044a429')
ORACLE_PRIVATE_KEY = os.getenv('ORACLE_PRIVATE_KEY')
RPC_URLS = [
os.getenv('RPC_URL', 'https://data-seed-prebsc-1-s1.binance.org:8545/'),
'https://data-seed-prebsc-1-s1.binance.org:8545',
'https://data-seed-prebsc-2-s1.binance.org:8545',
'https://bsc-testnet.publicnode.com',
'https://endpoints.omniatech.io/v1/bsc/testnet/public'
]
# Contract ABI - only the submitPrediction function
CONTRACT_ABI = [
{
"inputs": [
{"internalType": "string", "name": "ipfsHash", "type": "string"},
{"internalType": "uint8", "name": "confidenceScore", "type": "uint8"}
],
"name": "submitPrediction",
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
"stateMutability": "nonpayable",
"type": "function"
}
]
def test_rpc_connection(rpc_url):
"""Test RPC connection"""
try:
print(f"π Testing connection to {rpc_url}...")
w3 = Web3(Web3.HTTPProvider(rpc_url, request_kwargs={'timeout': 10}))
if w3.is_connected():
block_number = w3.eth.block_number
print(f"β
Connected! Current block: {block_number}")
return w3
else:
print(f"β Connection failed")
return None
except Exception as e:
print(f"β Error: {str(e)}")
return None
def submit_prediction(ipfs_hash, confidence_score):
"""Submit prediction to the smart contract"""
if len(sys.argv) != 3:
print("Usage: python python_oracle_submit.py <ipfs_hash> <confidence_score>")
return False
# Validate inputs
try:
confidence_score = int(confidence_score)
if confidence_score < 0 or confidence_score > 100:
print("β Confidence score must be between 0 and 100")
return False
except ValueError:
print("β Confidence score must be a number")
return False
print(f"π Python Oracle Submission")
print(f"π Contract: {CONTRACT_ADDRESS}")
print(f"π IPFS Hash: {ipfs_hash}")
print(f"π Confidence: {confidence_score}%")
# Test RPC connections
w3 = None
for rpc_url in RPC_URLS:
w3 = test_rpc_connection(rpc_url)
if w3:
break
if not w3:
print("β Could not connect to any BSC Testnet RPC endpoint")
return False
# Check if private key is available
if not ORACLE_PRIVATE_KEY:
print("β οΈ No private key found - running in simulation mode")
print("β
SUCCESS: Prediction data validated (SIMULATION)")
return True
try:
# Setup account
account = w3.eth.account.from_key(ORACLE_PRIVATE_KEY)
print(f"π Oracle Address: {account.address}")
# Create contract instance
contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=CONTRACT_ABI)
# Get gas price and optimize it
network_gas_price = w3.eth.gas_price
print(f"β½ Network Gas Price: {network_gas_price / 10**9:.2f} Gwei")
# Use lower gas price for cost optimization (BSC Testnet is usually not congested)
# Use 90% of network price or minimum 1 Gwei, whichever is higher
optimized_gas_price = max(int(network_gas_price * 0.9), w3.to_wei(1, 'gwei'))
print(f"β½ Optimized Gas Price: {optimized_gas_price / 10**9:.2f} Gwei (savings: {((network_gas_price - optimized_gas_price) / network_gas_price * 100):.1f}%)")
gas_price = optimized_gas_price
# Estimate gas for this specific transaction
try:
estimated_gas = contract.functions.submitPrediction(ipfs_hash, confidence_score).estimate_gas({
'from': account.address
})
# Add 20% buffer to estimated gas
safe_gas_limit = int(estimated_gas * 1.2)
print(f"β½ Estimated Gas: {estimated_gas:,}")
print(f"β½ Safe Gas Limit: {safe_gas_limit:,} (20% buffer)")
except Exception as e:
print(f"β οΈ Gas estimation failed: {e}")
safe_gas_limit = 180000 # Fallback
# Build transaction with optimized gas limit
transaction = contract.functions.submitPrediction(ipfs_hash, confidence_score).build_transaction({
'chainId': 97, # BSC Testnet
'gas': safe_gas_limit,
'gasPrice': gas_price,
'nonce': w3.eth.get_transaction_count(account.address),
})
# Sign transaction
signed_txn = w3.eth.account.sign_transaction(transaction, ORACLE_PRIVATE_KEY)
# Send transaction
print("π€ Sending transaction...")
tx_hash = w3.eth.send_raw_transaction(signed_txn.raw_transaction)
print(f"π Transaction Hash: {tx_hash.hex()}")
# Wait for confirmation
print("β³ Waiting for confirmation...")
receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
if receipt.status == 1:
print("β
SUCCESS: Prediction submitted to blockchain!")
print(f"π§Ύ Block Number: {receipt.blockNumber}")
print(f"β½ Gas Used: {receipt.gasUsed}")
return True
else:
print("β Transaction failed")
return False
except Exception as e:
print(f"β Error submitting to contract: {str(e)}")
return False
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python python_oracle_submit.py <ipfs_hash> <confidence_score>")
sys.exit(1)
ipfs_hash = sys.argv[1]
confidence_score = sys.argv[2]
success = submit_prediction(ipfs_hash, confidence_score)
sys.exit(0 if success else 1)