我一直在从事加密项目,并且一直在将bitz集成到该项目中。我的公用电话工作正常,但是在私人电话上,我得到以下答复:
{"code":100,"msg":"The required parameter cannot be empty","data":null}
我不确定缺少什么参数,因为通过查看api文档,我知道了发生调用所需的每个参数(api文档:bitz api docs)。
这是我的主要代码:
using bit_z;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Program
{
public static void Main(string[] args)
{
bit_z_core core = new bit_z_core("api_key", "api_secret");
WebFuncs weber = new WebFuncs();
tickerBase b = core.getTicker("eth_btc");
string sell = b._dat.sell;
//core.AddTrade("out", sell, "1", "eth_btc", "sdf");
Dictionary<string, string> data = new Dictionary<string, string>();
//tradeAdd
string payload_tradeAdd = bit_z.WebFuncs.Sign("api_key", "api_secret", new Dictionary<string, string>{
{ "price", sell},
{ "number", "0.876"},
{ "coin", "eth_btc"},
{ "tradepwd", "super-secret"},
{ "type" , "in" }
});
string info = bit_z.WebFuncs.callPrivateAPI(payload_tradeAdd).Result;
Console.WriteLine(info); //here it responses with: {"code":100,"msg":"The required parameter cannot be empty","data":null}
Console.ReadLine();
}
private static void TestSign(string expected, Dictionary<string, string> data)
{
string payload = bit_z.WebFuncs.Sign("KEY", "SECRET", data, "1532127208", "100000");
if (expected == payload)
{
Console.WriteLine("OK");
}
else
{
Console.WriteLine("Invalid payload. Expected {0}. Got {1}.", expected, payload);
}
}
}
}
以及执行bitz调用的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace bit_z
{
public class WebFuncs
{
private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
private string url = "https://api.bit-z.com/api_v1";
public string getHTML(string url_endpoint)
{
try
{
WebClient client = new WebClient();
string inf = client.DownloadString(url + url_endpoint);
return inf;
}
catch (Exception i)
{
return null;
}
}
public static async Task<string> callPrivateAPI(string payload)
{
string requestUri = "https://api.bit-z.com/api_v1";
try
{
var request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
string final = requestUri + "/tradeAdd?" + payload;
request.RequestUri = new Uri(final);
//string info = client.DownloadString(final);
//Console.WriteLine(info);
//request.Headers.Add("sign", encoded);
//request.Content = new ObjectContent(typeof(object), postData, new JsonMediaTypeFormatter());
using (var client = new HttpClient())
{
var response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
string r = await response.Content.ReadAsStringAsync();
//{"Success":true,"Error":null,"Data":[{"CurrencyId":2,"Symbol":"DOT","Total":9646.07411016,"Available":9646.07411016,"Unconfirmed":0.0,"HeldForTrades":0.0,"PendingWithdraw":0.0,"Address":"1HEfio1kreDBgj5uCw4VHbEDSgc6YJXfTN","Status":"OK","StatusMessage":null}]}
return r;
}
}
}
catch (Exception ii)
{
return null;
}
return null;
}
// Sign creates a signed payload with the given API key and secret
public static string Sign(string key, string secret, Dictionary<string, string> data = null, string timestamp = null, string nonce = null)
{
if (timestamp == null)
{
timestamp = GetTimestamp();
}
if (nonce == null)
{
nonce = GetNonce();
}
if (data == null)
{
data = new Dictionary<string, string>();
}
// Convert the data to a SortedDictionary
SortedDictionary<string, string> sortedData = new SortedDictionary<string, string>(data);
// Add the common key-value pairs
sortedData["api_key"] = key;
sortedData["nonce"] = nonce;
sortedData["timestamp"] = timestamp;
// Construct the body as key-value pairs, sorting by key
var pairs = new List<string>();
foreach (var kv in sortedData)
{
pairs.Add(kv.Key + "=" + kv.Value);
}
var body = String.Join("&", pairs);
// Append the signature
var signature = GetMD5(body + secret);
body += "&sign=" + signature;
return body;
}
// Timestamp returns the time in unix seconds as a string
private static string GetTimestamp()
{
return DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
}
// Nonce returns a 6-character nonce to use for API requests
private static string GetNonce()
{
return RandomInt32(100000, 999999).ToString();
}
private static Int32 RandomInt32(Int32 minValue, Int32 maxValue)
{
if (minValue > maxValue)
{
throw new ArgumentOutOfRangeException(nameof(minValue));
}
if (minValue == maxValue) return minValue;
Int64 diff = maxValue - minValue;
byte[] buffer = new byte[8];
while (true)
{
rngCsp.GetBytes(buffer);
UInt32 rand = BitConverter.ToUInt32(buffer, 0);
Int64 max = (1 + (Int64)UInt32.MaxValue);
Int64 remainder = max % diff;
if (rand < max - remainder)
{
return (Int32)(minValue + (rand % diff));
}
}
}
private static string GetMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString().ToLower();
}
}
}
}
提前谢谢!