Пример #1
0
 def _check_account_unlocked(self):
     try:
         eth_sign(bytes("pymaker testing if account is unlocked", "utf-8"), self.web3)
     except:
         self.logger.exception(f"Account {self.web3.eth.defaultAccount} is not unlocked and no private key supplied for it")
         self.logger.fatal(f"Unlocking the account or providing the private key is necessary for the keeper to operate")
         exit(-1)
Пример #2
0
def test_signing_with_key_and_rpc_should_return_same_result():
    # given
    web3 = Web3(HTTPProvider("http://localhost:8555"))
    web3.eth.defaultAccount = web3.eth.accounts[0]

    assert Address(web3.eth.defaultAccount) == Address(
        '0x9596c16d7bf9323265c2f2e22f43e6c80eb3d943')

    # and
    text = "abc"
    msg = bytes(text, 'utf-8')

    rpc_signature = eth_sign(msg, web3)

    # when
    keyfile_path = pkg_resources.resource_filename(
        __name__, "accounts/0_0x9596c16d7bf9323265c2f2e22f43e6c80eb3d943.json")
    passfile_path = pkg_resources.resource_filename(__name__, "accounts/pass")

    register_key_file(web3, keyfile_path, passfile_path)

    # and
    # [we do this in order to make sure that the message was signed using the local key]
    # [with `request_blocking` set to `None` any http requests will basically fail]
    web3.manager.request_blocking = None

    # and
    local_signature = eth_sign(msg, web3)

    # then
    assert rpc_signature == local_signature
Пример #3
0
    def cancel_order(self, order: Order) -> bool:
        assert(isinstance(order, Order))

        nonce = self.next_nonce()
        signed_data = keccak_256(encode_bytes(hexstring_to_bytes(order.order_hash)) +
                                 encode_uint256(nonce)).digest()

        signature = eth_sign(signed_data, self.idex.web3)
        v, r, s = to_vrs(signature)

        data = {
            'orderHash': order.order_hash,
            'nonce': str(nonce),
            'address': self._our_address(),
            'v': v,
            'r': bytes_to_hexstring(r),
            's': bytes_to_hexstring(s)
        }

        self.logger.info(f"Cancelling order #{order.order_id}...")

        result = self._http_post("/cancel", data)
        success = result['success'] == 1

        if success:
            self.logger.info(f"Cancelled order #{order.order_id}")
        else:
            self.logger.info(f"Failed to cancel order #{order.order_id}")

        return success
Пример #4
0
    def cancel_order(self, order: Order) -> bool:
        assert (isinstance(order, Order))

        order_hash = self.zrx_exchange.get_order_hash(order.zrx_order)
        self.logger.info(f"Cancelling order #{order_hash}...")

        cancel_msg = self.zrx_exchange.web3.sha3(text=f'cancel:{order_hash}')
        v, r, s = to_vrs(eth_sign(cancel_msg, self.zrx_exchange.web3))
        signature = bytes_to_hexstring(bytes([v])) + \
                    bytes_to_hexstring(r)[2:] + \
                    bytes_to_hexstring(s)[2:] + \
                    "03"  # EthSign

        cancel = {
            "cancellations": [{
                "orderHash": order_hash,
                "signature": signature
            }]
        }

        response = requests.post(f"{self.zrx_api.api_server}/v2/orders/cancel",
                                 json=cancel,
                                 timeout=self.zrx_api.timeout)
        if response.ok:
            data = response.json()[0]  # We suppose only one cancel
            if data.get('success'):
                self.logger.info(f"Cancelled order #{order_hash}")
                return True
            else:
                self.logger.error(
                    f"Failed to cancel: {http_response_summary(response)}")
                return False
        else:
            self.logger.info(f"Failed to cancel order #{order_hash}")
            return False
