Skip to content

Instantly share code, notes, and snippets.

@rainydio
Last active Oct 18, 2019
Embed
What would you like to do?
// No exception should be thrown handling external message after it was accepted.
//
// Throwing exception reverts contract state, including replay protection
// mechanisms (such as seqno). It's trivial to spot external message that
// raised exception. That message then can be replayed as many times as one
// would like draining contract out of funds.
//
// Due to limited resources available it might be impossible to perform
// all neccessary actions until message is accepted. This particular problem
// was discussed in paper. And suggested approach is to use external message
// handler to perform basic authentication only. Once sender is authenticated
// message payload should be transfered to internal message queue.
//
// This way authentication and replay protection are decoupled from any futher
// processing actions. Exception raised durring processing will still cause
// some funds to be lost. But it would be impossible for anyone else to simply
// replay it again.
//
// Example contract below can never gest past seqno=1. And will loose funds
// processing every message.
"Asm.fif" include
"TonUtil.fif" include
<{
DUP -1 INT EQUAL <{
DROP
ACCEPT
// how many times to repeat expensive cell creation operation
// is sent through external message
8 PLDU <{ NEWC ENDC DROP }> PUSHCONT REPEAT
// incrementing seqno, and leaving previous seqno on stack
PUSHROOT CTOS 32 PLDU DUP INC NEWC 32 STU ENDC POPROOT
// throw unless it's constructor message (previous seqno is zero)
ISZERO 50 THROWIFNOT
}> PUSHCONT IFJMP
DUP 85143 INT EQUAL <{
DROP
PUSHROOT CTOS 32 PLDU
}> PUSHCONT IFJMP
}>c constant code
<b 0 32 u, b> constant data
<b 10 8 u, b> <s constant msg
data
msg -1 code <s 3 roll runvm
dup <s 32 u@ 1 <> abort"seqno != 1"
swap 0 <> abort"exception raised"
msg -1 code <s 3 roll runvm
dup <s 32 u@ 1 > abort"seqno > 1"
swap 50 <> abort"no exception raised"
nip
drop
<b b{0011} s, code ref, data ref, dictnew dict, b> constant stateinit
0 stateinit hashu 2constant address
// <b b{1000100} s, address addr, b{000010} s, stateinit <s s, b{0} s, msg s, b>
// 2 boc+>B "accept-drain-new.boc" B>file
<b b{1000100} s, address addr, 0 Gram, b{00} s, msg s, b>
2 boc+>B "accept-drain-query.boc" B>file
"lite-client -c 'last' -c 'getaccount " type address 7 smca>$ type "'" type cr
"lite-client -c 'last' -c 'runmethod " type address 7 smca>$ type " seqno'" type cr
"lite-client -c 'sendfile accept-drain-query.boc'" type cr
// lite-client -c 'last' -c 'getaccount 0QBV5M_m2s-8ZRT54CPx7_Ek3vWaj89OHlB9hNvFHxk78Ts8'
// lite-client -c 'last' -c 'runmethod 0QBV5M_m2s-8ZRT54CPx7_Ek3vWaj89OHlB9hNvFHxk78Ts8 seqno'
// lite-client -c 'sendfile accept-drain-query.boc'
// */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment