def setup_operator(self, number_owners: int = 1) -> SafeOperator: assert number_owners >= 1, 'Number of owners cannot be less than 1!' safe_address = self.deploy_test_safe(owners=[self.ethereum_test_account.address]).safe_address safe_operator = SafeOperator(safe_address, self.ethereum_node_url) safe_operator.load_cli_owners([self.ethereum_test_account.key.hex()]) for _ in range(number_owners - 1): account = Account.create() safe_operator.add_owner(account.address) safe_operator.load_cli_owners([account.key.hex()]) return safe_operator
def test_get_safe_creation_info(self): random_address = Account.create().address self.assertIsNone(self.safe_service.get_safe_creation_info(random_address)) InternalTxFactory(contract_address=random_address, ethereum_tx__status=0) self.assertIsNone(self.safe_service.get_safe_creation_info(random_address)) InternalTxFactory(contract_address=random_address, ethereum_tx__status=1) safe_creation_info = self.safe_service.get_safe_creation_info(random_address) self.assertIsInstance(safe_creation_info, SafeCreationInfo)
def get_pairing_mock_data(expiration_date: Optional[datetime] = None, another_device_account: Optional[Account] = None, device_account: Optional[Account] = None): """ Generates a dictionary data for pairing purposes """ expiration_date = expiration_date or isoformat_without_ms( (timezone.now() + timedelta(days=2))) another_device_account = another_device_account or Account.create() device_account = device_account or Account.create() return { "temporary_authorization": { "expiration_date": expiration_date, "signature": get_signature_json(expiration_date, another_device_account.key), }, "signature": get_signature_json(another_device_account.address, device_account.key) }
def createAccount(): print("\n ---------------- New account ----------------") entropy_label = input("Please, add an entropy label to create account: ") new_acct = Account.create(entropy_label) new_acct_address = new_acct.address new_private_key = new_acct.privateKey print('\nThe new account address is: {}'.format(new_acct_address)) print('The new private key is: {}'.format(new_private_key.hex())) txtGenerator(entropy_label, new_acct_address, new_private_key) print("\nThe file '01_Account_Info.txt' has been succesfully updated")
class ContractFactory(DjangoModelFactory): class Meta: model = Contract address = factory.LazyFunction(lambda: Account.create().address) name = factory.Faker("cryptocurrency_name") display_name = "" logo = factory.django.ImageField(color="green") contract_abi = factory.SubFactory(ContractAbiFactory) trusted_for_delegate_call = False
def reset_balances(address: str): accounts = web3.eth.accounts account1 = Account.create() accounts.append(account1) print(accounts) accounts = web3.eth.accounts print(accounts) # balance = contract.functions.editBalance(Web3.toChecksumAddress(account1), 100).transact() # balance = contract.functions.getBalance(Web3.toChecksumAddress(account1)).call() return {"ss": account1}
class InternalTxFactory(DjangoModelFactory): class Meta: model = InternalTx ethereum_tx = factory.SubFactory(EthereumTxFactory) _from = factory.LazyFunction(lambda: Account.create().address) gas = factory.fuzzy.FuzzyInteger(1000, 5000) data = factory.Sequence(lambda n: HexBytes('%x' % (n + 1000))) to = factory.LazyFunction(lambda: Account.create().address) value = factory.fuzzy.FuzzyInteger(0, 1000) gas_used = factory.fuzzy.FuzzyInteger(1000, 5000) contract_address = None code = None output = None refund_address = NULL_ADDRESS tx_type = EthereumTxType.CALL.value call_type = EthereumTxCallType.CALL.value trace_address = factory.Sequence(lambda n: str(n)) error = None
def _create_ethereum_private_key( private_key_file: str = ETHEREUM_PRIVATE_KEY_FILE, ) -> None: """ Create an ethereum private key. :return: None """ account = Account.create() with open(private_key_file, "w+") as file: file.write(account.key.hex())
class EthereumTxFactory(DjangoModelFactory): class Meta: model = EthereumTx block = factory.SubFactory(EthereumBlockFactory) tx_hash = factory.Sequence( lambda n: Web3.keccak(text=f"ethereum_tx_hash-{n}").hex() ) _from = factory.LazyFunction(lambda: Account.create().address) gas = factory.fuzzy.FuzzyInteger(1000, 5000) gas_price = factory.fuzzy.FuzzyInteger(1, 100) max_fee_per_gas = None max_priority_fee_per_gas = None data = factory.Sequence(lambda n: HexBytes("%x" % (n + 1000))) nonce = factory.Sequence(lambda n: n) to = factory.LazyFunction(lambda: Account.create().address) value = factory.fuzzy.FuzzyInteger(0, 1000) logs = factory.LazyFunction(lambda: []) type = 0
def keystore_file(tmp_path) -> str: filename = tmp_path / KEYSTORE_FILE_NAME account = Account.create() keystore_json = Account.encrypt(private_key=account.key, password=KEYSTORE_PASSWORD) with open(filename, mode="w", encoding="utf-8") as f: json.dump(keystore_json, f) return filename
def test_retrieve_modules(self): safe_creation = self.deploy_test_safe( owners=[self.ethereum_test_account.address]) safe = Safe(safe_creation.safe_address, self.ethereum_client) safe_contract = safe.get_contract() module_address = Account.create().address self.assertEqual(safe.retrieve_modules(), []) tx = safe_contract.functions.enableModule( module_address).buildTransaction({ 'from': self.ethereum_test_account.address, 'gas': 0, 'gasPrice': 0 }) safe_tx = safe.build_multisig_tx(safe.address, 0, tx['data']) safe_tx.sign(self.ethereum_test_account.key) safe_tx.execute(tx_sender_private_key=self.ethereum_test_account.key, tx_gas_price=self.gas_price) self.assertEqual(safe.retrieve_modules(), [module_address]) more_modules = [Account.create().address for _ in range(2)] for more_module in more_modules: # Test pagination tx = safe_contract.functions.enableModule( more_module).buildTransaction({ 'from': self.ethereum_test_account.address, 'gas': 0, 'gasPrice': 0 }) safe_tx = safe.build_multisig_tx(safe.address, 0, tx['data']) safe_tx.sign(self.ethereum_test_account.key) safe_tx.execute( tx_sender_private_key=self.ethereum_test_account.key, tx_gas_price=self.gas_price) self.assertCountEqual(safe.retrieve_modules(pagination=1), [module_address] + more_modules)
def generate_new_account(base_dir, chain_dir) -> None: click.echo("Starting to generate a new private key...") account = Account.create() password = read_encryption_password() trustlines_files = TrustlinesFiles( os.path.join(base_dir, PASSWORD_FILE_PATH), os.path.join(base_dir, ADDRESS_FILE_PATH), os.path.join(base_dir, KEY_DIR, chain_dir, KEYSTORE_FILE_NAME), ) trustlines_files.store(account, password)
def test_safe_master_copy_sorting(self): SafeMasterCopy.objects.create(address=Account.create().address, initial_block_number=3, tx_block_number=5) SafeMasterCopy.objects.create(address=Account.create().address, initial_block_number=2, tx_block_number=1) SafeMasterCopy.objects.create(address=Account.create().address, initial_block_number=6, tx_block_number=3) initial_block_numbers = [ safe_master_copy.initial_block_number for safe_master_copy in SafeMasterCopy.objects.all() ] self.assertEqual(initial_block_numbers, [2, 6, 3])
def main(args): acct = Account.create() f = open(args.filename, 'w') f.write(json.dumps({ "key": acct.privateKey.hex(), "address": acct.address })) f.close() print("Wrote private key with address %s to %s" % (acct.address, args.filename))
def test_sign_safe_tx(self): owners = [Account.create() for _ in range(3)] owners_unsorted = sorted(owners, key=lambda x: int(x.address, 16), reverse=True) owner_addresses = [owner.address for owner in owners_unsorted] threshold = 1 safe = self.deploy_test_safe( owners=owner_addresses, threshold=threshold, initial_funding_wei=self.w3.toWei(0.1, "ether"), ) to = Account().create().address value = self.w3.toWei(0.01, "ether") safe_tx = SafeTx( self.ethereum_client, safe.address, to, value, b"", 0, 200000, 100000, self.gas_price, None, None, safe_nonce=0, ) safe_tx.sign(owners_unsorted[0].key) safe_tx.sign(owners_unsorted[2].key) signers = [owner_addresses[0], owner_addresses[2]] self.assertEqual(safe_tx.signers, safe_tx.sorted_signers) self.assertNotEqual(signers, safe_tx.signers) self.assertEqual(set(signers), set(safe_tx.signers)) self.assertEqual(len(safe_tx.signers), 2) safe_tx.sign(owners_unsorted[1].key) signers = owner_addresses self.assertEqual(safe_tx.signers, safe_tx.sorted_signers) self.assertNotEqual(signers, safe_tx.signers) self.assertEqual(set(signers), set(safe_tx.signers)) self.assertEqual(len(safe_tx.signers), 3) # Sign again safe_tx.sign(owners_unsorted[0].key) self.assertEqual(len(safe_tx.signers), 3) # Sign again safe_tx.unsign(owners_unsorted[1].address) signers = [owner_addresses[0], owner_addresses[2]] self.assertEqual(set(signers), set(safe_tx.signers)) self.assertEqual(len(safe_tx.signers), 2)
def deploy_test_safe( self, number_owners: int = 3, threshold: Optional[int] = None, owners: Optional[List[ChecksumAddress]] = None, initial_funding_wei: int = 0, fallback_handler: ChecksumAddress = None, ) -> Safe: """ Deploy a Safe v1.3.0 :param number_owners: :param threshold: :param owners: :param initial_funding_wei: :param fallback_handler: :return: """ fallback_handler = (fallback_handler or self.compatibility_fallback_handler.address) owners = (owners if owners else [Account.create().address for _ in range(number_owners)]) if not threshold: threshold = len(owners) - 1 if len(owners) > 1 else 1 empty_parameters = {"gas": 1, "gasPrice": 1} to = NULL_ADDRESS data = b"" payment_token = NULL_ADDRESS payment = 0 payment_receiver = NULL_ADDRESS initializer = HexBytes( self.safe_contract.functions.setup( owners, threshold, to, data, fallback_handler, payment_token, payment, payment_receiver, ).buildTransaction(empty_parameters)["data"]) ethereum_tx_sent = self.proxy_factory.deploy_proxy_contract( self.ethereum_test_account, self.safe_contract.address, initializer=initializer, ) safe = Safe(ethereum_tx_sent.contract_address, self.ethereum_client) if initial_funding_wei: self.send_ether(safe.address, initial_funding_wei) self.assertEqual(safe.retrieve_version(), "1.3.0") self.assertEqual(safe.retrieve_threshold(), threshold) self.assertCountEqual(safe.retrieve_owners(), owners) return safe
def test_pairing_deletion(self): another_device_account = Account.create() device_account = Account.create() device_2_account = Account.create() pairing_data = get_pairing_mock_data( another_device_account=another_device_account, device_account=device_account) pairing_data_2 = get_pairing_mock_data( another_device_account=device_2_account, device_account=device_account) DeviceFactory(owner=device_account.address) DeviceFactory(owner=another_device_account.address) DeviceFactory(owner=device_2_account.address) for pairing in (pairing_data, pairing_data_2): response = self.client.post(reverse('v1:pairing'), data=pairing, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) deletion_data = { 'device': another_device_account.address, 'signature': get_signature_json(another_device_account.address, device_account.key) } response = self.client.delete(reverse('v1:pairing'), data=deletion_data, format='json') self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual( DevicePair.objects.filter( authorizing_device__owner=device_account.address).count(), 1) self.assertEqual( DevicePair.objects.filter( authorized_device__owner=device_account.address).count(), 1)
def test_safe_cli_happy_path(self): accounts = [self.ethereum_test_account, Account.create()] account_addresses = [account.address for account in accounts] safe_address = self.deploy_test_safe(owners=account_addresses, threshold=2, initial_funding_wei=self.w3.toWei(1, 'ether')).safe_address safe = Safe(safe_address, self.ethereum_client) safe_operator = SafeOperator(safe_address, self.ethereum_node_url) prompt_parser = PromptParser(safe_operator) random_address = Account.create().address self.assertEqual(safe_operator.accounts, set()) prompt_parser.process_command(f'load_cli_owners {self.ethereum_test_account.key.hex()}') self.assertEqual(safe_operator.default_sender, self.ethereum_test_account) self.assertEqual(safe_operator.accounts, {self.ethereum_test_account}) prompt_parser.process_command(f'send_ether {random_address} 1') # No enough signatures self.assertEqual(self.ethereum_client.get_balance(random_address), 0) value = 123 prompt_parser.process_command(f'load_cli_owners {accounts[1].key.hex()}') prompt_parser.process_command(f'send_ether {random_address} {value}') self.assertEqual(self.ethereum_client.get_balance(random_address), value) # Change threshold self.assertEqual(safe_operator.safe_cli_info.threshold, 2) self.assertEqual(safe.retrieve_threshold(), 2) prompt_parser.process_command('change_threshold 1') self.assertEqual(safe_operator.safe_cli_info.threshold, 1) self.assertEqual(safe.retrieve_threshold(), 1) # Approve Hash safe_tx_hash = Web3.keccak(text='hola') self.assertFalse(safe_operator.safe.retrieve_is_hash_approved(accounts[0].address, safe_tx_hash)) prompt_parser.process_command(f'approve_hash {safe_tx_hash.hex()} {accounts[0].address}') self.assertTrue(safe_operator.safe.retrieve_is_hash_approved(accounts[0].address, safe_tx_hash)) # Remove owner self.assertEqual(len(safe_operator.safe_cli_info.owners), 2) self.assertEqual(len(safe.retrieve_owners()), 2) prompt_parser.process_command(f'remove_owner {accounts[1].address}') self.assertEqual(safe_operator.safe_cli_info.owners, [self.ethereum_test_account.address]) self.assertEqual(safe.retrieve_owners(), [self.ethereum_test_account.address])
class WebHookFactory(factory.DjangoModelFactory): class Meta: model = WebHook address = factory.LazyFunction(lambda: Account.create().address) url = 'http://localhost/test' # Configurable webhook types to listen to new_confirmation = True pending_outgoing_transaction = True new_executed_outgoing_transaction = True new_incoming_transaction = True
class MultisigConfirmationFactory(factory.DjangoModelFactory): class Meta: model = MultisigConfirmation ethereum_tx = factory.SubFactory(EthereumTxFactory) multisig_transaction = factory.SubFactory(MultisigTransaction) multisig_transaction_hash = factory.Sequence( lambda n: Web3.keccak(text=f'multisig-confirmation-tx-{n}').hex()) owner = factory.LazyFunction(lambda: Account.create().address) signature = None signature_type = SafeSignatureType.APPROVED_HASH.value
class MultisigTransactionFactory(factory.DjangoModelFactory): class Meta: model = MultisigTransaction safe_tx_hash = factory.Sequence( lambda n: Web3.keccak(text=f'multisig-tx-{n}').hex()) safe = factory.LazyFunction(lambda: Account.create().address) ethereum_tx = factory.SubFactory(EthereumTxFactory) to = factory.LazyFunction(lambda: Account.create().address) value = FuzzyInteger(low=0, high=10) data = b'' operation = FuzzyInteger(low=0, high=2) safe_tx_gas = FuzzyInteger(low=400000, high=500000) base_gas = FuzzyInteger(low=200000, high=300000) gas_price = FuzzyInteger(low=1, high=10) gas_token = NULL_ADDRESS refund_receiver = NULL_ADDRESS signatures = b'' nonce = factory.Sequence(lambda n: n) origin = factory.Faker('name')
def test_get_safe_info(self): safe_address = Account.create().address with self.assertRaises(CannotGetSafeInfo): self.safe_service.get_safe_info(safe_address) safe_create_tx = self.deploy_test_safe() safe_info = self.safe_service.get_safe_info(safe_create_tx.safe_address) self.assertIsInstance(safe_info, SafeInfo) self.assertEqual(safe_info.address, safe_create_tx.safe_address) self.assertEqual(safe_info.owners, safe_create_tx.owners) self.assertEqual(safe_info.threshold, safe_create_tx.threshold)
def test_process_decoded_internal_txs_task(self): owner = Account.create().address safe_address = Account.create().address fallback_handler = Account.create().address master_copy = Account.create().address threshold = 1 InternalTxDecodedFactory(function_name='setup', owner=owner, threshold=threshold, fallback_handler=fallback_handler, internal_tx__to=master_copy, internal_tx___from=safe_address) process_decoded_internal_txs_task.delay() self.assertTrue(SafeContract.objects.get(address=safe_address)) safe_status = SafeStatus.objects.get(address=safe_address) self.assertEqual(safe_status.enabled_modules, []) self.assertEqual(safe_status.fallback_handler, fallback_handler) self.assertEqual(safe_status.master_copy, master_copy) self.assertEqual(safe_status.owners, [owner]) self.assertEqual(safe_status.threshold, threshold)
def test_get_safe_creation_info(self): random_address = Account.create().address self.assertIsNone(self.safe_service.get_safe_creation_info(random_address)) InternalTxFactory(contract_address=random_address, ethereum_tx__status=0) self.assertIsNone(self.safe_service.get_safe_creation_info(random_address)) with mock.patch.object(ParityManager, 'trace_transaction', autospec=True, return_value=[create_trace]): InternalTxFactory(contract_address=random_address, ethereum_tx__status=1, trace_address='0') safe_creation_info = self.safe_service.get_safe_creation_info(random_address) self.assertIsInstance(safe_creation_info, SafeCreationInfo)
def test_get_safe_creation_info_with_next_trace(self, trace_transaction_mock: MagicMock): random_address = Account.create().address InternalTxFactory(contract_address=random_address, ethereum_tx__status=1, trace_address='') safe_creation_info = self.safe_service.get_safe_creation_info(random_address) self.assertIsInstance(safe_creation_info, SafeCreationInfo) self.assertEqual(safe_creation_info.master_copy, '0x8942595A2dC5181Df0465AF0D7be08c8f23C93af') self.assertTrue(safe_creation_info.setup_data) trace_transaction_mock.return_value = [] safe_creation_info = self.safe_service.get_safe_creation_info(random_address) self.assertIsNone(safe_creation_info.master_copy) self.assertIsNone(safe_creation_info.setup_data)
def build_test_safe(self, number_owners: int = 3, threshold: Optional[int] = None, owners: Optional[List[str]] = None, fallback_handler: Optional[str] = None) -> SafeCreate2Tx: salt_nonce = generate_salt_nonce() owners = owners if owners else [Account.create().address for _ in range(number_owners)] threshold = threshold if threshold else len(owners) - 1 gas_price = self.ethereum_client.w3.eth.gasPrice return Safe.build_safe_create2_tx(self.ethereum_client, self.safe_contract_address, self.proxy_factory_contract_address, salt_nonce, owners, threshold, fallback_handler=fallback_handler, gas_price=gas_price, payment_token=None, fixed_creation_cost=0)
class EthereumEventFactory(factory.DjangoModelFactory): class Meta: model = EthereumEvent class Params: to = None from_ = None erc721 = False value = 1200 ethereum_tx = factory.SubFactory(EthereumTxFactory) log_index = factory.Sequence(lambda n: n) token_address = factory.LazyFunction(lambda: Account.create().address) topic = ERC20_721_TRANSFER_TOPIC arguments = factory.LazyAttribute( lambda o: { 'to': o.to if o.to else Account.create().address, 'from': o.from_ if o.from_ else Account.create().address, 'tokenId' if o.erc721 else 'value': o.value })
def test_add_token(self): token = TokenFactory() buf = StringIO() call_command("add_token", token.address, stdout=buf) self.assertIn("already exists", buf.getvalue()) ethereum_client = EthereumClientProvider() erc20 = deploy_example_erc20(ethereum_client.w3, 10, Account.create().address) call_command("add_token", erc20.address, "--no-prompt", stdout=buf) self.assertIn("Created token", buf.getvalue())
def test_get_module_transactions(self): safe_address = Account.create().address response = self.client.get(reverse('v1:module-transactions', args=(safe_address,)), format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) module_transaction = ModuleTransactionFactory(safe=safe_address) response = self.client.get(reverse('v1:module-transactions', args=(safe_address,)), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['count'], 1) self.assertEqual(response.data['results'][0]['safe'], module_transaction.safe) self.assertEqual(response.data['results'][0]['module'], module_transaction.module)
def test_check_and_update_pending_transactions(self): SafeMultisigTxFactory(created=timezone.now() - timedelta(seconds=151), ethereum_tx__block=None) self.assertEqual(check_and_update_pending_transactions.delay().get(), 0) tx_hash = self.send_ether(Account.create().address, 1) SafeMultisigTxFactory(created=timezone.now() - timedelta(seconds=151), ethereum_tx__tx_hash=tx_hash, ethereum_tx__block=None) self.assertEqual(check_and_update_pending_transactions.delay().get(), 1) self.assertGreaterEqual(EthereumTx.objects.get(tx_hash=tx_hash).block_id, 0)