1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-13 03:32:22 +00:00
ton/crypto/fift/lib/TonUtil.fif
ton c860ce3d1e updated smartcontracts
- updated smartcontracts
- updated fullnode database layout
- fixed memory leak in blockchain-explorer
- updated tonlib
2019-10-23 17:43:50 +04:00

150 lines
5.3 KiB
Text

library TonUtil // TON Blockchain Fift Library
"Lists.fif" include
-1 constant Masterchain
0 constant Basechain
// parse workchain id
// ( S -- workchain )
{ (number) 1- abort"workchain id must be an integer"
dup 32 fits not abort"workchain id must fit in 32 bits"
} : parse-workchain-id
{ (number) 1- abort"integer expected" } : parse-int
// Private key load/generate
// ( fname -- pubkey privkey )
{ dup ."Loading private key from file " type cr
file>B dup Blen 32 <> abort"Private key must be exactly 32 bytes long"
dup priv>pub swap
} : load-keypair
// ( fname -- pubkey privkey )
{ dup file-exists?
{ load-keypair }
{ dup newkeypair swap rot over swap B>file
rot ."Saved new private key to file " type cr
} cond
} : load-generate-keypair
// Parse smart-contract address
// ( S -- workchain addr bounce? )
{ $>smca not abort"invalid smart-contract address"
1 and 0=
} : parse-smc-addr
// ( wc addr -- ) Show address in <workchain>:<account> form
{ swap ._ .":" 64 0x. } : .addr
// ( wc addr flags -- ) Show address in base64url form
{ smca>$ type } : .Addr
// ( wc addr fname -- ) Save address to file in 36-byte format
{ -rot 256 u>B swap 32 i>B B+ swap B>file } : save-address
// ( wc addr fname -- ) Save address and print message
{ dup ."(Saving address to file " type .")" cr save-address
} : save-address-verbose
// ( fname -- wc addr ) Load address from file
{ file>B 32 B|
dup Blen { 32 B>i@ } { drop Basechain } cond
swap 256 B>u@
} : load-address
// ( fname -- wc addr ) Load address from file and print message
{ dup ."(Loading address from file " type .")" cr load-address
} : load-address-verbose
// Parse string as address or load address from file (if string is prefixed by @)
// ( S default-bounce -- workchain addr bounce? )
{ over $len 0= abort"empty smart-contract address"
swap dup 1 $| swap "@" $=
{ nip load-address rot } { drop nip parse-smc-addr } cond
} : parse-load-address
// ( hex-str -- addr ) Parses ADNL address
{ dup $len 64 <> abort"ADNL address must consist of exactly 64 hexadecimal characters"
(hex-number) 1 <> abort"ADNL address must consist of 64 hexadecimal characters"
dup 256 ufits not abort"invalid ADNL address"
} : parse-adnl-address
// ( b wc addr -- b' ) Serializes address into Builder b
{ -rot 8 i, swap 256 u, } : addr,
// Gram utilities
1000000000 constant Gram
{ Gram swap */r } : Gram*/
{ Gram * } : Gram*
// ( S -- nanograms )
{ (number) ?dup 0= abort"not a valid Gram amount"
1- ' Gram*/ ' Gram* cond
} : $>GR
{ bl word $>GR 1 'nop } ::_ GR$
// ( nanograms -- S )
{ dup abs <# ' # 9 times char . hold #s rot sign #>
nip -trailing0 } : (.GR)
{ (.GR) ."GR$" type space } : .GR
// b x -- b' ( serializes a Gram amount )
{ -1 { 1+ 2dup 8 * ufits } until
rot over 4 u, -rot 8 * u, } : Gram,
// s -- x s' ( deserializes a Gram amount )
{ 4 u@+ swap 8 * u@+ } : Gram@+
// s -- x
{ 4 u@+ swap 8 * u@ } : Gram@
// currency collections
// b x --> b' ( serializes a VarUInteger32 )
{ -1 { 1+ 2dup 8 * ufits } until
rot over 5 u, -rot 8 * u, } : VarUInt32,
// s --> x ( deserializes a VarUInteger32 )
{ 5 u@+ swap 8 * u@ } : VarUInt32@
32 constant cc-key-bits
' VarUInt32, : val,
' VarUInt32@ : val@
// d k v -- d'
{ <b swap val, b> <s swap rot cc-key-bits idict! not abort"cannot add key-value to CurrencyCollection" } : +ccpair
dictnew constant cc0 // zero currency collection
// ( v k -- d ) Creates currency collection representing v units of currency k
{ cc0 swap rot +ccpair } : of-cc
{ dictnew { over null? not } { swap uncons -rot unpair +ccpair } while nip } : list>cc
{ dup null? { ."(null) " drop } { val@ . } cond } dup : .maybeVarUInt32 : .val
{ cc-key-bits { swap 32 1<< rmod . ."-> " .val ."; " true } dictforeach drop cr } : .cc
{ cc-key-bits { rot . ."-> " swap .val .val ."; " true } dictdiff drop cr } : show-cc-diff
{ cc-key-bits { val@ swap val@ + val, true } dictmerge } : cc+
{ null swap cc-key-bits { val@ pair swap cons true } dictforeach drop } : cc>list-rev
{ cc>list-rev list-reverse } : cc>list
forget val, forget val@ forget .val
// Libraries
// ( -- D ) New empty library collection
' dictnew : Libs{
// ( D -- D ) Return library collection as dictionary
'nop : }Libs
// ( D c x -- D' ) Add a public/private library c to collection D
{ <b swap 1 u, over ref, b> <s swap hash rot 256 udict!+
0= abort"duplicate library in collection" } : lib+
// ( D c -- D' ) Add private library c to collection D
{ 0 lib+ } : private_lib
// ( D c -- D' ) Add public library c to collection D
{ 1 lib+ } : public_lib
// serialize simple transfers with long comments
// b B n -- b'
recursive append-long-bytes {
over Blen over <= { drop B, } {
B| <b swap 127 append-long-bytes b> -rot B, swap ref,
} cond
} swap !
// b S n -- b'
{ swap $>B swap append-long-bytes } : append-long-string
// S -- c
{ <b over $len { 0 32 u, swap 36 append-long-string } { nip } cond b>
} : simple-transfer-body
// ( S -- x ) parse public key
{ dup $len 48 <> abort"public key must be 48 characters long"
base64url>B dup Blen 36 <> abort"public key must be 48 characters long"
34 B| 16 B>u@ over crc16 <> abort"crc16 mismatch in public key"
16 B>u@+ 0x3ee6 <> abort"invalid tag in public key"
256 B>u@
} : parse-pubkey
{ bl word parse-pubkey 1 'nop } ::_ PK'
// ( x -- S ) serialize public key
{ 256 u>B B{3ee6} swap B+ dup crc16 16 u>B B+ B>base64 } : pubkey>$
{ pubkey>$ type } : .pubkey