简体   繁体   中英

Problems Connecting to MtGox API 2 with Python

I am writing a trading program that I need to connect to MtGox (a bitcoin exchange) through the API v2. But I keep getting the following error:

URL: 1 https://data.mtgox.com/api/2/BTCUSD/money/bitcoin/address

HTTP Error 403: Forbidden.

Most of my script is a direct copy from here (that is a pastebin link). I just had to change it to work with Python 3.3.

I suspect that it has to do with the part of script where I use base64.b64encode. In my code , I have to encode my strings to utf-8 to use base64.b64encode:

                url = self.__url_parts + '2/' + path
                api2postdatatohash = (path + chr(0) + post_data).encode('utf-8')          #new way to hash for API 2, includes path + NUL
                ahmac = base64.b64encode(str(hmac.new(base64.b64decode(self.secret),api2postdatatohash,hashlib.sha512).digest()).encode('utf-8'))

                # Create header for auth-requiring operations
                header = {
                     "User-Agent": 'Arbitrater',
                     "Rest-Key": self.key,
                     "Rest-Sign": ahmac
                }

However, with the other guy's script, he doesn't have too:

                url = self.__url_parts + '2/' + path
                api2postdatatohash = path + chr(0) + post_data          #new way to hash for API 2, includes path + NUL
                ahmac = base64.b64encode(str(hmac.new(base64.b64decode(self.secret),api2postdatatohash,hashlib.sha512).digest()))

                # Create header for auth-requiring operations
                header = {
                     "User-Agent": 'genBTC-bot',
                      "Rest-Key": self.key,
                     "Rest-Sign": ahmac
                }

I'm wondering if that extra encoding is causing my header credentials to be incorrect. I think this is another Python 2 v. Python 3 problem. I don't know how the other guy got away without changing to utf-8, because the script won't run if you try to pass a string to b64encode or hmac. Do you guys see any problems with what I am doing? Is out code equivalent?

This line specifically seems to be the problem -

ahmac = base64.b64encode(str(hmac.new(base64.b64decode(self.secret),api2postdatatohash,hashlib.sha512).digest()).encode('utf-8'))

To clarify, hmac.new() creates an object to which you then call digest(). Digest returns a bytes object such as

b.digest()

b'\x92b\x129\xdf\t\xbaPPZ\x00.\x96\xf8%\xaa'

Now, when you call str on this, it turns to b'\\\\x92b\\\\x129\\\\xdf\\\\t\\\\xbaPPZ\\\\x00.\\\\x96\\\\xf8%\\\\xaa'

So, see what happens there? The byte indicator is now part of the string itself, which you then call encode() on.

str(b.digest()).encode("utf-8")
b"b'\\x92b\\x129\\xdf\\t\\xbaPPZ\\x00.\\x96\\xf8%\\xaa'"

To fix this, as turning bytes into a string back into bytes was unnecessary anyhow(besides problematic), I believe this will work -

ahmac = base64.b64encode(hmac.new(base64.b64decode(self.secret),api2postdatatohash,hashlib.sha512).digest())

I believe you are likely to find help in a related question of mine although it deals with the WebSocket API:
Authenticated call to MtGox WebSocket API in Python 3

Also, the HTTP 403 error seems to indicate that there is something fundamentally wrong with the request. Even if you threw the wrong authentication info at the API you should have gotten an error message as a response and not a 403. My best guess is that you are using the wrong HTTP method so check if you are using the appropriate one (GET/POST).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM