2019-10-11 13:31:10 +02:00
|
|
|
|
"TonUtil.fif" include
|
|
|
|
|
|
2019-10-10 17:37:47 +02:00
|
|
|
|
// b body -- b'
|
|
|
|
|
{ tuck <s 2dup s-fits? not rot over 1 i, -rot
|
|
|
|
|
{ drop swap ref, } { s, nip } cond
|
2019-10-11 13:31:10 +02:00
|
|
|
|
} : maybe-ref,
|
2019-10-10 17:37:47 +02:00
|
|
|
|
|
|
|
|
|
// filename -- c
|
|
|
|
|
{ dup ."Loading order from file " type ."..." cr
|
|
|
|
|
file>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
|
|
|
|
|
|
2019-10-11 13:31:10 +02:00
|
|
|
|
' constant : const
|
2019-10-11 19:23:59 +02:00
|
|
|
|
' 2constant : 2const
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
|
|
|
|
// D n -- uint
|
|
|
|
|
{
|
|
|
|
|
0 -rot
|
2019-10-11 16:54:08 +02:00
|
|
|
|
{ drop swap 1+ swap -1 } dictmap drop
|
2019-10-11 13:31:10 +02:00
|
|
|
|
} : dictlen
|
|
|
|
|
|
2019-10-11 16:54:08 +02:00
|
|
|
|
// u D n -- s ? or ?
|
|
|
|
|
{
|
|
|
|
|
{ swap 2 pick = { nip 0 } { drop -1 } cond } dictforeach
|
|
|
|
|
dup ' nip if
|
|
|
|
|
not
|
|
|
|
|
} : dict[]
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
|
|
|
|
{ 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!
|
2019-10-11 16:54:08 +02:00
|
|
|
|
variable-set sig-count sig-count!
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
2019-10-11 16:54:08 +02:00
|
|
|
|
// udata BSig ukey – ?
|
|
|
|
|
{
|
|
|
|
|
256 u>B rot 256 u>B -rot ed25519_chksign
|
|
|
|
|
} : ed25519_chksignuu
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
//
|
|
|
|
|
// <b b{1000100} s, wallet-addr addr, 0 Gram, b{00} s,
|
|
|
|
|
// swap <s s, b>
|
|
|
|
|
// (external message)
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// message$_ {X:Type} info:CommonMsgInfo
|
|
|
|
|
// init:(Maybe (Either StateInit ^StateInit))
|
|
|
|
|
// body:(Either X ^X) = Message X;
|
|
|
|
|
<s dup csr. cr
|
|
|
|
|
// External message
|
|
|
|
|
// ext_in_msg_info$10 src:MsgAddressExt (addr_none$00) dest:MsgAddressInt (addr_std$10 anycast 0) ... import_fee:Grams = CommonMsgInfo;
|
|
|
|
|
// 10 00 10 0
|
|
|
|
|
// 1000100 => 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@ <s } if // Load ref
|
|
|
|
|
dup message-contents!
|
|
|
|
|
|
|
|
|
|
// multiSigWrapper$0 signatures:(HashmapE 4 Signature) message:(WrappedMessage X) = MultiSigWrapper X;
|
|
|
|
|
1 u@+ swap
|
|
|
|
|
dup ."Message version: " . cr
|
|
|
|
|
abort"Unsupported message version!"
|
|
|
|
|
|
|
|
|
|
dict@+ swap
|
|
|
|
|
dup null? abort"Empty signature list!"
|
2019-10-11 16:54:08 +02:00
|
|
|
|
dup 4 dictlen sig-count!
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
|
|
|
|
."Signed by the following keys: "
|
2019-10-11 19:26:22 +02:00
|
|
|
|
4 { drop . ."- " -1 } dictforeach cr drop
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
|
|
|
|
."Hash: " dup s>c hashu dup x. cr
|
|
|
|
|
message-hash!
|
|
|
|
|
|
2019-10-11 16:54:08 +02:00
|
|
|
|
// modeMessage$0 mode:uint8 body:^(Message X) = ModeMessage X;
|
2019-10-11 13:31:10 +02:00
|
|
|
|
// 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
|
|
|
|
|
|
2019-10-11 16:54:08 +02:00
|
|
|
|
1 u@+ swap
|
2019-10-11 19:23:59 +02:00
|
|
|
|
{ ."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@ <s
|
2019-10-11 13:31:10 +02:00
|
|
|
|
|
|
|
|
|
1 u@+ swap
|
2019-10-11 19:23:59 +02:00
|
|
|
|
{ // External message *$1*
|
|
|
|
|
."Inside: external message" cr
|
|
|
|
|
}
|
|
|
|
|
{ // Internal message int_msg_info$0
|
|
|
|
|
."Inside: internal message" cr
|
|
|
|
|
1 u@+ swap
|
|
|
|
|
."Instant hypercube routing disabled? " . cr
|
|
|
|
|
|
|
|
|
|
1 u@+ swap
|
|
|
|
|
."Bounce flag set? " . cr
|
|
|
|
|
|
|
|
|
|
1 u@+ swap
|
|
|
|
|
// ."Bounced flag set? " . cr
|
|
|
|
|
drop
|
|
|
|
|
|
|
|
|
|
2 u@+ nip // Drop src address constructor + flags
|
|
|
|
|
|
|
|
|
|
3 u@+ swap // Read dst address constructor + flags
|
|
|
|
|
// addr_std$10 anycast 0 => 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
|
2019-10-11 13:31:10 +02:00
|
|
|
|
} cond
|
|
|
|
|
drop
|
|
|
|
|
} : inspect
|