Example #1
0
    def perform_tx():
        op = dbsession.query(CryptoOperation).get(opid)
        # Check everyting looks sane
        assert op.crypto_account.id
        assert op.crypto_account.account.id

        asset = op.holding_account.asset
        assert asset.id

        # Set information on asset that we have now created and have its smart contract id
        assert not asset.external_id, "Asset has been already assigned its smart contract id. Recreate error?"

        address = bin_to_eth_address(op.crypto_account.address.address)

        # Create Tonex proxy object
        token = Token.create_token(web3, name=asset.name, symbol=asset.symbol, supply=asset.supply, owner=address)

        # Call geth RPC API over Populus contract proxy
        op.txid = txid_to_bin(token.initial_txid)
        op.block = None
        op.external_address = eth_address_to_bin(token.address)

        asset.external_id = op.external_address

        op.mark_performed()
        op.mark_broadcasted()
Example #2
0
    def perform_tx():
        op = dbsession.query(CryptoOperation).get(opid)
        # Check everyting looks sane
        assert op.crypto_account.id
        assert op.crypto_account.account.id

        asset = op.holding_account.asset
        assert asset.id

        # Set information on asset that we have now created and have its smart contract id
        assert not asset.external_id, "Asset has been already assigned its smart contract id. Recreate error?"

        address = bin_to_eth_address(op.crypto_account.address.address)

        # Create Tonex proxy object
        token = Token.create_token(web3,
                                   name=asset.name,
                                   symbol=asset.symbol,
                                   supply=asset.supply,
                                   owner=address)

        # Call geth RPC API over Populus contract proxy
        op.txid = txid_to_bin(token.initial_txid)
        op.block = None
        op.external_address = eth_address_to_bin(token.address)

        asset.external_id = op.external_address

        op.mark_performed()
        op.mark_broadcasted()
Example #3
0
 def setup_listeners(self):
     """Setup subsystems that scan for incoming events from geth."""
     wallet_contract = HostedWallet.contract_class(self.web3)
     token_contract = Token.contract_class(self.web3)
     self.eth_wallet_listener = EthWalletListener(self.web3, wallet_contract, self.dbsession, self.asset_network_id, registry=self.registry)
     self.eth_token_listener = EthTokenListener(self.web3, token_contract, self.dbsession, self.asset_network_id, registry=self.registry)
     self.confirmation_updater = DatabaseConfirmationUpdater(self.web3, self.dbsession, self.asset_network_id, self.registry)
     self.op_queue_manager = OperationQueueManager(self.web3, self.dbsession, self.asset_network_id, self.registry)
def test_starter_token(dbsession, registry, eth_network_id, web3: Web3, eth_service: EthereumService, house_address, toybox):
    """See that a fresh user account is supplied with some play assets."""

    with transaction.manager:
        user = create_user(dbsession, registry)
        setup_user_account(user)

    # Let all the events completed
    success, fail = eth_service.run_event_cycle()
    assert success == 1
    assert fail == 0

    # We need another event cycle to process the initial asset transfers
    with transaction.manager:
        user = dbsession.query(User).first()
        opid = user.user_data["starter_asset_txs"][0]["toybox"]
        assert opid

    wait_for_op_confirmations(eth_service, opid)

    # Let the transfer come through
    eth_service.run_event_cycle()

    # Make sure we confirm the deposit
    with transaction.manager:
        user = dbsession.query(User).first()
        user_depo = user.owned_crypto_operations.join(CryptoOperation).filter_by(operation_type=CryptoOperationType.deposit).first()
        opid = user_depo.crypto_operation.id

    wait_for_op_confirmations(eth_service, opid)

    with transaction.manager:

        # Sanity check our token contract posts us logs
        user = dbsession.query(User).first()
        client = get_rpc_client(web3)
        asset = dbsession.query(Asset).get(toybox)
        address = bin_to_eth_address(asset.external_id)
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        user_address = UserCryptoAddress.get_default(user, network).address
        house_address = dbsession.query(CryptoAddress).get(house_address)
        house = bin_to_eth_address(house_address.address)
        token = Token.get(web3, address)

        # Check we correctly resolved low level logs
        token_logs = client.get_logs(from_block=0, address=[address])
        wallet_logs = client.get_logs(from_block=0, address=[house])
        assert len(token_logs) > 0
        assert len(wallet_logs) > 0

        # Check contract state matches
        assert token.contract.call().balanceOf(house) == 9990
        assert token.contract.call().balanceOf(bin_to_eth_address(user_address.address)) == 10

        # Check our internal book keeping matches
        assert house_address.get_account(asset).account.get_balance() == 9990
        assert user_address.get_account(asset).account.get_balance() == 10
def test_withdraw_token(dbsession, eth_network_id, web3: Web3, eth_service: EthereumService, deposit_address: str, token_asset: str, target_account: str):
    """"See that we can withdraw token outside to an account."""

    with transaction.manager:
        address = dbsession.query(CryptoAddress).filter_by(address=eth_address_to_bin(deposit_address)).one()
        asset = dbsession.query(Asset).get(token_asset)
        caccount = address.get_account(asset)

        op = caccount.withdraw(Decimal(2000), eth_address_to_bin(target_account), "Sending to friend")
        opid = op.id

        assert caccount.account.get_balance() == 8000

    # Run import token operation
    success_count, failure_count = eth_service.run_waiting_operations()
    assert success_count == 1
    assert failure_count == 0

    # TX was broadcasted, marked as complete
    with transaction.manager:
        op = dbsession.query(CryptoOperation).get(opid)
        assert isinstance(op, CryptoAddressWithdraw)
        asset = dbsession.query(Asset).get(token_asset)
        assert op.broadcasted_at
        assert not op.completed_at

    wait_for_op_confirmations(eth_service, opid)

    # After tx has been mined the new balances should match
    with transaction.manager:
        op = dbsession.query(CryptoOperation).get(opid)
        assert op.broadcasted_at
        assert op.completed_at
        asset = dbsession.query(Asset).get(token_asset)

        # Tokens have been removed on from account
        token = Token.get(web3, bin_to_eth_address(asset.external_id))
        assert token.contract.call().balanceOf(deposit_address) == 8000

        # Tokens have been credited on to account
        token = Token.get(web3, bin_to_eth_address(asset.external_id))
        assert token.contract.call().balanceOf(target_account) == 2000
Example #6
0
    def perform_tx():
        op = dbsession.query(CryptoOperation).get(opid)
        address = bin_to_eth_address(op.external_address)
        token = Token.get(web3, address)

        network = op.network

        def gen_error(e: Exception):
            # Set operation as impossible to complete
            # Set user readable and technical error explanation
            op.mark_failed()
            op.other_data[
                "error"] = "Address did not provide EIP-20 token API:" + address
            op.other_data["exception"] = str(e)
            logger.exception(e)

        try:
            name = token.contract.call().name()
            symbol = token.contract.call().symbol()
            supply = Decimal(token.contract.call().totalSupply())
        except BadFunctionCallOutput as e:
            # When we try to access a contract attrib which is not supported by underlying code
            gen_error(e)
            return

        asset = network.create_asset(name=name,
                                     symbol=symbol,
                                     supply=supply,
                                     asset_class=AssetClass.token)
        asset.external_id = op.external_address

        # Fill in balances for the addresses we host
        # TODO: Too much for one transaction
        for caddress in dbsession.query(CryptoAddress).all():

            # Returns 0 for unknown addresses
            try:
                amount = token.contract.call().balanceOf(
                    bin_to_eth_address(caddress.address))
            except BadFunctionCallOutput as e:
                # Bad contract doesn't define balanceOf()
                # This leaves badly imported asset
                gen_error(e)
                return

            if amount > 0:
                account = caddress.get_or_create_account(asset)
                account.account.do_withdraw_or_deposit(
                    Decimal(amount), "Token contract import")

        # This operation immediately closes
        op.mark_performed()
        op.mark_broadcasted()
        op.mark_complete()
Example #7
0
    def setup_listeners(self):
        """Setup subsystems that scan for incoming events from geth."""
        wallet_contract = HostedWallet.contract_class(self.web3)
        token_contract = Token.contract_class(self.web3)

        self.eth_wallet_listener = EthWalletListener(self.web3, wallet_contract, self.dbsession, self.asset_network_id, registry=self.registry)

        self.eth_token_listener = EthTokenListener(self.web3, token_contract, self.dbsession, self.asset_network_id, registry=self.registry)

        self.confirmation_updater = DatabaseConfirmationUpdater(self.web3, self.dbsession, self.asset_network_id, self.registry)
        self.op_queue_manager = OperationQueueManager(self.web3, self.dbsession, self.asset_network_id, self.registry)
def test_withdraw_token(dbsession, eth_network_id, web3: Web3, eth_service: EthereumService, deposit_address: str, token_asset: str, target_account: str):
    """"See that we can withdraw token outside to an account."""

    with transaction.manager:
        address = dbsession.query(CryptoAddress).filter_by(address=eth_address_to_bin(deposit_address)).one()
        asset = dbsession.query(Asset).get(token_asset)
        caccount = address.get_account(asset)

        op = caccount.withdraw(Decimal(2000), eth_address_to_bin(target_account), "Sending to friend")
        opid = op.id

        assert caccount.account.get_balance() == 8000

    # Run import token operation
    success_count, failure_count = eth_service.run_waiting_operations()
    assert success_count == 1
    assert failure_count == 0

    # TX was broadcasted, marked as complete
    with transaction.manager:
        op = dbsession.query(CryptoOperation).get(opid)
        assert isinstance(op, CryptoAddressWithdraw)
        asset = dbsession.query(Asset).get(token_asset)
        assert op.broadcasted_at
        assert not op.completed_at

    wait_for_op_confirmations(eth_service, opid)

    with transaction.manager:
        op = dbsession.query(CryptoOperation).get(opid)
        assert op.broadcasted_at
        assert op.completed_at
        asset = dbsession.query(Asset).get(token_asset)

        # Tokens have been removed on from account
        token = Token.get(web3, bin_to_eth_address(asset.external_id))
        assert token.contract.call().balanceOf(deposit_address) == 8000

        # Tokens have been credited on to account
        token = Token.get(web3, bin_to_eth_address(asset.external_id))
        assert token.contract.call().balanceOf(target_account) == 2000
Example #9
0
def token(dbsession, web3, eth_service, eth_network_id) -> Callable:
    # signer, multisig, cap
    extra_arguments = [
        web3.eth.coinbase,
        "0x8f480474b014ea63d4fe5e52478e833fb9e8f938",  # Mikko's testnet address
        to_wei(6000, "ether"),
        2,  # 2 share per each ETH
        10**18,  # 1 ETH 10**18 wei
    ]

    token = Token.create_token(web3, name="Toycrowd", supply=0, symbol="TOYCROWD", owner=web3.eth.coinbase, extra_arguments=extra_arguments, contract_name="CrowdfundToken")

    print("Token deployed")

    return token
Example #10
0
    def perform_tx():
        op = dbsession.query(CryptoOperation).get(opid)
        address = bin_to_eth_address(op.external_address)
        token = Token.get(web3, address)

        network = op.network

        def gen_error(e: Exception):
            # Set operation as impossible to complete
            # Set user readable and technical error explanation
            op.mark_failed()
            op.other_data["error"] = "Address did not provide EIP-20 token API:" + address
            op.other_data["exception"] = str(e)
            logger.exception(e)

        try:
            name = token.contract.call().name()
            symbol = token.contract.call().symbol()
            supply = Decimal(token.contract.call().totalSupply())
        except eth_abi.exceptions.DecodingError as e:
            # When we try to access a contract attrib which is not supported by underlying code
            gen_error(e)
            return

        asset = network.create_asset(name=name, symbol=symbol, supply=supply, asset_class=AssetClass.token)
        asset.external_id = op.external_address

        # Fill in balances for the addresses we host
        # TODO: Too much for one transaction
        for caddress in dbsession.query(CryptoAddress).all():

            # Returns 0 for unknown addresses
            try:
                amount = token.contract.call().balanceOf(bin_to_eth_address(caddress.address))
            except eth_abi.exceptions.DecodingError as e:
                # Bad contract doesn't define balanceOf()
                # This leaves badly imported asset
                gen_error(e)
                return

            if amount > 0:
                account = caddress.get_or_create_account(asset)
                account.account.do_withdraw_or_deposit(Decimal(amount), "Token contract import")

        # This operation immediately closes
        op.mark_performed()
        op.mark_broadcasted()
        op.mark_complete()