Пример #5
0
def test_signing(datadir):
    try:
        from sha3 import keccak_256
    except ImportError:
        from sha3 import sha3_256 as keccak_256

    # given
    web3 = Web3(EthereumTesterProvider())
    web3.eth.defaultAccount = web3.eth.accounts[0]

    # and
    text = "abc"
    msg = bytes(text, 'utf-8')
    msg_raw = keccak_256(b'\x19Ethereum Signed Message:\n' +
                         str(len(text)).encode('utf-8') +
                         text.encode("utf-8")).digest()

    # and
    keyfile = str(datadir.join("test_key.json"))
    password = "******"

    # and
    expected_signature = "0x1ca03a12406951a3545b3154e3a544c9b9af677351395facd56a42c3f0b0aae1056b9a2f52ffe81ccd2829fac6446e2c73ca9fe7102fd6341a6408208520ad121b"

    # expect
    assert eth_sign(msg, web3) == expected_signature
    assert eth_sign_with_keyfile(msg, False, keyfile,
                                 password) == expected_signature
    assert eth_sign_with_keyfile(msg_raw, True, keyfile,
                                 password) == expected_signature
Пример #6
0
    def withdraw_token(self, leverjobj: LeverjAPI, token_addr: str,
                       quantity: int) -> int:
        assert (isinstance(leverjobj, LeverjAPI))
        assert (isinstance(token_addr, str))
        assert (isinstance(quantity, int))

        app_id = leverjobj.get_spot_exchange_id()
        ethereum_account = leverjobj.account_id
        custodian_account = self.address
        timestamp = int(time.time() * 1000)
        api_secret = leverjobj.api_secret
        sha3_hash = Web3.soliditySha3(
            ['string', 'string', 'uint256', 'uint256'],
            [ethereum_account, token_addr,
             int(quantity), timestamp])
        signature = eth_sign(sha3_hash, leverjobj.web3, api_secret, True,
                             self.middle_account)
        payload = {
            'asset': token_addr,
            'quantity': str(int(quantity)),
            'timestamp': timestamp,
            'signature': signature
        }
        leverjobj._http_authenticated("POST", "/api/v1", "/account/withdraw",
                                      payload)
        number_dict = leverjobj._http_authenticated("GET", "/api/v1",
                                                    f"/plasma/{app_id}", None)
        return number_dict['number'] + 3
Пример #7
0
    def place_order(self, pair: str, is_sell: bool, price: Wad, amount: Wad) -> str:
        assert(isinstance(pair, str))
        assert(isinstance(is_sell, bool))
        assert(isinstance(price, Wad))
        assert(isinstance(amount, Wad))

        self.logger.info(f"Placing order ({'SELL' if is_sell else 'BUY'}, amount {amount} of {pair},"
                         f" price {price})...")

        # build order
        order = {
            "amount": str(amount),
            "price": str(price),
            "side": 'sell' if is_sell else 'buy',
            "marketId": pair,
        }
        result = self._http_post_signed("/v2/orders/build", order)
        order_id = result['data']['order']['id']
        unsignedOrder = result['data']['order']['json']
        fee = result['data']['order']['feeAmount']

        # sign order
        signature = eth_sign(hexstring_to_bytes(order_id), self.web3)
        result = self._http_post_signed("/v2/orders", {"orderId": order_id, "signature": signature})

        self.logger.info(f"Placed order ({'SELL' if is_sell else 'BUY'}, amount {amount} of {pair},"
                         f" price {price}, fee {float(fee)*100:.4f}%) as #{order_id}")

        return order_id
Пример #8
0
    def place_order(self, pair: str, is_sell: bool, price: Wad,
                    amount: Wad) -> str:
        assert (isinstance(pair, str))
        assert (isinstance(is_sell, bool))
        assert (isinstance(price, Wad))
        assert (isinstance(amount, Wad))

        self.logger.info(
            f"Placing order ({'SELL' if is_sell else 'BUY'}, amount {amount} of {pair},"
            f" price {price})...")

        # build order
        order = self._build_order(amount, price, is_sell, pair)

        result = self._http_post_signed(f"/{self.version}/orders/build", order)
        order_id = result['data']['order']['id']
        unsignedOrder = result['data']['order']['json']
        fee = self._get_fee_rate(result)

        # sign order
        signature = eth_sign(hexstring_to_bytes(order_id), self.web3)
        result = self._http_post_signed(f"/{self.version}/orders", {
            "orderId": order_id,
            "signature": signature
        })

        self.logger.info(
            f"Placed order ({'SELL' if is_sell else 'BUY'}, amount {amount} of {pair},"
            f" price {price}, fee {float(fee)*100:.4f}%) as #{order_id}")

        return order_id
