"TonUtil.fif" include // b body -- b' { tuck B B>boc } : load-boc // filename -- uint256 { dup ."Loading public key from file " type ."..." cr file>B dup Blen 32 <> abort"Public key must be exactly 32 bytes long" 256 B>u@ } : load-pubkey ' constant : const ' 2constant : 2const // D n -- uint { 0 -rot { drop swap 1+ swap -1 } dictmap drop } : dictlen // u D n -- s ? or ? { { swap 2 pick = { nip 0 } { drop -1 } cond } dictforeach dup ' nip if not } : dict[] { hole dup 1 ' @ does create 1 ' ! does create } : variable-set { hole hole 2dup 2 { @ swap @ swap } does create 2 { rot swap ! ! } does create } : 2variable-set 2variable-set wallet-addr wallet-addr! variable-set message-hash message-hash! variable-set message-contents message-contents! variable-set sig-count sig-count! // udata BSig ukey – ? { 256 u>B rot 256 u>B -rot ed25519_chksign } : ed25519_chksignuu // Inspects contents of cell provided on top of the stack // c -- // // defines/updates the following vars // // wallet-addr = u u // message-hash = B // message-contents = s { // Assuming the same external structure created by create.fif (simple external message) // // addr_none$00 = MsgAddressExt; // addr_extern$01 len:(## 9) external_address:(bits len) // = MsgAddressExt; // anycast_info$_ depth:(#<= 30) { depth >= 1 } // rewrite_pfx:(bits depth) = Anycast; // addr_std$10 anycast:(Maybe Anycast) // workchain_id:int8 address:bits256 = MsgAddressInt; // addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) // workchain_id:int32 address:(bits addr_len) = MsgAddressInt; // // ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt // import_fee:Grams = CommonMsgInfo; // // // message$_ {X:Type} info:CommonMsgInfo // init:(Maybe (Either StateInit ^StateInit)) // body:(Either X ^X) = Message X; // // // (external message) // // message$_ {X:Type} info:CommonMsgInfo // init:(Maybe (Either StateInit ^StateInit)) // body:(Either X ^X) = Message X; 68 7 u@+ swap 68 <> { ."There seems to be an invalid header" cr } if 8 i@+ 256 u@+ -rot 2dup wallet-addr! ."Wallet address: " .addr cr Gram@+ nip // Ignore grams 1 u@+ swap // init:(Maybe abort"This seems to be an init message" // body:(Either X ^X) 1 u@+ swap { ref@ c hashu dup x. cr message-hash! // modeMessage$0 mode:uint8 body:^(Message X) = ModeMessage X; // wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMessage X; 32 u@+ swap dup ."Expires: " . dup now < { ."(already EXPIRED!)" drop } { ."(in " now - . ."seconds)" } cond cr 32 u@+ swap ."Seqno: " . cr 1 u@+ swap { ."Is code message!" cr } { 8 u@+ swap ."Mode: " . cr // Now on to the actual message we're agreeing to sign // // int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool // src:MsgAddressInt dest:MsgAddressInt // value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams // created_lt:uint64 created_at:uint32 = CommonMsgInfo; // ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt // import_fee:Grams = CommonMsgInfo; // ext_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt // created_lt:uint64 created_at:uint32 = CommonMsgInfo; ."=>" cr ref@ 100 => 4 4 <> abort"Unsupported address!" // Make things simple for now 8 i@+ 256 u@+ -rot ."Destination address: " .addr cr Gram@+ swap ."Grams: " .GR cr } cond } cond drop } : inspect