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)
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
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
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
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
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
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
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
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
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)
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']
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")
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)
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)
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)
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)
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
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
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
def _create_signature(self, msg: str) -> str: assert(isinstance(msg, str)) return eth_sign(bytes(msg, 'utf-8'), self.web3)
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))