Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 69 additions & 28 deletions .ai/categories/smart-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -11179,8 +11179,6 @@ Page Title: Web3.py

# Web3.py

!!! smartcontract "PolkaVM Preview Release"
PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**.
## Introduction

Interacting with blockchains typically requires an interface between your application and the network. [Web3.py](https://web3py.readthedocs.io/en/stable/index.html){target=\_blank} offers this interface through a collection of libraries, facilitating seamless interaction with the nodes using HTTP or WebSocket protocols.
Expand Down Expand Up @@ -11221,7 +11219,7 @@ The [provider](https://web3py.readthedocs.io/en/stable/providers.html){target=\_

The provider connection script should look something like this:

```python title="connect_to_provider.py"
```python title="fetch_last_block.py"
from web3 import Web3

def create_provider(rpc_url):
Expand Down Expand Up @@ -11276,7 +11274,7 @@ The [provider](https://web3py.readthedocs.io/en/stable/providers.html){target=\_
Before deploying your contracts, make sure you've compiled them and obtained two key files:

- An ABI (.json) file, which provides a JSON interface describing the contract's functions and how to interact with it.
- A bytecode (.polkavm) file, which contains the low-level machine code executable on [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} that represents the compiled smart contract ready for blockchain deployment.
- A bytecode (.bin) file, which contains the low-level machine code executable on EVM that represents the compiled smart contract ready for blockchain deployment.

To follow this guide, you can use the following solidity contract as an example:

Expand Down Expand Up @@ -11309,6 +11307,7 @@ To deploy your compiled contract to Polkadot Hub using Web3.py, you'll need an a
```python title="deploy.py"
from web3 import Web3
import json
import time

def get_abi(contract_name):
try:
Expand All @@ -11320,66 +11319,108 @@ def get_abi(contract_name):

def get_bytecode(contract_name):
try:
with open(f"{contract_name}.polkavm", 'rb') as file:
return '0x' + file.read().hex()
with open(f"{contract_name}.bin", 'r') as file:
bytecode = file.read().strip()
return bytecode if bytecode.startswith('0x') else f"0x{bytecode}"
except Exception as error:
print(f"❌ Could not find bytecode for contract {contract_name}: {error}")
raise error

async def deploy(config):
def deploy_with_retry(config, max_retries=3):
"""Deploy with retry logic for RPC errors"""
for attempt in range(max_retries):
try:
return deploy(config)
except Exception as error:
error_str = str(error)
if "500" in error_str or "Internal Server Error" in error_str or "Connection" in error_str:
if attempt < max_retries - 1:
wait_time = (attempt + 1) * 3
print(f"RPC error, retrying in {wait_time} seconds... (attempt {attempt + 1}/{max_retries})")
time.sleep(wait_time)
continue
raise error

def deploy(config):
try:
# Initialize Web3 with RPC URL
web3 = Web3(Web3.HTTPProvider(config["rpc_url"]))
# Initialize Web3 with RPC URL and longer timeout
web3 = Web3(Web3.HTTPProvider(
config["rpc_url"],
request_kwargs={'timeout': 120}
))

# Prepare account
account = web3.eth.account.from_key(config["private_key"])
print(f"address: {account.address}")
formatted_private_key = config["private_key"] if config["private_key"].startswith('0x') else f"0x{config['private_key']}"
account = web3.eth.account.from_key(formatted_private_key)
print(f"Deploying from address: {account.address}")

# Load ABI
# Load ABI and bytecode
abi = get_abi('Storage')
bytecode = get_bytecode('Storage')
print(f"Bytecode length: {len(bytecode)}")

# Create contract instance
contract = web3.eth.contract(abi=abi, bytecode=get_bytecode('Storage'))
contract = web3.eth.contract(abi=abi, bytecode=bytecode)

# Get current nonce
# Get current nonce (this will test the connection)
print("Getting nonce...")
nonce = web3.eth.get_transaction_count(account.address)
print(f"Nonce: {nonce}")

# Prepare deployment transaction
transaction = {
# Estimate gas
print("Estimating gas...")
gas_estimate = web3.eth.estimate_gas({
'from': account.address,
'data': bytecode
})
print(f"Estimated gas: {gas_estimate}")

# Get gas price
print("Getting gas price...")
gas_price = web3.eth.gas_price
print(f"Gas price: {web3.from_wei(gas_price, 'gwei')} gwei")

# Build deployment transaction
print("Building transaction...")
construct_txn = contract.constructor().build_transaction({
'from': account.address,
'nonce': nonce,
}
'gas': gas_estimate,
'gasPrice': gas_price,
})

# Build and sign transaction
construct_txn = contract.constructor().build_transaction(transaction)
signed_txn = web3.eth.account.sign_transaction(construct_txn, private_key=config["private_key"])
# Sign transaction
print("Signing transaction...")
signed_txn = web3.eth.account.sign_transaction(construct_txn, private_key=formatted_private_key)

# Send transaction
print("Sending transaction...")
tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction)
print(f"Transaction hash: {tx_hash.hex()}")

# Wait for transaction receipt
tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
print("Waiting for transaction receipt...")
tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=300)
contract_address = tx_receipt.contractAddress

# Log and return contract details
print(f"Contract deployed at: {contract_address}")
# Log results
print(f"βœ… Contract deployed at: {contract_address}")
print(f"Gas used: {tx_receipt.gasUsed}")
print(f"Block number: {tx_receipt.blockNumber}")

return web3.eth.contract(address=contract_address, abi=abi)

except Exception as error:
print('Deployment failed:', error)
print(f'❌ Deployment failed: {error}')
raise error

if __name__ == "__main__":
# Example usage
import asyncio

deployment_config = {
"rpc_url": "INSERT_RPC_URL",
"private_key": "INSERT_PRIVATE_KEY",
}

asyncio.run(deploy(deployment_config))
deploy_with_retry(deployment_config)
```

!!!warning
Expand Down
97 changes: 69 additions & 28 deletions .ai/categories/tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -13274,8 +13274,6 @@ Page Title: Web3.py

# Web3.py

!!! smartcontract "PolkaVM Preview Release"
PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**.
## Introduction

Interacting with blockchains typically requires an interface between your application and the network. [Web3.py](https://web3py.readthedocs.io/en/stable/index.html){target=\_blank} offers this interface through a collection of libraries, facilitating seamless interaction with the nodes using HTTP or WebSocket protocols.
Expand Down Expand Up @@ -13316,7 +13314,7 @@ The [provider](https://web3py.readthedocs.io/en/stable/providers.html){target=\_

The provider connection script should look something like this:

```python title="connect_to_provider.py"
```python title="fetch_last_block.py"
from web3 import Web3

def create_provider(rpc_url):
Expand Down Expand Up @@ -13371,7 +13369,7 @@ The [provider](https://web3py.readthedocs.io/en/stable/providers.html){target=\_
Before deploying your contracts, make sure you've compiled them and obtained two key files:

- An ABI (.json) file, which provides a JSON interface describing the contract's functions and how to interact with it.
- A bytecode (.polkavm) file, which contains the low-level machine code executable on [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} that represents the compiled smart contract ready for blockchain deployment.
- A bytecode (.bin) file, which contains the low-level machine code executable on EVM that represents the compiled smart contract ready for blockchain deployment.

To follow this guide, you can use the following solidity contract as an example:

Expand Down Expand Up @@ -13404,6 +13402,7 @@ To deploy your compiled contract to Polkadot Hub using Web3.py, you'll need an a
```python title="deploy.py"
from web3 import Web3
import json
import time

def get_abi(contract_name):
try:
Expand All @@ -13415,66 +13414,108 @@ def get_abi(contract_name):

def get_bytecode(contract_name):
try:
with open(f"{contract_name}.polkavm", 'rb') as file:
return '0x' + file.read().hex()
with open(f"{contract_name}.bin", 'r') as file:
bytecode = file.read().strip()
return bytecode if bytecode.startswith('0x') else f"0x{bytecode}"
except Exception as error:
print(f"❌ Could not find bytecode for contract {contract_name}: {error}")
raise error

async def deploy(config):
def deploy_with_retry(config, max_retries=3):
"""Deploy with retry logic for RPC errors"""
for attempt in range(max_retries):
try:
return deploy(config)
except Exception as error:
error_str = str(error)
if "500" in error_str or "Internal Server Error" in error_str or "Connection" in error_str:
if attempt < max_retries - 1:
wait_time = (attempt + 1) * 3
print(f"RPC error, retrying in {wait_time} seconds... (attempt {attempt + 1}/{max_retries})")
time.sleep(wait_time)
continue
raise error

def deploy(config):
try:
# Initialize Web3 with RPC URL
web3 = Web3(Web3.HTTPProvider(config["rpc_url"]))
# Initialize Web3 with RPC URL and longer timeout
web3 = Web3(Web3.HTTPProvider(
config["rpc_url"],
request_kwargs={'timeout': 120}
))

# Prepare account
account = web3.eth.account.from_key(config["private_key"])
print(f"address: {account.address}")
formatted_private_key = config["private_key"] if config["private_key"].startswith('0x') else f"0x{config['private_key']}"
account = web3.eth.account.from_key(formatted_private_key)
print(f"Deploying from address: {account.address}")

# Load ABI
# Load ABI and bytecode
abi = get_abi('Storage')
bytecode = get_bytecode('Storage')
print(f"Bytecode length: {len(bytecode)}")

# Create contract instance
contract = web3.eth.contract(abi=abi, bytecode=get_bytecode('Storage'))
contract = web3.eth.contract(abi=abi, bytecode=bytecode)

# Get current nonce
# Get current nonce (this will test the connection)
print("Getting nonce...")
nonce = web3.eth.get_transaction_count(account.address)
print(f"Nonce: {nonce}")

# Prepare deployment transaction
transaction = {
# Estimate gas
print("Estimating gas...")
gas_estimate = web3.eth.estimate_gas({
'from': account.address,
'data': bytecode
})
print(f"Estimated gas: {gas_estimate}")

# Get gas price
print("Getting gas price...")
gas_price = web3.eth.gas_price
print(f"Gas price: {web3.from_wei(gas_price, 'gwei')} gwei")

# Build deployment transaction
print("Building transaction...")
construct_txn = contract.constructor().build_transaction({
'from': account.address,
'nonce': nonce,
}
'gas': gas_estimate,
'gasPrice': gas_price,
})

# Build and sign transaction
construct_txn = contract.constructor().build_transaction(transaction)
signed_txn = web3.eth.account.sign_transaction(construct_txn, private_key=config["private_key"])
# Sign transaction
print("Signing transaction...")
signed_txn = web3.eth.account.sign_transaction(construct_txn, private_key=formatted_private_key)

# Send transaction
print("Sending transaction...")
tx_hash = web3.eth.send_raw_transaction(signed_txn.raw_transaction)
print(f"Transaction hash: {tx_hash.hex()}")

# Wait for transaction receipt
tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
print("Waiting for transaction receipt...")
tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=300)
contract_address = tx_receipt.contractAddress

# Log and return contract details
print(f"Contract deployed at: {contract_address}")
# Log results
print(f"βœ… Contract deployed at: {contract_address}")
print(f"Gas used: {tx_receipt.gasUsed}")
print(f"Block number: {tx_receipt.blockNumber}")

return web3.eth.contract(address=contract_address, abi=abi)

except Exception as error:
print('Deployment failed:', error)
print(f'❌ Deployment failed: {error}')
raise error

if __name__ == "__main__":
# Example usage
import asyncio

deployment_config = {
"rpc_url": "INSERT_RPC_URL",
"private_key": "INSERT_PRIVATE_KEY",
}

asyncio.run(deploy(deployment_config))
deploy_with_retry(deployment_config)
```

!!!warning
Expand Down
Loading
Loading