"TonUtil.fif" include "lib.fif" include { ."usage: " @' $0 type ." [ ...]" cr cr ."Updates an existing multisignature wallet." cr ."The first of the keys must be a private key (with ID ), used to sign the wallet update request saved to .boc; the rest MUST be public keys." cr ."Create or generate public key files from private keys using gen-pub.fif privkey" cr cr ."Min (1-10) signatures required to send an order; load pre-existing public keys from files ." cr 1 halt } : usage $# 6 < ' usage if $1 constant file-base $2 constant update-file $3 parse-int constant msg-seqno $4 (number) 1 <> abort" must be a number!" constant n $5 (number) 1 <> abort" must be a number!" constant k $6 (number) 1 <> abort" must be a number!" constant key-id file-base +".addr" load-address 2dup 2constant wallet-addr ."Source wallet address = " 2dup .addr cr 6 .Addr cr 3 constant send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors 3 86400 * constant timeout // external message expires in 3 days n 1 < n 10 > or abort" must be between 1 and 10" k 1 < k 10 > or abort" must be between 1 and 10" k n <= not abort" must smaller than or equal to " $# 6 n + < abort"Not enough keys were provided in args!" $7 +".pk" load-generate-keypair const privkey 256 B>u@ 8 { dup $() +".pubkey" load-pubkey swap 1+ } n 1- times drop n tuple constant keys cr ."Updating pre-existing multisignature wallet with n=" n . ."k=" k . ."..." cr cr // idict! (v x s n – s0 −1 or s 0), adds a new value v (represented // by a Slice) with key given by signed big-endian n-bit integer x into // dictionary s with n-bit keys, and returns the new dictionary s0 and −1 // on success. Otherwise the unchanged dictionary s and 0 are returned. // Create dictionaries with keys and messages // Extract keys keys explode dup 1- // Create counter dictnew swap // ...and dict (swap the two) rot // Put length on top for times { dup 1- swap // Decrement counter 3 roll // Get n-th value v (val dict ncount curcount) udict! not abort"Failure storing dictionary value!" swap } swap times drop const keys-dict // code "wallet-code-update.fif" include // Create code message // codeMessage$1 minSigs:(## 4) keys:(HashmapE 4 PubKey) code:^Cell = ModeMessage X; // create wrapper message // wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMessage X; dup ."signing message: " u@+ swap 256 B>u@ swap // key ID => signature // multiSigWrapper$0 signatures:(HashmapE 4 Signature) message:(WrappedMessage X) = MultiSigWrapper X; // // 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; // dup ."resulting external message: " B dup Bx. cr update-file +".boc" tuck B>file ."Query expires in " timeout . ."seconds" cr ."(Saved to file " type .")" cr