전달 수수료
일반적으로 스마트 컨트랙트가 다른 스마트 컨트랙트에 쿼리를 보내려면 내부 메시지를 대상 스마트 컨트랙트로 보내고(메시지 전달 수수료), 대상에서 이 메시지를 처리하고(가스비), 필요한 경우 답변을 다시 보내는 데 드는 비용(메시지 전달 수수료)을 지불해야 합니다.
대부분의 경우 발신자는 내부 메시지에 소량의 톤코인(예: 1톤코인)을 첨부하고(메시지 처리 비용을 지불하기에 충분) "반송" 플래그를 설정합니다(즉, 반송 가능한 내부 메시지를 전송); 수신자는 수신한 값 중 사용하지 않은 부분을 응답으로 반환합니다(메시지 전달 수수료를 공제함). 이 작업은 일반적으로 mode = 64
로 SENDRAWMSG
를 호출하여 수행합니다(TON VM 설명서의 부록 A 참조).
수신자가 수신한 메시지를 구문 분석할 수 없고 0이 아닌 종료 코드로 종료되는 경우(예: 처리되지 않은 셀 역직렬화 예외로 인해) 메시지는 자동으로 발신자에게 '반송'되며 '반송' 플래그가 지워지고 '반송됨' 플래그가 설정됩니다. 반송된 메시지의 본문에는 32비트 '0xffffffff'와 원본 메시지의 256비트가 포함됩니다. 스마트 컨트랙트에서 op
필드를 파싱하고 해당 쿼리를 처리하기 전에 수신되는 내부 메시지의 반송
플래그를 확인하는 것이 중요합니다(그렇지 않으면 반송된 메시지에 포함된 쿼리가 원래 발신자에 의해 새로운 별도의 쿼리로 처리될 위험이 있습니다). "반송됨" 플래그가 설정되면 특수 코드가 반송된 메시지에서 op
와 query_id
를 역직렬화하여 어떤 쿼리가 실패했는지 파악하고 적절한 조치를 취할 수 있습니다(예: 반송된 메시지에서 op
와 query_id
를 역직렬화). 더 간단한 스마트 컨트랙트는 모든 반송된 메시지를 무시할 수도 있습니다("반송됨" 플래그가 설정된 경우 종료 코드 0으로 종료). "반송" 플래그는 전송 중에 다시 작성되므로 위조가 불가능하며, "반송" 플래그가 있는 메시지는 수신자가 보낸 일부 메시지가 반송된 결과라고 가정하는 것이 안전하다는 점에 유의하시기 바랍니다.
반면에 수신자는 들어오는 쿼리를 성공적으로 구문 분석하여 요청된 메서드 op
가 지원되지 않거나 다른 오류 조건이 충족되는 것을 확인할 수 있습니다. 그런 경우 위에서 언급한 대로 mode = 64
와 함께 SENDRAWMSG
를 사용하여 op
가 0xffffffff
또는 다른 적절한 값으로 응답을 다시 보내야 합니다.
어떤 상황에서는 발신자가 어떤 가치를 전송하는 동시에 확인 또는 오류 메시지를 받기를 원하기도 합니다. 예를 들어, 검증자가 스마트 컨트랙트를 선거하는 경우 선거 참여 요청과 함께 첨부된 가치로 지분을 받습니다. 이러한 경우, 의도한 가치에 톤코인 1개를 추가로 첨부하는 것이 합리적입니다. 오류가 있는 경우(예: 어떤 이유로든 스테이크가 수락되지 않을 수 있음), 수신된 전체 금액(처리 수수료 제외)은 오류 메시지와 함께 발신자에게 반환되어야 합니다(예: 앞서 설명한 대로 mode = 64
와 함께 SENDRAWMSG
를 사용). 성공하면 확인 메시지가 생성되고 정확히 하나의 톤코인이 반환됩니다(이 값에서 메시지 전송 수수료가 차감된 값, 즉 SENDRAWMSG
의 mode = 1
).