kopia lustrzana https://github.com/bugout-dev/moonworm
small fixes
rodzic
7fada297d2
commit
68e898142c
|
@ -26,9 +26,10 @@ if __name__ == "__main__":
|
|||
|
||||
# RCC has around 11k Transfer events
|
||||
# https://etherscan.io/token/0x9b6443b0fb9c241a7fdac375595cea13e6b7807a
|
||||
RCC_ADDRESS = "0x9b6443b0fB9C241A7fdAC375595cEa13e6B7807A"
|
||||
RCC_ADDRESS = "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619"
|
||||
|
||||
# Reduced ERC-20 ABI, only Transfer event
|
||||
|
||||
ABI = [
|
||||
{
|
||||
"anonymous": False,
|
||||
|
@ -62,7 +63,7 @@ if __name__ == "__main__":
|
|||
provider.middlewares.clear()
|
||||
|
||||
web3 = Web3(provider)
|
||||
|
||||
print(web3.eth.block_number)
|
||||
# Restore/create our persistent state
|
||||
state = JSONifiedState()
|
||||
state.restore()
|
||||
|
@ -93,7 +94,7 @@ if __name__ == "__main__":
|
|||
# Note that our chain reorg safety blocks cannot go negative
|
||||
# start_block = max(state.get_last_scanned_block() - chain_reorg_safety_blocks, 0)
|
||||
end_block = scanner.get_suggested_scan_end_block()
|
||||
start_block = 0
|
||||
start_block = end_block - 1000
|
||||
blocks_to_scan = end_block - start_block
|
||||
|
||||
print(f"Scanning events from blocks {start_block} - {end_block}")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
from typing import Any, Dict, List, Optional, Tuple, Type, Union
|
||||
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
|
@ -6,6 +7,8 @@ from web3 import Web3
|
|||
from web3.contract import Contract
|
||||
from web3.types import ABIEvent, ABIFunction
|
||||
|
||||
from .web3_util import deploy_contract
|
||||
|
||||
|
||||
def init_web3(ipc_path: str) -> Web3:
|
||||
return Web3(web3.HTTPProvider(ipc_path))
|
||||
|
@ -28,3 +31,33 @@ def abi_show(abi: Dict[str, Any]) -> Tuple[List[ABIFunction], List[ABIEvent]]:
|
|||
|
||||
def call_function(contract: Contract, function_name, *args) -> Any:
|
||||
contract.functions[function_name]().call(*args)
|
||||
|
||||
|
||||
def deploy_ERC1155(
|
||||
web3: Web3,
|
||||
token_name: str,
|
||||
token_symbol: str,
|
||||
token_uri: str,
|
||||
token_owner: ChecksumAddress,
|
||||
deployer: ChecksumAddress,
|
||||
deployer_private_key: str,
|
||||
) -> str:
|
||||
base_dir = os.path.dirname(__file__)
|
||||
contract_bytecode_path = os.path.join(base_dir, "fixture/bytecodes/ERC1155.bin")
|
||||
with open(contract_bytecode_path, "r") as ifp:
|
||||
contract_bytecode = ifp.read()
|
||||
|
||||
contract_abi_path = os.path.join(base_dir, "fixture/abis/ERC1155.json")
|
||||
with open(contract_abi_path, "r") as ifp:
|
||||
contract_abi = ifp.read()
|
||||
|
||||
contract_address = deploy_contract(
|
||||
web3,
|
||||
contract_bytecode,
|
||||
contract_abi,
|
||||
deployer,
|
||||
deployer_private_key,
|
||||
[token_name, token_symbol, token_uri, token_owner],
|
||||
)
|
||||
|
||||
return contract_address
|
||||
|
|
|
@ -4,10 +4,12 @@ import unittest
|
|||
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
from web3 import Web3, EthereumTesterProvider
|
||||
from ens import ENS
|
||||
|
||||
from centipede.manage import deploy_ERC1155
|
||||
from .web3_util import (
|
||||
build_transaction,
|
||||
deploy_ERC1155,
|
||||
decode_transaction_input,
|
||||
get_nonce,
|
||||
submit_signed_raw_transaction,
|
||||
submit_transaction,
|
||||
|
@ -43,26 +45,42 @@ def airdrop_ether(web3: Web3, to_address: ChecksumAddress):
|
|||
web3.eth.wait_for_transaction_receipt(tx_hash)
|
||||
|
||||
|
||||
class CentipedeTestCase(unittest.TestCase):
|
||||
class CentipedeEthTesterTestCase(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.web3 = get_web3_test_provider()
|
||||
self.tester_address = Web3.toChecksumAddress(PK_ADDRESS)
|
||||
self.tester_address_pk = PK
|
||||
airdrop_ether(self.web3, self.tester_address)
|
||||
|
||||
def check_eth_send(
|
||||
self,
|
||||
sender_previous_balance,
|
||||
receiver_previous_balance,
|
||||
sender_current_balance,
|
||||
receiver_current_balance,
|
||||
send_value,
|
||||
tx_receipt,
|
||||
):
|
||||
|
||||
assert receiver_current_balance == receiver_previous_balance + send_value
|
||||
assert (
|
||||
sender_current_balance
|
||||
== sender_previous_balance - send_value - tx_receipt["gasUsed"]
|
||||
)
|
||||
|
||||
def test_submit_transaction(self) -> None:
|
||||
|
||||
sender = Web3.toChecksumAddress(PK_ADDRESS)
|
||||
self.web3.eth.send_transaction
|
||||
receiver = Web3.toChecksumAddress(self.web3.eth.accounts[1])
|
||||
|
||||
current_sender_balance = self.web3.eth.get_balance(sender)
|
||||
current_receiver_balance = self.web3.eth.get_balance(receiver)
|
||||
|
||||
sender_previous_balance = self.web3.eth.get_balance(sender)
|
||||
receiver_previous_balance = self.web3.eth.get_balance(receiver)
|
||||
send_value = 10
|
||||
transaction = {
|
||||
"from": sender,
|
||||
"to": receiver,
|
||||
"value": 10,
|
||||
"value": send_value,
|
||||
"nonce": get_nonce(self.web3, sender),
|
||||
"gasPrice": 1,
|
||||
}
|
||||
|
@ -73,9 +91,17 @@ class CentipedeTestCase(unittest.TestCase):
|
|||
transaction,
|
||||
PK,
|
||||
)
|
||||
wait_for_transaction_receipt(self.web3, tx_hash)
|
||||
current_sender_balance = self.web3.eth.get_balance(sender)
|
||||
current_receiver_balance = self.web3.eth.get_balance(receiver)
|
||||
tx_receipt = wait_for_transaction_receipt(self.web3, tx_hash)
|
||||
sender_current_balance = self.web3.eth.get_balance(sender)
|
||||
receiver_current_balance = self.web3.eth.get_balance(receiver)
|
||||
self.check_eth_send(
|
||||
sender_previous_balance,
|
||||
receiver_previous_balance,
|
||||
sender_current_balance,
|
||||
receiver_current_balance,
|
||||
send_value,
|
||||
tx_receipt,
|
||||
)
|
||||
|
||||
def test_submit_signed_transaction(self) -> None:
|
||||
|
||||
|
@ -83,13 +109,14 @@ class CentipedeTestCase(unittest.TestCase):
|
|||
self.web3.eth.send_transaction
|
||||
receiver = Web3.toChecksumAddress(self.web3.eth.accounts[1])
|
||||
|
||||
current_sender_balance = self.web3.eth.get_balance(sender)
|
||||
current_receiver_balance = self.web3.eth.get_balance(receiver)
|
||||
sender_previous_balance = self.web3.eth.get_balance(sender)
|
||||
receiver_previous_balance = self.web3.eth.get_balance(receiver)
|
||||
send_value = 10
|
||||
|
||||
transaction = {
|
||||
"from": sender,
|
||||
"to": receiver,
|
||||
"value": 10,
|
||||
"value": send_value,
|
||||
"nonce": get_nonce(self.web3, sender),
|
||||
"gasPrice": 1,
|
||||
}
|
||||
|
@ -102,9 +129,17 @@ class CentipedeTestCase(unittest.TestCase):
|
|||
tx_hash = submit_signed_raw_transaction(
|
||||
self.web3, signed_transaction.rawTransaction
|
||||
)
|
||||
wait_for_transaction_receipt(self.web3, tx_hash)
|
||||
current_sender_balance = self.web3.eth.get_balance(sender)
|
||||
current_receiver_balance = self.web3.eth.get_balance(receiver)
|
||||
tx_receipt = wait_for_transaction_receipt(self.web3, tx_hash)
|
||||
sender_current_balance = self.web3.eth.get_balance(sender)
|
||||
receiver_current_balance = self.web3.eth.get_balance(receiver)
|
||||
self.check_eth_send(
|
||||
sender_previous_balance,
|
||||
receiver_previous_balance,
|
||||
sender_current_balance,
|
||||
receiver_current_balance,
|
||||
send_value,
|
||||
tx_receipt,
|
||||
)
|
||||
|
||||
def test_deploy_erc1155(self):
|
||||
TOKEN_NAME = "CENTIPEDE-TEST"
|
||||
|
@ -144,3 +179,11 @@ class CentipedeTestCase(unittest.TestCase):
|
|||
assert (
|
||||
contract.functions["uri"](1).call() == TOKEN_URI + "1"
|
||||
), "Token with id 1 is not created or has different uri from that is expected"
|
||||
|
||||
def test_decode_tx_input(self):
|
||||
base_dir = os.path.dirname(__file__)
|
||||
contract_abi_path = os.path.join(base_dir, "fixture/abis/ERC1155.json")
|
||||
with open(contract_abi_path, "r") as ifp:
|
||||
contract_abi = ifp.read()
|
||||
tx_input = "0xf242432a0000000000000000000000004f9a8e7dddee5f9737bafad382fa3bb119fc80c4000000000000000000000000c2485a4a8fbabbb7c39fe7b459816f2f16c238840000000000000000000000000000000000000000000000000000000000000378000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000"
|
||||
print(decode_transaction_input(self.web3, tx_input, contract_abi))
|
||||
|
|
|
@ -4,37 +4,56 @@ import os
|
|||
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
from hexbytes.main import HexBytes
|
||||
from web3 import Web3
|
||||
from web3.contract import ContractFunction
|
||||
from web3 import Web3, eth
|
||||
from web3.contract import Contract, ContractFunction
|
||||
from web3.types import Nonce, TxParams, TxReceipt, Wei
|
||||
|
||||
|
||||
# TODO: need to test in ropsten with maxFeePerFas and maxPriorityFeePerGas
|
||||
# eth-tester doesnot support this values
|
||||
def build_transaction(
|
||||
web3: Web3,
|
||||
builder: ContractFunction,
|
||||
sender: ChecksumAddress,
|
||||
maxFeePerGas: Optional[Wei] = None,
|
||||
maxPriorityFeePerGas: Optional[Wei] = None,
|
||||
):
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Builds transaction json with the given arguments. It is not submitting transaction
|
||||
Arguments:
|
||||
- web3: Web3 client
|
||||
- builder: ContractFunction or other class that has method buildTransaction(TxParams)
|
||||
- sender: `from` value of transaction, address which is sending this transaction
|
||||
- maxFeePerGas: Optional, max priority fee for dynamic fee transactions in Wei
|
||||
- maxPriorityFeePerGas: Optional the part of the fee that goes to the miner
|
||||
"""
|
||||
transaction = builder.buildTransaction(
|
||||
{
|
||||
"from": sender,
|
||||
# "maxFeePerGas": maxFeePerGas,
|
||||
# "maxPriorityFeePerGas": maxPriorityFeePerGas,
|
||||
"nonce": get_nonce(web3, sender),
|
||||
}
|
||||
)
|
||||
if maxFeePerGas:
|
||||
transaction["maxFeePerGas"] = maxFeePerGas
|
||||
if maxPriorityFeePerGas:
|
||||
transaction["maxPriorityFeePerGas"] = maxPriorityFeePerGas
|
||||
|
||||
return transaction
|
||||
|
||||
|
||||
def get_nonce(web3: Web3, sender: ChecksumAddress) -> Nonce:
|
||||
nonce = web3.eth.get_transaction_count(sender)
|
||||
def get_nonce(web3: Web3, address: ChecksumAddress) -> Nonce:
|
||||
"""
|
||||
Returns Nonce: number of transactions for given address
|
||||
"""
|
||||
nonce = web3.eth.get_transaction_count(address)
|
||||
return nonce
|
||||
|
||||
|
||||
def submit_transaction(
|
||||
web3: Web3, transaction: Dict[str, Any], signer_private_key: str
|
||||
) -> HexBytes:
|
||||
"""
|
||||
Signs and submits json transaction to blockchain from the name of signer
|
||||
"""
|
||||
signed_transaction = web3.eth.account.sign_transaction(
|
||||
transaction, private_key=signer_private_key
|
||||
)
|
||||
|
@ -44,7 +63,9 @@ def submit_transaction(
|
|||
def submit_signed_raw_transaction(
|
||||
web3: Web3, signed_raw_transaction: HexBytes
|
||||
) -> HexBytes:
|
||||
|
||||
"""
|
||||
Submits already signed raw transaction.
|
||||
"""
|
||||
transaction_hash = web3.eth.send_raw_transaction(signed_raw_transaction)
|
||||
return transaction_hash
|
||||
|
||||
|
@ -61,6 +82,16 @@ def deploy_contract(
|
|||
deployer_private_key: str,
|
||||
constructor_arguments: Optional[List[Any]] = None,
|
||||
) -> str:
|
||||
"""
|
||||
Deploys smart contract to blockchain
|
||||
Arguments:
|
||||
- web3: web3 client
|
||||
- contract_bytecode: Compiled smart contract bytecode
|
||||
- contract_abi: Json abi of contract. Must include `constructor` function
|
||||
- deployer: Address which is deploying contract. Deployer will pay transaction fee
|
||||
- deployer_private_key: Private key of deployer. Needed for signing and submitting transaction
|
||||
- constructor_arguments: arguments that are passed to `constructor` function of the smart contract
|
||||
"""
|
||||
contract = web3.eth.contract(abi=contract_abi, bytecode=contract_bytecode)
|
||||
transaction = build_transaction(
|
||||
web3, contract.constructor(*constructor_arguments), deployer
|
||||
|
@ -72,6 +103,11 @@ def deploy_contract(
|
|||
return contract_address
|
||||
|
||||
|
||||
def decode_transaction_input(web3: Web3, transaction_input: str, abi: Dict[str, Any]):
|
||||
contract = web3.eth.contract(abi=abi)
|
||||
return contract.decode_function_input(transaction_input)
|
||||
|
||||
|
||||
def read_keys_from_cli() -> Tuple[ChecksumAddress, str]:
|
||||
raw_address = input("Enter your ethereum address:")
|
||||
private_key = input("Enter private key of your address:")
|
||||
|
@ -86,33 +122,3 @@ def read_keys_from_env() -> Tuple[ChecksumAddress, str]:
|
|||
if raw_address is None:
|
||||
raise ValueError("CENTIPEDE_ETHEREUM_ADDRESS_PRIVATE_KEY is not set")
|
||||
return (Web3.toChecksumAddress(raw_address), private_key)
|
||||
|
||||
|
||||
def deploy_ERC1155(
|
||||
web3: Web3,
|
||||
token_name: str,
|
||||
token_symbol: str,
|
||||
token_uri: str,
|
||||
token_owner: ChecksumAddress,
|
||||
deployer: ChecksumAddress,
|
||||
deployer_private_key: str,
|
||||
) -> str:
|
||||
base_dir = os.path.dirname(__file__)
|
||||
contract_bytecode_path = os.path.join(base_dir, "fixture/bytecodes/ERC1155.bin")
|
||||
with open(contract_bytecode_path, "r") as ifp:
|
||||
contract_bytecode = ifp.read()
|
||||
|
||||
contract_abi_path = os.path.join(base_dir, "fixture/abis/ERC1155.json")
|
||||
with open(contract_abi_path, "r") as ifp:
|
||||
contract_abi = ifp.read()
|
||||
|
||||
contract_address = deploy_contract(
|
||||
web3,
|
||||
contract_bytecode,
|
||||
contract_abi,
|
||||
deployer,
|
||||
deployer_private_key,
|
||||
[token_name, token_symbol, token_uri, token_owner],
|
||||
)
|
||||
|
||||
return contract_address
|
||||
|
|
Ładowanie…
Reference in New Issue