Пример #9
0
    def place_order(self,
                    pay_token: Address,
                    pay_amount: Wad,
                    buy_token: Address,
                    buy_amount: Wad) -> Order:
        """Places a new order.

        Args:
            pay_token: Address of the ERC20 token you want to put on sale.
            pay_amount: Amount of the `pay_token` token you want to put on sale.
            buy_token: Address of the ERC20 token you want to be paid with.
            buy_amount: Amount of the `buy_token` you want to receive.

        Returns:
            New order as an instance of the :py:class:`pyexchange.idex.Order` class.
        """
        assert(isinstance(pay_token, Address))
        assert(isinstance(pay_amount, Wad))
        assert(isinstance(buy_token, Address))
        assert(isinstance(buy_amount, Wad))

        expires = 0
        nonce = self.next_nonce()
        order_hash = keccak_256(encode_address(self.idex.address) +
                                encode_address(buy_token) +
                                encode_uint256(buy_amount.value) +
                                encode_address(pay_token) +
                                encode_uint256(pay_amount.value) +
                                encode_uint256(expires) +
                                encode_uint256(nonce) +
                                encode_address(Address(self._our_address()))).digest()

        signature = eth_sign(order_hash, self.idex.web3)
        v, r, s = to_vrs(signature)

        data = {
            'tokenBuy': buy_token.address,
            'amountBuy': str(buy_amount.value),
            'tokenSell': pay_token.address,
            'amountSell': str(pay_amount.value),
            'address': self._our_address(),
            'nonce': str(nonce),
            'expires': expires,
            'v': v,
            'r': bytes_to_hexstring(r),
            's': bytes_to_hexstring(s)
        }

        self.logger.info(f"Placing order selling {pay_amount} {pay_token} for {buy_amount} {buy_token}...")

        result = self._http_post("/order", data)
        order = self._json_to_order(result)

        self.logger.info(f"Placed order selling {pay_amount} {pay_token} for {buy_amount} {buy_token} as #{order.order_id}")

        return order
Пример #10
0
    def _create_signature(self, msg: str) -> str:
        assert (isinstance(msg, str))

        try:
            from sha3 import keccak_256
        except ImportError:
            from sha3 import sha3_256 as keccak_256

        message = bytes(msg, 'utf-8')
        return eth_sign(message, self.web3)
Пример #11
0
    def _get_token(self) -> str:
        data = self._http_unauthenticated(
            "GET", f"/json_web_tokens/{self.our_account}", {})
        nonce = data['data']['attributes']['nonce']

        signature = eth_sign(bytes(nonce, 'utf-8'), self.zrx_exchange.web3)
        data['data']['attributes']['signature'] = signature
        result = self._http_unauthenticated(
            "PUT", f"/json_web_tokens/{self.our_account}", data)

        return result['data']['attributes']['token']
Пример #12
0
def test_signing():
    # given
    web3 = Web3(HTTPProvider("http://localhost:8555"))
    web3.eth.defaultAccount = web3.eth.accounts[0]

    # and
    text = "abc"
    msg = bytes(text, 'utf-8')

    # expect
    assert eth_sign(msg, web3).startswith("0x")
Пример #13
0
    def _create_signature(self, params: dict) -> str:
        assert (isinstance(params, dict))

        keys = ''
        values = ''
        for key in sorted(params.keys()):
            keys += key
            values += str(params[key])

        message = bytes(keys + values, 'utf-8')
        return eth_sign(message, self.zrx_exchange.web3)
Пример #14
0
    def _get_orders(self, endpoint: str):
        assert (isinstance(endpoint, str))

        nonce = str(time.time() + 3)

        body = {
            'protocol': '0x',
            'nonce': nonce,
            'signature': eth_sign(bytes(nonce, 'utf-8'), self.tethfinex.web3)
        }

        return self._http_post(f"{endpoint}", body)
