Api

GDAX Post API 不工作 VB.net

  • December 2, 2020

我在 POST 請求上遇到 (400) 錯誤請求。我能夠使用相同的簽名過程執行所有 Get 和 Delete 請求,但顯然主體是 string.empty。我們已經測試了各種不同的 JSON 格式來嘗試讓它工作,但它不起作用。我們無法找到任何 prehash 簽名的範例進行比較。此外,除非 POST 伺服器時間與 GET 和 DELETE 伺服器時間不同,否則我們有正確的時間戳,因為我們在 GET/time API 呼叫伺服器時間的 1 秒內。GDAX 允許 30 秒的緩衝區進行身份驗證。

Public Shared Function placeOrder()
   Try
       Dim Body As String = "{""type"":""limit"",""side"":""sell"",""product_id"":""BTC-USD"",""price"":""20000"",""size\"":""0.02235229""}"
       Dim ts As String = GetNonce()
       Dim method As String = "/orders"
       Dim str_GDAX_Main As String = "https://api.gdax.com"
       Dim sig As String = GetSignature(ts, "POST", method, Body)
       Dim fr As System.Net.HttpWebRequest
       Dim targetURI As New Uri(str_GDAX_Main & method)
       'Dim response As String

       Dim jsonDataBytes As Byte() = Encoding.UTF8.GetBytes(Body)


       fr = DirectCast(HttpWebRequest.Create(targetURI), System.Net.HttpWebRequest)
       fr.Headers.Add("CB-ACCESS-KEY", config_API_Key)
       fr.Headers.Add("CB-ACCESS-SIGN", sig)
       fr.Headers.Add("CB-ACCESS-TIMESTAMP", ts)
       fr.Headers.Add("CB-ACCESS-PASSPHRASE", config_API_Passphrase)
       fr.UserAgent = UserAgent
       fr.Accept = "application/json"
       fr.Method = "POST"
       fr.ContentLength = jsonDataBytes.Length

       Dim stream = fr.GetRequestStream()
       stream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
       stream.Close()

       Dim response = fr.GetResponse().GetResponseStream()

       Dim reader As New StreamReader(response)
       Dim res = reader.ReadToEnd()
       reader.Close()
       response.Close()
       Return res

       'If (fr.GetResponse().ContentLength > 0) Then
       '    Dim str As New System.IO.StreamReader(fr.GetResponse().GetResponseStream())
       '    response = (str.ReadToEnd())
       '    str.Close()
       'End If

       'Form1.RichTextBox1.Text = (response)
   Catch ex As System.Net.WebException
       MessageBox.Show(ex.Message)
       'Error in accessing the resource, handle it
   End Try
End Function