def test_deposit_token(dbsession, eth_network_id, web3: Web3, eth_service: EthereumService, coinbase: str, deposit_address: str, token: Token):
    """"See that we can deposit tokens to accounts."""

    # Import a contract where coinbase has all balance
    with transaction.manager:
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        import_token(network, eth_address_to_bin(token.address))

    # Run import token operation
    success_count, failure_count = eth_service.run_waiting_operations()
    assert success_count == 1
    assert failure_count == 0

    # Coinbase transfers token balance to deposit address
    txid = token.transfer(deposit_address, Decimal(4000))
    confirm_transaction(web3, txid)

    # We should pick up incoming deposit
    success_count, failure_count = eth_service.run_listener_operations()
    assert success_count == 1
    assert failure_count == 0

    # Check that data is setup correctly on incoming transaction
    with transaction.manager:
        op = dbsession.query(CryptoOperation).all()[-1]
        opid = op.id
        assert not op.completed_at
        address = dbsession.query(CryptoAddress).filter_by(address=eth_address_to_bin(deposit_address)).one()
        asset = op.holding_account.asset
        assert op.holding_account.get_balance() == 4000
        assert op.completed_at is None
        assert address.get_account(asset).account.get_balance() == 0  # Not credited until confirmations reached
        assert address.crypto_address_accounts.count() == 1

    # Wait the token transaction to get enough confirmations
    wait_for_op_confirmations(eth_service, opid)

    # Check that the transaction is not final
    with transaction.manager:
        op = dbsession.query(CryptoOperation).get(opid)
        assert op.completed_at
        assert op.completed_at
        address = dbsession.query(CryptoAddress).filter_by(address=eth_address_to_bin(deposit_address)).one()
        asset = op.holding_account.asset
        assert op.holding_account.get_balance() == 0
        assert address.get_account(asset).account.get_balance() == 4000
        assert op.state == CryptoOperationState.success
def test_deposit_token(dbsession, eth_network_id, web3: Web3, eth_service: EthereumService, coinbase: str, deposit_address: str, token: Token):
    """"See that we can deposit tokens to accounts."""

    # Import a contract where coinbase has all balance
    with transaction.manager:
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        import_token(network, eth_address_to_bin(token.address))

    # Run import token operation
    success_count, failure_count = eth_service.run_waiting_operations()
    assert success_count == 1
    assert failure_count == 0

    # Coinbase transfers token balance to deposit address
    txid = token.transfer(deposit_address, Decimal(4000))
    confirm_transaction(web3, txid)

    # We should pick up incoming deposit
    success_count, failure_count = eth_service.run_listener_operations()
    assert success_count == 1
    assert failure_count == 0

    # Check that data is setup correctly on incoming transaction
    with transaction.manager:
        op = dbsession.query(CryptoOperation).all()[-1]
        opid = op.id
        assert not op.completed_at
        address = dbsession.query(CryptoAddress).filter_by(address=eth_address_to_bin(deposit_address)).one()
        asset = op.holding_account.asset
        assert op.holding_account.get_balance() == 4000
        assert op.completed_at is None
        assert address.get_account(asset).account.get_balance() == 0  # Not credited until confirmations reached
        assert address.crypto_address_accounts.count() == 1

    # Wait the token transaction to get enough confirmations
    wait_for_op_confirmations(eth_service, opid)

    # Check that the transaction is not final
    with transaction.manager:
        op = dbsession.query(CryptoOperation).get(opid)
        assert op.completed_at
        assert op.completed_at
        address = dbsession.query(CryptoAddress).filter_by(address=eth_address_to_bin(deposit_address)).one()
        asset = op.holding_account.asset
        assert op.holding_account.get_balance() == 0
        assert address.get_account(asset).account.get_balance() == 4000
        assert op.state == CryptoOperationState.success
def token(web3, coinbase) -> Contract:
    """Deploy a token contract in the blockchain."""

    # signer, multisig, cap
    extra_arguments = [
        coinbase,
        MULTISIG,
        CAP,
        2,  # 2 share per each ETH
        10**18,  # 1 ETH 10**18 wei
    ]
    return Token.create_token(web3,
                              name="Mootoken",
                              supply=0,
                              symbol="MOO",
                              owner=coinbase,
                              extra_arguments=extra_arguments,
                              contract_name="CrowdfundToken")
Example #14
0
def withdraw_token(web3: Web3, dbsession: Session, opid: UUID):
    """Perform token withdraw operation from the wallet."""

    @retryable(tm=dbsession.transaction_manager)
    def prepare_withdraw():
        # Check everyting looks sane
        op = dbsession.query(CryptoOperation).get(opid)
        assert op.crypto_account.id
        assert op.crypto_account.account.id
        assert op.holding_account.id
        assert op.holding_account.get_balance() > 0
        assert op.external_address
        assert op.required_confirmation_count  # Should be set by the creator
        asset = op.holding_account.asset
        assert asset.asset_class == AssetClass.token

        from_address = bin_to_eth_address(op.crypto_account.address.address)
        to_address = bin_to_eth_address(op.external_address)
        asset_address = bin_to_eth_address(asset.external_id)

        # How much we are withdrawing
        amount = op.holding_account.transactions.one().amount
        op.mark_performed()  # Don't try to pick this op automatically again
        return from_address, to_address, asset_address, amount

    @retryable(tm=dbsession.transaction_manager)
    def close_withdraw():
        # Fill in details.
        # Block number will be filled in later, when confirmation updater picks a transaction receipt for this operation.
        op = dbsession.query(CryptoOperation).get(opid)
        op.txid = txid_to_bin(txid)
        op.block = None
        op.mark_broadcasted()

    from_address, to_address, asset_address, amount = prepare_withdraw()
    wallet = HostedWallet.get(web3, from_address)
    token = Token.get(web3, asset_address)
    amount = token.validate_transfer_amount(amount)
    # Perform actual transfer outside retryable transaction
    # boundaries to avoid double withdrwa
    txid = wallet.execute(token.contract, "transfer", [to_address, amount])
    close_withdraw()
Example #15
0
def withdraw_token(web3: Web3, dbsession: Session, opid: UUID):
    """Perform token withdraw operation from the wallet."""
    @retryable(tm=dbsession.transaction_manager)
    def prepare_withdraw():
        # Check everyting looks sane
        op = dbsession.query(CryptoOperation).get(opid)
        assert op.crypto_account.id
        assert op.crypto_account.account.id
        assert op.holding_account.id
        assert op.holding_account.get_balance() > 0
        assert op.external_address
        assert op.required_confirmation_count  # Should be set by the creator
        asset = op.holding_account.asset
        assert asset.asset_class == AssetClass.token

        from_address = bin_to_eth_address(op.crypto_account.address.address)
        to_address = bin_to_eth_address(op.external_address)
        asset_address = bin_to_eth_address(asset.external_id)

        # How much we are withdrawing
        amount = op.holding_account.transactions.one().amount
        op.mark_performed()  # Don't try to pick this op automatically again
        return from_address, to_address, asset_address, amount

    @retryable(tm=dbsession.transaction_manager)
    def close_withdraw():
        # Fill in details.
        # Block number will be filled in later, when confirmation updater picks a transaction receipt for this operation.
        op = dbsession.query(CryptoOperation).get(opid)
        op.txid = txid_to_bin(txid)
        op.block = None
        op.mark_broadcasted()

    from_address, to_address, asset_address, amount = prepare_withdraw()
    wallet = HostedWallet.get(web3, from_address)
    token = Token.get(web3, asset_address)
    amount = token.validate_transfer_amount(amount)
    # Perform actual transfer outside retryable transaction
    # boundaries to avoid double withdrwa
    txid = wallet.execute(token.contract, "transfer", [to_address, amount])
    close_withdraw()
def test_import_token(dbsession, eth_network_id, web3: Web3, eth_service: EthereumService, coinbase: str, deposit_address: str, token: Token):
    """Import an existing smart contract token to system."""

    # Make sure we have an address that holds some of the tokens so it is cleared up during import
    txid = token.transfer(deposit_address, Decimal(4000))
    confirm_transaction(web3, txid)

    with transaction.manager:

        network = dbsession.query(AssetNetwork).get(eth_network_id)
        op = import_token(network, eth_address_to_bin(token.address))
        opid = op.id

        # Let's create another address that doesn't hold tokens
        # and see that import doesn't fail for it
        addr = CryptoAddress(network=network, address=eth_address_to_bin("0x2f70d3d26829e412a602e83fe8eebf80255aeea5"))
        dbsession.add(addr)

    success_count, failure_count = eth_service.run_waiting_operations()
    assert success_count == 1
    assert failure_count == 0

    # Check that we created a new asset and its imports where fulfilled
    with transaction.manager:

        op = dbsession.query(CryptoOperation).get(opid)
        assert op.completed_at

        # We got account with tokens on it
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        caddress = CryptoAddress.get_network_address(network, eth_address_to_bin(deposit_address))

        asset = network.assets.filter_by(external_id=eth_address_to_bin(token.address)).one()
        assert asset.name == "Mootoken"
        assert asset.symbol == "MOO"
        assert asset.supply == 10000

        caccount = caddress.get_account_by_address(eth_address_to_bin(token.address))
        assert caccount.account.get_balance() == 4000
