pull/2/head
yhtiyar 2021-10-27 14:39:05 +03:00
rodzic 7fada297d2
commit 68e898142c
4 zmienionych plików z 140 dodań i 57 usunięć

Wyświetl plik

@ -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}")

Wyświetl plik

@ -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

Wyświetl plik

@ -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))

Wyświetl plik

@ -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