StarkEX永续合约签名验证失败:INVALID_SIGNATURE错误排查
StarkEX Perpetual Playground Transfer交易签名无效问题排查
问题场景
使用StarkEX Perpetual Playground发送Transfer交易,已遵循官方文档操作,但向网关发送curl请求时持续收到StarkErrorCode.INVALID_SIGNATURE错误。本地签名验证显示有效,但网关返回无效。
请求示例
curl -k -d '{"tx_id": 39,"tx": {"amount": "3","asset_id": "0xa21edc9d9997b1b1956f542fe95922518a9e28ace11b7b2972a1974bf5971f","expiration_timestamp": "20000000","nonce": "0","receiver_position_id": "4","receiver_public_key": "0x63f62982fa598ad7c4e469870b3a1c23316ba8fb717aa2b1ee3114283fb1b82","sender_position_id": "997","sender_public_key": "0x63e08af5f1a5a70c118b5a47c4ae89ddad32f9d36626ad0f0cc296fd570fec4","signature": {"r": "0x4f3106aa42f35b94a290349387fe1d7366e201a65a86314ccf80025375d9ed5","s": "0x37b4705ac61f712d13196a260320433122016afc8c5a79c48ac7847db0cd68"},"type": "TRANSFER"}}' https://perpetual-playground-v2.starkex.co/gateway/add_transaction; echo
响应结果:
{"code": "StarkErrorCode.INVALID_SIGNATURE", "message": "Transfer has an invalid signature."}
本地签名及验证代码
from services.perpetual.public.perpetual_messages import get_transfer_msg from starkware.crypto.signature.signature import private_to_stark_key, sign from starkware.crypto.signature.signature import * # Define the transfer message data. type = "Transfer" asset_id = 286442224669982855773917167725901379555005478797788066723536016706544965407 asset_id_fee = 0 receiver_public_key = 2825868930652315540133093693348064822157481518754303749560050236804923333506 sender_position_id = 997 receiver_position_id = 4 src_fee_position_id = 7 nonce = 0 amount = 3 max_amount_fee = 0 expiration_timestamp = 20000000 # Calculate the message hash. message_hash = get_transfer_msg( asset_id, asset_id_fee, receiver_public_key, sender_position_id, receiver_position_id, src_fee_position_id, nonce, amount, max_amount_fee, expiration_timestamp, ) private_key=<private key> # Sign the message hash. r, s = sign(message_hash, private_key) # verify the signature verification_result = verify( msg_hash=message_hash, r=r, s=s, public_key=<public key> ) if verification_result: print("Signature is valid.") else: print("Signature is not valid.") # Print the signature. r_hex = hex(r) s_hex = hex(s) # Print the signature in hexadecimal. print("Signature (r, s):", r_hex, s_hex)
排查建议
核对消息哈希生成的参数一致性:网关会重新计算交易哈希,若本地参数与网关使用的参数不匹配,会直接导致签名验证失败。需重点检查:
- 本地十进制
asset_id转十六进制后,是否与curl请求中的值完全一致 - 确认
src_fee_position_id是否是网关要求的必填参数,curl请求未传递该字段,可能本地计算哈希时多传了不必要参数 - 检查
expiration_timestamp、nonce、amount等字段的数值类型(字符串/整数)和取值是否完全对应
- 本地十进制
检查签名格式与编码:
- 确认
r和s的十六进制字符串长度是否符合要求,部分系统要求偶数长度,若为奇数需补前导零 - 确保签名使用的是Stark Curve参数,避免误用其他椭圆曲线
- 确认
核对公私钥对应关系:
- 验证本地使用的
public_key转十六进制后,是否与curl请求中的sender_public_key完全一致 - 确认私钥确实对应该公钥,避免出现公私钥不匹配的情况
- 验证本地使用的
检查交易类型大小写:curl请求中交易类型为
"TRANSFER",本地代码中为"Transfer",若系统对大小写敏感,会导致哈希生成逻辑差异,进而引发签名无效模拟网关哈希计算逻辑:按照StarkEX官方文档的Transfer交易哈希规则,用curl请求中的字段手动计算哈希,与本地生成的
message_hash对比,排查get_transfer_msg函数实现或参数传递的问题
内容的提问来源于stack exchange,提问作者arpish R
相关产品推荐
相关产品推荐

