{"code":3702,"msg":"Invalid signature.","timestamp":1623848681308}
我使用 trbinance.com api。我一直收到同样的错误
procedure TForm1.Button1Click(Sender: TObject);
var
url, sign, queryString, nonce: string;
ST: SystemTime;
DT: TDateTime;
uTime: int64;
sHour, sMin, sSec, sMili: Word;
stream, s_url: string;
Post: TStringList;
IdHTTP10 : TIDhttp;
api_key , api_secret : String;
begin
api_key := '**';
api_secret := '**';
GetSystemTime(ST);
DT := EncodeDate(ST.wYear, ST.wMonth, ST.wDay) +
EncodeTime(ST.wHour, ST.wMinute, ST.wSecond, ST.wMilliseconds);
uTime := DateUtils.MilliSecondsBetween(DT, UnixDateDelta);
nonce:=inttostr(uTime);
url :='https://trbinance.com/open/v1/orders';
queryString := 'symbol=BTT_TRY&side=0&type=1&quantity=1&price=0.0022&recvWindow=5000×tamp='+nonce;
sign := THashSHA2.GetHMAC(queryString, api_secret, SHA256);
IdHTTP10 := TidHTTP.Create(nil);
IdHTTP10.HandleRedirects := True;
IdHTTP10.Request.CustomHeaders.Add('X-MBX-APIKEY:'+api_key);
IdHTTP10.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
Post:=TStringList.Create;
Post.Add('quantity=1&');
Post.Add('price=0.0022&');
Post.Add('recvWindow=5000&');
Post.Add('timestamp='+nonce+'&');
Post.Add('signature='+sign);
s_url := url + '?symbol=BTT_TRY&side=0&type=1';
try
stream:=IdHTTP10.POST(s_url, Post);
Memo1.Lines.Add(stream);
except
on E: Exception do
Memo1.Lines.Add(TimeToStr(time)+' <---> [Order] error: '+E.Message);
end;
IdHTTP10.Free;
Post.Free;
end;
总是有问题:
{"code":3702,"msg":"Invalid signature.","timestamp":1623848681308}
Normaly Binance Symbol : BTTTRY
Turkey Api : BTT_TRY
Normaly Binance Order Url : httpps://api.binance.com/api/v3/order
Turkey Api Order Url : https://trbinance.com/open/v1/orders
问题出在哪里?
非常感谢。
答案 0 :(得分:0)
此代码存在许多问题,但我看到的最大问题是您不应在 &
字符串中包含尾随 TStringList
字符,例如:
Post:=TStringList.Create; Post.Add('quantity=1'); Post.Add('price=0.0022'); Post.Add('recvWindow=5000'); Post.Add('timestamp='+nonce); Post.Add('signature='+sign);
TIdHTTP.Post()
会为您将这些 &
字符插入到请求正文中,因此传输的数据与您签署的数据不同。
答案 1 :(得分:0)
感谢您的回答。我对代码进行了改进。
有需要的朋友可以在delphi中使用这个程序。 ( 全球币安 Api )
procedure TForm1.Button1Click(Sender: TObject);
const
Publickey= '***';
Secretkey= '***';
var
IdHTTP : TIdHTTP;
RBody : TStringstream;
QueryString : String;
Signature : String;
url : String;
begin
queryString :=
'symbol=BTTTRY&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1000&price=0.024400&recvWindow=5000×tamp='
+ ABDULLAH_GetTimestamp();
Signature := THashSHA2.GetHMAC(queryString, Secretkey, SHA256);
Try
IdHTTP := TIdHTTP.Create();
RBody := TStringStream.Create(queryString + '&signature=' + Signature);
IdHTTP.Request.CustomHeaders.Add('X-MBX-APIKEY:' + Publickey);
IdHTTP.Request.CustomHeaders.UnfoldLines := True;
IdHTTP.Request.Accept := 'application/json';
IdHTTP.Request.ContentType := 'application/json';
IdHTTP.Request.ContentEncoding := 'utf-8';
IdHTTP.Request.BasicAuthentication := True;
IdHTTP.HandleRedirects := True;
IdHTTP.HTTPOptions := [hoKeepOrigProtocol, hoForceEncodeParams,
hoNoProtocolErrorException, hoWantProtocolErrorContent];
IdHTTP.iohandler := IdSSLIOHandlerSocketOpenSSL1;
url := 'https://api.binance.com/api/v3/order?';
Try
Memo1.Lines.Add(IdHTTP.Post(url, RBody));
Except
ON E: EXCEPTION DO
Memo1.Lines.Add('Error Message:' + E.Message);
End;
Finally
FreeAndNil(IdHTTP);
FreeAndNil(RBody);
End;
end;
此代码适用于 Global Binance Api。
更改符号:BTTTRY -> BTT_TRY 和发布网址:https://api.binance.com/api/v3/order -> https://trbinance.com/open/v1/orders
它不起作用,结果:
{"code":3702,"msg":"Invalid signature.","timestamp":1723648673412}
此程序适用于“Global Binance Api”,但不适用于“trbinance Api”
相同的过程在“trbinance api”中给出“无效签名”错误。 :(
trbinance api 示例:
HMAC SHA256 签名:
[linux]$ echo -n "symbol=BTC_USDT&side=0&type=1&quantity=0.16&price=7500×tamp=1581720670624&recvWindow=5000" | openssl dgst -sha256 -hmac "cfDC92B191b9B3Ca3D842Ae0e01108CBKI6BqEW6xr4NrPus3hoZ9Ze9YrmWwPFV"
(stdin)= 33824b5160daefc34257ab9cd3c3db7a0158a446674f896c9fc3b122ae656bfa
curl 命令:
(HMAC SHA256)
[linux]$ curl -H "X-MBX-APIKEY: cfDC92B191b9B3Ca3D842Ae0e01108CBKI6BqEW6xr4NrPus3hoZ9Ze9YrmWwPFV" -X POST 'https://www.trbinance.com/open/v1/orders' -d 'symbol=BTC_USDT&side=0&type=1&quantity=0.16&price=7500×tamp=1581720670624&recvWindow=5000&signature=33824b5160daefc34257ab9cd3c3db7a0158a446674f896c9fc3b122ae656bfa'
答案 2 :(得分:0)
使用您的 secretKey 作为密钥,使用 totalParams 作为 HMAC 操作的值。 totalParams 定义为与请求正文连接的查询字符串。
来自 API 的错误,文本为“无效签名”。可以告诉您问题出在您的签名算法上的线索:
sign := THashSHA2.GetHMAC(queryString, api_secret, SHA256);
此处的代码仅对查询字符串进行签名,但根据 API 文档,您必须对查询字符串进行签名与请求正文连接。
因此,您需要像这样更改代码(必须在此行之前初始化“Post”变量):
sign := THashSHA2.GetHMAC(queryString + Post.text, api_secret, SHA256);