Пример #15
0
    def create_order(self,
                     pay_token: Address,
                     pay_amount: Wad,
                     buy_token: Address,
                     buy_amount: Wad,
                     expires: int) -> Order:
        """Creates a new off-chain order.

        Although it's not necessary to have any amount of `pay_token` deposited to EtherDelta
        before placing an order, nobody will be able to take this order until some balance of
        'pay_token' is provided.

        If you want to trade raw ETH, pass `Address('0x0000000000000000000000000000000000000000')`
        as either `pay_token` or `buy_token`.

        Args:
            pay_token: Address of the ERC20 token you want to put on sale.
            pay_amount: Amount of the `pay_token` token you want to put on sale.
            buy_token: Address of the ERC20 token you want to be paid with.
            buy_amount:  Amount of the `buy_token` you want to receive.
            expires: The block number after which the order will expire.

        Returns:
            Newly created order as an instance of the :py:class:`pymaker.etherdelta.Order` class.
        """

        assert(isinstance(pay_token, Address))
        assert(isinstance(pay_amount, Wad))
        assert(isinstance(buy_token, Address))
        assert(isinstance(buy_amount, Wad))
        assert(isinstance(expires, int) and (expires > 0))
        assert(pay_amount > Wad(0))
        assert(buy_amount > Wad(0))

        nonce = self.random_nonce()
        order_hash = hashlib.sha256(encode_address(self.address) +
                                    encode_address(buy_token) +
                                    encode_uint256(buy_amount.value) +
                                    encode_address(pay_token) +
                                    encode_uint256(pay_amount.value) +
                                    encode_uint256(expires) +
                                    encode_uint256(nonce)).digest()

        signature = eth_sign(order_hash, self.web3)
        v, r, s = to_vrs(signature)

        return Order(self, Address(self.web3.eth.defaultAccount), pay_token, pay_amount, buy_token, buy_amount,
                     expires, nonce, v, r, s)
Пример #16
0
    def _create_signature(self, params: dict) -> str:
        assert (isinstance(params, dict))

        try:
            from sha3 import keccak_256
        except ImportError:
            from sha3 import sha3_256 as keccak_256

        keys = ''
        values = ''
        for key in sorted(params.keys()):
            keys += key
            values += str(params[key])

        message = bytes(keys + values, 'utf-8')
        return eth_sign(message, self.zrx_exchange.web3)
Пример #17
0
    def sign_order(self, order: Order) -> Order:
        """Signs an order so it can be submitted to the relayer.

        Order will be signed by the `web3.eth.defaultAccount` account.

        Args:
            order: Order you want to sign.

        Returns:
            Signed order. Copy of the order passed as a parameter with the `ec_signature_r`, `ec_signature_s`
            and `ec_signature_v` fields filled with signature values.
        """
        assert(isinstance(order, Order))

        signature = eth_sign(hexstring_to_bytes(self.get_order_hash(order)), self.web3)
        v, r, s = to_vrs(signature)

        signed_order = copy.copy(order)
        signed_order.ec_signature_r = bytes_to_hexstring(r)
        signed_order.ec_signature_s = bytes_to_hexstring(s)
        signed_order.ec_signature_v = v
        return signed_order
Пример #18
0
    def cancel_order(self, order_id: int) -> bool:
        assert (isinstance(order_id, int))

        self.logger.info(f"Cancelling order #{order_id}...")

        data = {
            "orderId":
            str(order_id),
            "protocol":
            '0x',
            "signature":
            eth_sign(bytes(str(order_id), 'utf-8'), self.tethfinex.web3)
        }

        result = self._http_post("/trustless/v1/w/oc", data)
        success = result[0] == order_id

        if success:
            self.logger.info(f"Cancelled order #{order_id}")
        else:
            self.logger.info(f"Failed to cancel order #{order_id}")

        return success
Пример #19
0
    def sign_order(self, order: Order) -> Order:
        """Signs an order so it can be submitted to the relayer.

        Order will be signed by the `web3.eth.defaultAccount` account.

        Args:
            order: Order you want to sign.

        Returns:
            Signed order. Copy of the order passed as a parameter with the `signature` field filled with signature.
        """
        assert (isinstance(order, Order))

        signature = eth_sign(hexstring_to_bytes(self.get_order_hash(order)),
                             self.web3)
        v, r, s = to_vrs(signature)

        signed_order = copy.copy(order)
        signed_order.signature = bytes_to_hexstring(bytes([v])) + \
                                 bytes_to_hexstring(r)[2:] + \
                                 bytes_to_hexstring(s)[2:] + \
                                 "03"  # EthSign
        return signed_order
Пример #20
0
    def _create_signature(self, msg: str) -> str:
        assert(isinstance(msg, str))

        return eth_sign(bytes(msg, 'utf-8'), self.web3)
Пример #21
0
    def _create_signature(self, params: str) -> str:
        assert (isinstance(params, str))

        return eth_sign(bytes(params, 'utf-8'), self.web3, self.api_secret,
                        False, Address(self.account_id))