转账时如何验证Jetton?Jetton身份识别与安全验证问询
TON Jetton转账场景技术问题解答
首先先明确场景背景:在TON的Jetton转账流程中,jetton-wallet发送的transfer_notification消息体结构如下:
var msg_body = begin_cell() .store_uint(op::transfer_notification(), 32) .store_uint(query_id, 64) .store_coins(jetton_amount) .store_slice(from_address) .store_slice(either_forward_payload) .end_cell();
接收合约的解析逻辑为:
if (op == op::transfer_notification()) { throw_unless(error::invalid_address(), equal_slices(sender_address, jetton_wallet)); int jetton_amount = in_msg_body~load_coins(); throw_if(error::insufficient_jetton_amount(), jetton_amount <= 0); slice from_address = in_msg_body~load_msg_addr(); slice payload = in_msg_body; int either_payload = payload~load_uint(1); if (either_payload) { slice payload = payload.preload_ref().begin_parse(); }
以下是针对技术问题的解答:
一、如何识别Jetton的具体类型?
虽然transfer_notification消息本身不携带Jetton Master地址,但发送该消息的sender就是对应Jetton的Wallet合约地址。你可以通过以下方式识别Jetton类型:
- 调用该Jetton Wallet合约的
get_jetton_master方法,直接获取关联的Jetton Master地址; - 拿到Jetton Master地址后,调用其
get_metadata方法,就能获取Jetton的名称、符号、精度等标识信息,以此确定具体类型; - 另外接收合约本身已经通过
equal_slices(sender_address, jetton_wallet)校验sender,说明合约预存了合法的Jetton Wallet地址,也可以直接通过这个预存地址反向关联到Jetton Master。
二、如何对消息中的信息进行验证?
结合现有解析逻辑,需要补充和强化以下验证步骤:
- Sender合法性:现有代码已经校验sender是预存的Jetton Wallet地址,这是核心验证,确保消息来自合法的Jetton分发渠道;
- 消息结构完整性:加载
either_forward_payload时,要检查剩余slice的长度是否符合格式要求,避免恶意构造的残缺消息导致合约异常; - Payload格式校验:当
either_payload为1时,要验证ref的存在性,不能直接加载空引用; - 金额合理性:除了校验金额大于0,还可以根据业务场景限制单次转账的最大金额;
- 重放攻击防范:要维护已处理的
query_id列表,避免黑客重放旧的转账通知消息。
三、是否存在黑客通过发送TVM内部消息窃取Jetton的风险?
正常情况下风险极低,但存在几种可能的攻击场景,需要针对性防范:
- 伪造合法Wallet地址:如果合约预存的Jetton Wallet地址被篡改,黑客可以冒充合法Wallet发送消息,但这需要合约本身存在存储漏洞;
- 消息构造漏洞:如果合约对
transfer_notification的消息结构校验不严格,黑客可能篡改金额等字段,但现有代码的sender和金额校验能规避大部分这类风险; - 重放攻击:如果未正确处理
query_id,黑客可能重放旧的转账通知,只要合约维护已处理的query_id列表就能避免。
只要严格执行sender身份验证、消息结构校验和query_id管理,就能有效防范这类风险。
四、是否支持同时转账多种类型的Jetton?
单个transfer_notification消息只能对应一种Jetton,因为每个消息的sender是特定Jetton的Wallet合约,一次消息只能传递该Jetton的转账信息。如果要同时转账多种Jetton,需要分别调用不同Jetton Wallet的transfer方法,生成多个独立的transfer_notification消息,发送到对应的owner合约。接收合约需要分别处理每个Jetton的转账通知,单独维护不同Jetton的余额数据。
内容的提问来源于stack exchange,提问作者Vyacheslav
相关产品推荐
相关产品推荐

