【问题标题】:Delphi + Binance Api + Limit Order Problem Invalid signaturDelphi + Binance Api + 限价单问题 签名无效
【发布时间】:2021-06-18 09:45:05
【问题描述】:
{"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&timestamp='+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

问题出在哪里?

非常感谢。

【问题讨论】:

  • 您必须使用try..finally 块来保护您的资源。
  • 谢谢,但不影响结果。
  • 我知道,但您仍然必须使用它们来保护资源。
  • 不,像这样:i.stack.imgur.com/IHdIO.png
  • 总是这种模式:Frog := TFrog.Create; try { use Frog } finally Frog.Free end。如果您有五个资源,则嵌套五个这样的块。好的 Delphi 代码是三角形的!

标签: delphi post binance idhttp binance-api-client


【解决方案1】:

感谢您的回答。我对代码进行了改进。

有需要的朋友可以在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&timestamp='
    + 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}

此程序在“全球币安 API”中有效,但在“trbinance Api”中无效

相同的程序在“trbinance api”中给出“无效签名”错误。 :(

trbinance api 示例:

HMAC SHA256 签名:

[linux]$ echo -n "symbol=BTC_USDT&side=0&type=1&quantity=0.16&price=7500&timestamp=1581720670624&recvWindow=5000" | openssl dgst -sha256 -hmac "cfDC92B191b9B3Ca3D842Ae0e01108CBKI6BqEW6xr4NrPus3hoZ9Ze9YrmWwPFV"
(stdin)= 33824b5160daefc34257ab9cd3c3db7a0158a446674f896c9fc3b122ae656bfa

卷曲命令:

(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&timestamp=1581720670624&recvWindow=5000&signature=33824b5160daefc34257ab9cd3c3db7a0158a446674f896c9fc3b122ae656bfa'

【讨论】:

    【解决方案2】:

    这段代码有很多问题,但我看到的最大问题是你不应该在TStringList 字符串中包含尾随&amp; 字符,例如:

    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() 会为您将那些&amp; 字符插入到请求正文中,因此传输的数据与您签名的数据不同。

    【讨论】:

      【解决方案3】:

      根据Binance TR API docs

      使用您的 secretKey 作为密钥,使用 totalParams 作为 HMAC 操作的值。 totalParams 定义为与请求正文连接的查询字符串。

      来自 API 的错误,文本为“无效签名”。可以给您一个线索,表明问题出在您的签名算法上:

      sign := THashSHA2.GetHMAC(queryString, api_secret, SHA256);
      

      您在此处的代码仅对您的查询字符串进行签名,但根据 API 文档,您必须对查询字符串进行签名与请求正文连接

      因此,您需要像这样更改代码(“Post”变量必须在此行之前初始化):

      sign := THashSHA2.GetHMAC(queryString + Post.text, api_secret, SHA256);
      

      【讨论】:

        猜你喜欢
        • 2019-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-25
        • 1970-01-01
        • 2019-09-24
        • 2021-08-25
        • 2022-12-04
        相关资源
        最近更新 更多