def test_import_token(dbsession, eth_network_id, web3: Web3, eth_service: EthereumService, coinbase: str, deposit_address: str, token: Token):
    """Import an existing smart contract token to system."""

    # Make sure we have an address that holds some of the tokens so it is cleared up during import
    txid = token.transfer(deposit_address, Decimal(4000))
    confirm_transaction(web3, txid)

    with transaction.manager:

        network = dbsession.query(AssetNetwork).get(eth_network_id)
        op = import_token(network, eth_address_to_bin(token.address))
        opid = op.id

        # Let's create another address that doesn't hold tokens
        # and see that import doesn't fail for it
        addr = CryptoAddress(network=network, address=eth_address_to_bin("0x2f70d3d26829e412a602e83fe8eebf80255aeea5"))
        dbsession.add(addr)

    success_count, failure_count = eth_service.run_waiting_operations()
    assert success_count == 1
    assert failure_count == 0

    # Check that we created a new asset and its imports where fulfilled
    with transaction.manager:

        op = dbsession.query(CryptoOperation).get(opid)
        assert op.completed_at

        # We got account with tokens on it
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        caddress = CryptoAddress.get_network_address(network, eth_address_to_bin(deposit_address))

        asset = network.assets.filter_by(external_id=eth_address_to_bin(token.address)).one()
        assert asset.name == "Mootoken"
        assert asset.symbol == "MOO"
        assert asset.supply == 10000

        caccount = caddress.get_account_by_address(eth_address_to_bin(token.address))
        assert caccount.account.get_balance() == 4000
Example #18
0
def token(web3, coinbase) -> Contract:
    """Deploy a token contract in the blockchain."""
    return Token.create_token(web3, name="Mootoken", supply=10000, symbol="MOO", owner=coinbase)
Example #19
0
def test_starter_token(dbsession, registry, eth_network_id, web3: Web3,
                       eth_service: EthereumService, house_address, toybox):
    """See that a fresh user account is supplied with some play assets."""

    with transaction.manager:
        user = create_user(dbsession, registry)
        setup_user_account(user, do_mainnet=True)

    # Let all the events completed
    success, fail = eth_service.run_event_cycle()
    assert success == 1
    assert fail == 0

    # We need another event cycle to process the initial asset transfers
    with transaction.manager:
        user = dbsession.query(User).first()
        opid = user.user_data["starter_asset_txs"][0]["toybox"]
        assert opid

    wait_for_op_confirmations(eth_service, opid)

    # Let the transfer come through
    eth_service.run_event_cycle()

    # Make sure we confirm the deposit
    with transaction.manager:
        user = dbsession.query(User).first()
        user_depo = user.owned_crypto_operations.join(
            CryptoOperation).filter_by(
                operation_type=CryptoOperationType.deposit).first()
        opid = user_depo.crypto_operation.id

    wait_for_op_confirmations(eth_service, opid)

    with transaction.manager:

        # Sanity check our token contract posts us logs
        user = dbsession.query(User).first()
        client = get_rpc_client(web3)
        asset = dbsession.query(Asset).get(toybox)
        address = bin_to_eth_address(asset.external_id)
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        user_address = UserCryptoAddress.get_default(user, network).address
        house_address = dbsession.query(CryptoAddress).get(house_address)
        house = bin_to_eth_address(house_address.address)
        token = Token.get(web3, address)

        # Check we correctly resolved low level logs
        token_logs = client.get_logs(from_block=0, address=[address])
        wallet_logs = client.get_logs(from_block=0, address=[house])
        assert len(token_logs) > 0
        assert len(wallet_logs) > 0

        # Check contract state matches
        assert token.contract.call().balanceOf(house) == 9990
        assert token.contract.call().balanceOf(
            bin_to_eth_address(user_address.address)) == 10

        # Check our internal book keeping matches
        assert house_address.get_account(asset).account.get_balance() == 9990
        assert user_address.get_account(asset).account.get_balance() == 10
Example #20
0
def token(web3, coinbase) -> Contract:
    """Deploy a token contract in the blockchain."""
    return Token.create_token(web3, name="Mootoken", supply=10000, symbol="MOO", owner=coinbase)