Public Shared Function GetNonce() As String
   Return (DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds.ToString()
End Function

Public Shared Function GetSignature(nonce As String, method As String, url As String, body As String) As String
   Dim message As String = String.Concat(nonce, method.ToUpper(), url, body)
   Dim encoding = New ASCIIEncoding()
   Dim keyByte As Byte() = Convert.FromBase64String(config_API_Secret)
   Dim messageBytes As Byte() = encoding.GetBytes(message)
   Using hmacsha256 = New HMACSHA256(keyByte)
       Dim hashmessage As Byte() = hmacsha256.ComputeHash(messageBytes)
       Return Convert.ToBase64String(hashmessage)
   End Using
End Function

我們不知道我們的 body 是否不正確,或者 URI 是否不正確,或者問題是什麼。如果有人可以看一下並找出我們的正文語法錯誤在哪裡。或者,如果我們應該尋找其他地方。

您的“公共共享函式 GetSignature”工作正常!我已經絞盡腦汁寫了幾天,但沒有運氣!謝謝你的片段!

至於您的問題,可能已經有人回答了。

為了解決進一步的問題,我建議您在收到 HTTP 錯誤後繼續您的流,GDAX 將為您提供有用的資訊。

這是我處理網路異常的方式。

         Catch ex As WebException

       Dim output As New ClassWebRequestOutput
       output._ErrorMessage = ex.Message.ToString

       Dim exResponse As String
       output._Error = True

       exResponse = New StreamReader(ex.Response.GetResponseStream()).ReadToEnd
       output._Resopnse = exResponse

       Return output
       Exit Function

這將通過有用的提示繼續網路連接。

我沒有詳細介紹您的程式碼,但似乎您收到 400 錯誤,它是一個通用錯誤。使用我正在使用的程式碼,我可以獲得更具體的詳細資訊,但我遇到的問題是簽名總是“消息”:“無效簽名”。很明顯,我正在訪問伺服器,但簽名的建構方式不正確。

我附上我的程式碼,如果它對你有幫助的話。

PS。我嘗試 PostMan 進行一些測試,但問題仍然存在。

如果我們能分享我們的發現來解決這個問題,我將不勝感激。

Private Function PrivateRequest(sMethod As String, sData As String) As String
   Dim key As String = "MY KEY"
   Dim secret As String = "MY SECRET"
   Dim url As String = "https://api.gdax.com"
   Dim nonce As String = (TimeToUnix(DateTime.Now) - 3600).ToString
   Dim targetURI As New Uri(url & sMethod)

   Dim postdataStr As String = sData
   Dim postdata = New Byte(postdataStr.Count - 1) {}
   Dim encText As New System.Text.UTF8Encoding()
   postdata = encText.GetBytes(postdataStr)

   Dim messageStr As String = String.Concat(nonce, "POST", targetURI, sData)

   Dim base64DecodedSecret As Byte() = Convert.FromBase64String(secret)

   Dim message = New Byte(messageStr.Count - 1) {}
   Dim encText1 As New System.Text.UTF8Encoding()
   message = encText1.GetBytes(messageStr)

   Dim signature = getHash(base64DecodedSecret, message)
   Dim signatureStr = Convert.ToBase64String(signature)

   Dim webRequest__1 As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
   webRequest__1.ContentType = ("application/json")
   webRequest__1.Method = "POST"
   webRequest__1.UserAgent = ".NET Framework Test Client"
   webRequest__1.Headers.Add("CB-ACCESS-SIGN", signatureStr)
   webRequest__1.Headers.Add("CB-ACCESS-TIMESTAMP", nonce)
   webRequest__1.Headers.Add("CB-ACCESS-KEY", key)
   webRequest__1.Headers.Add("CB-ACCESS-PASSPHRASE", "MY PASSPHRASE")

   Dim postreqstream As Stream = webRequest__1.GetRequestStream()
   postreqstream.Write(postdata, 0, postdata.Length)
   postreqstream.Close()

   Try
       Using webResponse As WebResponse = webRequest__1.GetResponse()
           Using str As Stream = webResponse.GetResponseStream()
               Using sr As New StreamReader(str)
                   Dim responseContent3 As String = sr.ReadToEnd
                   Return responseContent3
               End Using
           End Using
       End Using
   Catch wex As WebException
       Using response As HttpWebResponse = DirectCast(wex.Response, HttpWebResponse)
           Using str As Stream = response.GetResponseStream()
               Using sr As New StreamReader(str)
                   Dim responseContent3 As String = sr.ReadToEnd
                   Return responseContent3
               End Using
           End Using
       End Using
   End Try
End Function

Private Function getHash(keyByte As Byte(), messageBytes As Byte()) As Byte()
   Using hmacsha256 = New HMACSHA256(keyByte)
       Dim result As [Byte]() = hmacsha256.ComputeHash(messageBytes)
       Return result
   End Using
End Function

Public Function TimeToUnix(ByVal dteDate As Date) As String
   If dteDate.IsDaylightSavingTime = True Then
       dteDate = DateAdd(DateInterval.Hour, -1, dteDate)
   End If
   TimeToUnix = DateDiff(DateInterval.Second, #1/1/1970#, dteDate)
End Function

   MethodString = "/accounts"
   DataString = "{}"
   response = PrivateRequest(MethodString, DataString)

`

引用自:https://bitcoin.stackexchange.com/questions/65827