mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
minor improvements and bugfixes
This commit is contained in:
parent
eecf05ca59
commit
040df63c98
24 changed files with 665 additions and 344 deletions
|
@ -94,41 +94,41 @@ WordList& WordList::append(const std::vector<Ref<WordDef>>& other) {
|
|||
}
|
||||
|
||||
//
|
||||
// WordRef
|
||||
// DictEntry
|
||||
//
|
||||
|
||||
WordRef::WordRef(Ref<WordDef> _def, bool _act) : def(std::move(_def)), active(_act) {
|
||||
DictEntry::DictEntry(Ref<WordDef> _def, bool _act) : def(std::move(_def)), active(_act) {
|
||||
}
|
||||
|
||||
WordRef::WordRef(StackWordFunc func) : def(Ref<StackWord>{true, std::move(func)}), active(false) {
|
||||
DictEntry::DictEntry(StackWordFunc func) : def(Ref<StackWord>{true, std::move(func)}), active(false) {
|
||||
}
|
||||
|
||||
WordRef::WordRef(CtxWordFunc func, bool _act) : def(Ref<CtxWord>{true, std::move(func)}), active(_act) {
|
||||
DictEntry::DictEntry(CtxWordFunc func, bool _act) : def(Ref<CtxWord>{true, std::move(func)}), active(_act) {
|
||||
}
|
||||
|
||||
WordRef::WordRef(CtxTailWordFunc func, bool _act) : def(Ref<CtxTailWord>{true, std::move(func)}), active(_act) {
|
||||
DictEntry::DictEntry(CtxTailWordFunc func, bool _act) : def(Ref<CtxTailWord>{true, std::move(func)}), active(_act) {
|
||||
}
|
||||
|
||||
Ref<WordDef> WordRef::get_def() const & {
|
||||
Ref<WordDef> DictEntry::get_def() const& {
|
||||
return def;
|
||||
}
|
||||
|
||||
Ref<WordDef> WordRef::get_def() && {
|
||||
Ref<WordDef> DictEntry::get_def() && {
|
||||
return std::move(def);
|
||||
}
|
||||
|
||||
void WordRef::operator()(IntCtx& ctx) const {
|
||||
void DictEntry::operator()(IntCtx& ctx) const {
|
||||
def->run(ctx);
|
||||
}
|
||||
|
||||
bool WordRef::is_active() const {
|
||||
bool DictEntry::is_active() const {
|
||||
return active;
|
||||
}
|
||||
|
||||
//
|
||||
// Dictionary
|
||||
//
|
||||
WordRef* Dictionary::lookup(td::Slice name) {
|
||||
DictEntry* Dictionary::lookup(td::Slice name) {
|
||||
auto it = words_.find(name);
|
||||
if (it == words_.end()) {
|
||||
return nullptr;
|
||||
|
@ -153,7 +153,7 @@ void Dictionary::def_ctx_tail_word(std::string name, CtxTailWordFunc func) {
|
|||
def_word(std::move(name), std::move(func));
|
||||
}
|
||||
|
||||
void Dictionary::def_word(std::string name, WordRef word) {
|
||||
void Dictionary::def_word(std::string name, DictEntry word) {
|
||||
auto res = words_.emplace(name, std::move(word));
|
||||
LOG_IF(FATAL, !res.second) << "Cannot redefine word: " << name;
|
||||
}
|
||||
|
|
|
@ -110,34 +110,34 @@ class WordList : public WordDef {
|
|||
}
|
||||
};
|
||||
|
||||
class WordRef {
|
||||
class DictEntry {
|
||||
Ref<WordDef> def;
|
||||
bool active;
|
||||
|
||||
public:
|
||||
WordRef() = delete;
|
||||
WordRef(const WordRef& ref) = default;
|
||||
WordRef(WordRef&& ref) = default;
|
||||
WordRef(Ref<WordDef> _def, bool _act = false);
|
||||
WordRef(StackWordFunc func);
|
||||
WordRef(CtxWordFunc func, bool _act = false);
|
||||
WordRef(CtxTailWordFunc func, bool _act = false);
|
||||
//WordRef(const std::vector<Ref<WordDef>>& word_list);
|
||||
//WordRef(std::vector<Ref<WordDef>>&& word_list);
|
||||
WordRef& operator=(const WordRef&) = default;
|
||||
WordRef& operator=(WordRef&&) = default;
|
||||
Ref<WordDef> get_def() const &;
|
||||
DictEntry() = delete;
|
||||
DictEntry(const DictEntry& ref) = default;
|
||||
DictEntry(DictEntry&& ref) = default;
|
||||
DictEntry(Ref<WordDef> _def, bool _act = false);
|
||||
DictEntry(StackWordFunc func);
|
||||
DictEntry(CtxWordFunc func, bool _act = false);
|
||||
DictEntry(CtxTailWordFunc func, bool _act = false);
|
||||
//DictEntry(const std::vector<Ref<WordDef>>& word_list);
|
||||
//DictEntry(std::vector<Ref<WordDef>>&& word_list);
|
||||
DictEntry& operator=(const DictEntry&) = default;
|
||||
DictEntry& operator=(DictEntry&&) = default;
|
||||
Ref<WordDef> get_def() const&;
|
||||
Ref<WordDef> get_def() &&;
|
||||
void operator()(IntCtx& ctx) const;
|
||||
bool is_active() const;
|
||||
~WordRef() = default;
|
||||
~DictEntry() = default;
|
||||
};
|
||||
|
||||
/*
|
||||
WordRef::WordRef(const std::vector<Ref<WordDef>>& word_list) : def(Ref<WordList>{true, word_list}) {
|
||||
DictEntry::DictEntry(const std::vector<Ref<WordDef>>& word_list) : def(Ref<WordList>{true, word_list}) {
|
||||
}
|
||||
|
||||
WordRef::WordRef(std::vector<Ref<WordDef>>&& word_list) : def(Ref<WordList>{true, std::move(word_list)}) {
|
||||
DictEntry::DictEntry(std::vector<Ref<WordDef>>&& word_list) : def(Ref<WordList>{true, std::move(word_list)}) {
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -149,12 +149,12 @@ WordRef::WordRef(std::vector<Ref<WordDef>>&& word_list) : def(Ref<WordList>{true
|
|||
|
||||
class Dictionary {
|
||||
public:
|
||||
WordRef* lookup(td::Slice name);
|
||||
DictEntry* lookup(td::Slice name);
|
||||
void def_ctx_word(std::string name, CtxWordFunc func);
|
||||
void def_ctx_tail_word(std::string name, CtxTailWordFunc func);
|
||||
void def_active_word(std::string name, CtxWordFunc func);
|
||||
void def_stack_word(std::string name, StackWordFunc func);
|
||||
void def_word(std::string name, WordRef word);
|
||||
void def_word(std::string name, DictEntry word);
|
||||
void undef_word(td::Slice name);
|
||||
|
||||
auto begin() const {
|
||||
|
@ -167,7 +167,7 @@ class Dictionary {
|
|||
static Ref<WordDef> nop_word_def;
|
||||
|
||||
private:
|
||||
std::map<std::string, WordRef, std::less<>> words_;
|
||||
std::map<std::string, DictEntry, std::less<>> words_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -171,26 +171,26 @@ void IntCtx::skipspc(bool skip_eol) {
|
|||
} while (load_next_line());
|
||||
}
|
||||
|
||||
void check_compile(const IntCtx& ctx) {
|
||||
if (ctx.state <= 0) {
|
||||
void IntCtx::check_compile() const {
|
||||
if (state <= 0) {
|
||||
throw IntError{"compilation mode only"};
|
||||
}
|
||||
}
|
||||
|
||||
void check_execute(const IntCtx& ctx) {
|
||||
if (ctx.state != 0) {
|
||||
void IntCtx::check_execute() const {
|
||||
if (state != 0) {
|
||||
throw IntError{"interpret mode only"};
|
||||
}
|
||||
}
|
||||
|
||||
void check_not_int_exec(const IntCtx& ctx) {
|
||||
if (ctx.state < 0) {
|
||||
void IntCtx::check_not_int_exec() const {
|
||||
if (state < 0) {
|
||||
throw IntError{"not allowed in internal interpret mode"};
|
||||
}
|
||||
}
|
||||
|
||||
void check_int_exec(const IntCtx& ctx) {
|
||||
if (ctx.state >= 0) {
|
||||
void IntCtx::check_int_exec() const {
|
||||
if (state >= 0) {
|
||||
throw IntError{"internal interpret mode only"};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,12 +141,12 @@ struct IntCtx {
|
|||
Savepoint(IntCtx& _ctx, std::string new_filename, std::string new_current_dir, std::istream* new_input_stream);
|
||||
~Savepoint();
|
||||
};
|
||||
};
|
||||
|
||||
void check_compile(const IntCtx& ctx);
|
||||
void check_execute(const IntCtx& ctx);
|
||||
void check_not_int_exec(const IntCtx& ctx);
|
||||
void check_int_exec(const IntCtx& ctx);
|
||||
void check_compile() const;
|
||||
void check_execute() const;
|
||||
void check_not_int_exec() const;
|
||||
void check_int_exec() const;
|
||||
};
|
||||
|
||||
td::StringBuilder& operator<<(td::StringBuilder& os, const IntCtx& ctx);
|
||||
std::ostream& operator<<(std::ostream& os, const IntCtx& ctx);
|
||||
|
|
|
@ -1782,7 +1782,7 @@ void interpret_wordlist_begin_aux(vm::Stack& stack) {
|
|||
}
|
||||
|
||||
void interpret_wordlist_begin(IntCtx& ctx) {
|
||||
check_not_int_exec(ctx);
|
||||
ctx.check_not_int_exec();
|
||||
interpret_wordlist_begin_aux(ctx.stack);
|
||||
push_argcount(ctx, 0);
|
||||
++(ctx.state);
|
||||
|
@ -1795,20 +1795,20 @@ void interpret_wordlist_end_aux(vm::Stack& stack) {
|
|||
}
|
||||
|
||||
void interpret_wordlist_end(IntCtx& ctx) {
|
||||
check_compile(ctx);
|
||||
ctx.check_compile();
|
||||
interpret_wordlist_end_aux(ctx.stack);
|
||||
push_argcount(ctx, 1);
|
||||
--(ctx.state);
|
||||
}
|
||||
|
||||
void interpret_internal_interpret_begin(IntCtx& ctx) {
|
||||
check_compile(ctx);
|
||||
ctx.check_compile();
|
||||
push_argcount(ctx, 0);
|
||||
ctx.state = -ctx.state;
|
||||
}
|
||||
|
||||
void interpret_internal_interpret_end(IntCtx& ctx) {
|
||||
check_int_exec(ctx);
|
||||
ctx.check_int_exec();
|
||||
ctx.state = -ctx.state;
|
||||
ctx.stack.push({vm::from_object, Dictionary::nop_word_def});
|
||||
}
|
||||
|
@ -1830,9 +1830,9 @@ void interpret_create_aux(IntCtx& ctx, int mode) {
|
|||
bool active = (mode & 1);
|
||||
auto entry = ctx.dictionary->lookup(word);
|
||||
if (entry) {
|
||||
*entry = WordRef{wd_ref, active}; // redefine word
|
||||
*entry = DictEntry{std::move(wd_ref), active}; // redefine word
|
||||
} else {
|
||||
ctx.dictionary->def_word(std::move(word), {wd_ref, active});
|
||||
ctx.dictionary->def_word(std::move(word), {std::move(wd_ref), active});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -235,29 +235,7 @@ variable special-dict
|
|||
// restricted wallet creation
|
||||
|
||||
// same as in new-wallet-v3.fif
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL OVER 78748 INT EQUAL OR IFJMP:<{ // "seqno" and "get_public_key" get-methods
|
||||
1 INT AND c4 PUSHCTR CTOS 32 LDU 32 LDU NIP 256 PLDU CONDSEL // cnt or pubk
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
9 PUSHPOW2 LDSLICEX DUP 32 LDU 32 LDU 32 LDU // signature in_msg subwallet_id valid_until msg_seqno cs
|
||||
NOW s1 s3 XCHG LEQ 35 THROWIF // signature in_msg subwallet_id cs msg_seqno
|
||||
c4 PUSH CTOS 32 LDU 32 LDU 256 LDU ENDS // signature in_msg subwallet_id cs msg_seqno stored_seqno stored_subwallet public_key
|
||||
s3 s2 XCPU EQUAL 33 THROWIFNOT // signature in_msg subwallet_id cs public_key stored_seqno stored_subwallet
|
||||
s4 s4 XCPU EQUAL 34 THROWIFNOT // signature in_msg stored_subwallet cs public_key stored_seqno
|
||||
s0 s4 XCHG HASHSU // signature stored_seqno stored_subwallet cs public_key msg_hash
|
||||
s0 s5 s5 XC2PU // public_key stored_seqno stored_subwallet cs msg_hash signature public_key
|
||||
CHKSIGNU 35 THROWIFNOT // public_key stored_seqno stored_subwallet cs
|
||||
ACCEPT
|
||||
WHILE:<{
|
||||
DUP SREFS // public_key stored_seqno stored_subwallet cs _51
|
||||
}>DO<{ // public_key stored_seqno stored_subwallet cs
|
||||
8 LDU LDREF s0 s2 XCHG // public_key stored_seqno stored_subwallet cs _56 mode
|
||||
SENDRAWMSG
|
||||
}> // public_key stored_seqno stored_subwallet cs
|
||||
ENDS SWAP INC // public_key stored_subwallet seqno'
|
||||
NEWC 32 STU 32 STU 256 STU ENDC c4 POP
|
||||
}>c
|
||||
"wallet-v3-code.fif" include
|
||||
=: WCode3
|
||||
|
||||
"auto/wallet-code.fif" include =: WCode0
|
||||
|
|
|
@ -26,7 +26,7 @@ $5 base64>B dup Blen 64 <> abort"validator Ed25519 signature must be exactly 64
|
|||
=: signature
|
||||
$6 savefile replace-if-null =: savefile
|
||||
|
||||
."Creating the body of an internal message to be sent to the elections smart contract" cr }
|
||||
."Creating the body of an internal message to be sent to the elections smart contract" cr
|
||||
."containing a signed request to vote for complaint 0x" compl-hash 64x. ."of past validator set " elect-id .
|
||||
."on behalf of current validator with index " val-idx . "and public key" pubkey Bx. cr
|
||||
|
||||
|
|
|
@ -318,6 +318,19 @@ _ ~credit_to(credits, addr, amount) inline_ref {
|
|||
return (credits, recovered + tot_bonuses - returned_bonuses);
|
||||
}
|
||||
|
||||
int stakes_sum(frozen_dict) inline_ref {
|
||||
var total = 0;
|
||||
var pubkey = -1;
|
||||
do {
|
||||
(pubkey, var cs, var f) = frozen_dict.udict_get_next?(256, pubkey);
|
||||
if (f) {
|
||||
cs~skip_bits(256 + 64);
|
||||
total += cs~load_grams();
|
||||
}
|
||||
} until (~ f);
|
||||
return total;
|
||||
}
|
||||
|
||||
_ unfreeze_all(credits, past_elections, elect_id) inline_ref {
|
||||
var (fs, f) = past_elections~udict_delete_get?(32, elect_id);
|
||||
ifnot (f) {
|
||||
|
@ -325,6 +338,7 @@ _ unfreeze_all(credits, past_elections, elect_id) inline_ref {
|
|||
return (credits, past_elections, 0);
|
||||
}
|
||||
var (unfreeze_at, stake_held, vset_hash, fdict, tot_stakes, bonuses, complaints) = fs.unpack_past_election();
|
||||
;; tot_stakes = fdict.stakes_sum(); ;; TEMP BUGFIX
|
||||
var unused_prizes = (bonuses > 0) ?
|
||||
credits~unfreeze_with_bonuses(fdict, tot_stakes, bonuses) :
|
||||
credits~unfreeze_without_bonuses(fdict, tot_stakes);
|
||||
|
@ -468,7 +482,7 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
var (_, bits, refs) = slice_compute_data_size(complaint, 4096);
|
||||
var pps = (bits + 1024) * bit_price + (refs + 2) * cell_price;
|
||||
paid = pps * expire_in + deposit;
|
||||
if (paid + (1 << 30) < msg_value) { ;; not enough money
|
||||
if (msg_value < paid + (1 << 30)) { ;; not enough money
|
||||
return -5;
|
||||
}
|
||||
;; re-pack modified complaint
|
||||
|
@ -503,12 +517,12 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
return paid;
|
||||
}
|
||||
|
||||
(cell, cell, int) punish(credits, frozen, complaint) inline_ref {
|
||||
(cell, cell, int, int) punish(credits, frozen, complaint) inline_ref {
|
||||
var (validator_pubkey, description, created_at, severity, reward_addr, paid, suggested_fine, suggested_fine_part) = complaint.begin_parse().unpack_complaint();
|
||||
var (cs, f) = frozen.udict_get?(256, validator_pubkey);
|
||||
ifnot (f) {
|
||||
;; no validator to punish
|
||||
return (credits, frozen, 0);
|
||||
return (credits, frozen, 0, 0);
|
||||
}
|
||||
var (addr, weight, stake, banned) = (cs~load_uint(256), cs~load_uint(64), cs~load_grams(), cs~load_int(1));
|
||||
cs.end_parse();
|
||||
|
@ -520,9 +534,8 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
.store_grams(stake)
|
||||
.store_int(banned, 1));
|
||||
int reward = min(fine >> 3, paid * 8);
|
||||
fine -= reward;
|
||||
credits~credit_to(reward_addr, reward);
|
||||
return (credits, frozen, fine);
|
||||
return (credits, frozen, fine - reward, fine);
|
||||
}
|
||||
|
||||
(cell, cell, int) register_vote(complaints, chash, idx, weight) inline_ref {
|
||||
|
@ -534,7 +547,12 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
var (cur_vset, total_weight, _) = get_current_vset();
|
||||
int cur_vset_id = cur_vset.cell_hash();
|
||||
var (complaint, voters, vset_id, weight_remaining) = unpack_complaint_status(cstatus);
|
||||
if (vset_id != cur_vset_id) {
|
||||
int vset_old? = (vset_id != cur_vset_id);
|
||||
if ((weight_remaining < 0) & vset_old?) {
|
||||
;; previous validator set already collected 2/3 votes, skip new votes
|
||||
return (complaints, null(), -3);
|
||||
}
|
||||
if (vset_old?) {
|
||||
;; complaint votes belong to a previous validator set, reset voting
|
||||
vset_id = cur_vset_id;
|
||||
voters = null();
|
||||
|
@ -572,10 +590,11 @@ int proceed_register_vote(election_id, chash, idx, weight) impure inline_ref {
|
|||
return status;
|
||||
}
|
||||
ifnot (accepted_complaint.null?()) {
|
||||
(credits, frozen_dict, int fine) = punish(credits, frozen_dict, accepted_complaint);
|
||||
grams += fine;
|
||||
(credits, frozen_dict, int fine_unalloc, int fine_collected) = punish(credits, frozen_dict, accepted_complaint);
|
||||
grams += fine_unalloc;
|
||||
total_stake -= fine_collected;
|
||||
}
|
||||
past_elections.udict_set_builder(32, election_id, pack_past_election(unfreeze_at, stake_held, vset_hash, frozen_dict, total_stake, bonuses, complaints));
|
||||
past_elections~udict_set_builder(32, election_id, pack_past_election(unfreeze_at, stake_held, vset_hash, frozen_dict, total_stake, bonuses, complaints));
|
||||
store_data(elect, credits, past_elections, grams, active_id, active_hash);
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@ file>B B>boc dup =: complaint hash =: c-hash
|
|||
complaint <s 8 u@ 0xbc <> abort"Not a valid ValidatorComplaint"
|
||||
complaint <s csr.
|
||||
|
||||
." complaint envelope will expire at " expire-at . ."(in " expire-in . ."seconds)" cr
|
||||
// ." complaint envelope will expire at " expire-at . ."(in " expire-in . ."seconds)" cr
|
||||
now 32 << c-hash 0xffffffff and or =: query-id
|
||||
."Query id is " query-id . cr
|
||||
|
||||
<b x{52674370} s, query-id 64 u, election-id 32 u, expire-at 32 u,
|
||||
<b x{52674370} s, query-id 64 u, election-id 32 u,
|
||||
complaint <s s, b>
|
||||
|
||||
dup ."resulting internal message body: " <s csr. cr
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#!/usr/bin/create-state -s
|
||||
"TonUtil.fif" include
|
||||
"Asm.fif" include
|
||||
"Lists.fif" include
|
||||
|
||||
def? $1 { @' $1 } { "" } cond constant suffix
|
||||
{ suffix $+ } : +suffix
|
||||
256 1<<1- 15 / constant AllOnes
|
||||
|
||||
wc_master setworkchain
|
||||
-17 setglobalid // negative value means a test instance of the blockchain
|
||||
-239 setglobalid // negative value means a test instance of the blockchain
|
||||
|
||||
// Initial state of Workchain 0 (Basic workchain)
|
||||
|
||||
|
@ -16,30 +19,35 @@ dup dup 31 boc+>B dup Bx. cr
|
|||
dup "basestate0" +suffix +".boc" tuck B>file
|
||||
."(Initial basechain state saved to file " type .")" cr
|
||||
Bhashu dup =: basestate0_fhash
|
||||
."file hash=" dup x. space 256 u>B dup B>base64url type cr
|
||||
."file hash=" dup 64x. space 256 u>B dup B>base64url type cr
|
||||
"basestate0" +suffix +".fhash" B>file
|
||||
hashu dup =: basestate0_rhash
|
||||
."root hash=" dup x. space 256 u>B dup B>base64url type cr
|
||||
."root hash=" dup 64x. space 256 u>B dup B>base64url type cr
|
||||
"basestate0" +suffix +".rhash" B>file
|
||||
|
||||
basestate0_rhash basestate0_fhash now 0 2 32 0 add-std-workchain
|
||||
// root-hash file-hash start-at actual-min-split min-split-depth max-split-depth wc-id
|
||||
basestate0_rhash basestate0_fhash now 0 4 8 0 add-std-workchain
|
||||
config.workchains!
|
||||
|
||||
// SmartContract #1 (Simple wallet)
|
||||
|
||||
<{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP 8 LDU LDREF ENDS // pubk cnt mode msg
|
||||
SWAP SENDRAWMSG // pubk cnt ; ( message sent )
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP 8 LDU LDREF ENDS // pubk cnt mode msg
|
||||
SWAP SENDRAWMSG // pubk cnt ; ( message sent )
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
}>c
|
||||
// code
|
||||
<b 0 32 u,
|
||||
|
@ -50,10 +58,11 @@ Libs{
|
|||
x{ABACABADABACABA} s>c public_lib
|
||||
x{1234} x{5678} |_ s>c private_lib
|
||||
}Libs // libraries
|
||||
GR$1700000000 // balance
|
||||
GR$4999990000 // balance
|
||||
0 // split_depth
|
||||
0 // ticktock
|
||||
2 // mode: create
|
||||
AllOnes 0 * // address
|
||||
6 // mode: create+setaddr
|
||||
register_smc
|
||||
dup make_special dup constant smc1_addr
|
||||
Masterchain over
|
||||
|
@ -61,7 +70,11 @@ Masterchain over
|
|||
"main-wallet" +suffix +".addr" save-address-verbose
|
||||
|
||||
// SmartContract #2 (Simple money giver for test network)
|
||||
<{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
32 LDU SWAP // cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU ENDS // cs cnt cnt'
|
||||
TUCK EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
|
@ -74,8 +87,8 @@ Masterchain over
|
|||
// code
|
||||
<b 0 32 u, b> // data
|
||||
empty_cell // libraries
|
||||
GR$1000000 // initial balance (1m test Grams)
|
||||
0 0 2 register_smc
|
||||
GR$1000 // initial balance (1k test Grams)
|
||||
0 0 AllOnes 6 * 6 register_smc
|
||||
dup make_special dup constant smc2_addr
|
||||
Masterchain over
|
||||
2dup ."free test gram giver address = " .addr cr 2dup 6 .Addr cr
|
||||
|
@ -112,60 +125,95 @@ Libs{
|
|||
x{ABACABADABACABA} s>c public_lib
|
||||
x{1234} x{5678} |_ s>c public_lib
|
||||
}Libs // libraries
|
||||
0x333333333 // balance
|
||||
GR$666 // balance
|
||||
0 // split_depth
|
||||
3 // ticktock: tick
|
||||
2 // mode: create
|
||||
register_smc
|
||||
dup make_special dup constant smc3_addr
|
||||
."address = " x. cr
|
||||
."address = " 64x. cr
|
||||
|
||||
// SmartContract #4 (elector)
|
||||
/*
|
||||
*
|
||||
* SmartContract #4 (elector)
|
||||
*
|
||||
*/
|
||||
"auto/elector-code.fif" include // code in separate source file
|
||||
<b 0 1 1+ 1+ 5 + u, 0 256 u, b> // data
|
||||
<b 0 1 1+ 1+ 4 + 32 + u, 0 256 u, b> // data: dict dict dict grams uint32 uint256
|
||||
empty_cell // libraries
|
||||
GR$10 // balance: 10 grams
|
||||
0 // split_depth
|
||||
1 // ticktock: tick
|
||||
2 // mode: create
|
||||
2 // ticktock: tick
|
||||
AllOnes 3 * // address: -1:333...333
|
||||
6 // mode: create + setaddr
|
||||
register_smc
|
||||
dup make_special dup constant smc4_addr dup constant elector_addr
|
||||
Masterchain swap
|
||||
."elector smart contract address = " 2dup .addr cr 2dup 7 .Addr cr
|
||||
"elector" +suffix +".addr" save-address-verbose
|
||||
|
||||
// Configuration Parameters
|
||||
|
||||
/*
|
||||
*
|
||||
* Configuration Parameters
|
||||
*
|
||||
*/
|
||||
// version capabilities
|
||||
1 capCreateStats capBounceMsgBody or capReportVersion or capShortDequeue or config.version!
|
||||
// max-validators max-main-validators min-validators
|
||||
// 9 3 2 config.validator_num!
|
||||
1000 100 5 config.validator_num!
|
||||
// 9 4 1 config.validator_num!
|
||||
1000 100 13 config.validator_num!
|
||||
// min-stake max-stake min-total-stake max-factor
|
||||
GR$10000 GR$10000000 GR$1000000 sg~10 config.validator_stake_limits!
|
||||
GR$10000 GR$10000000 GR$500000 sg~3 config.validator_stake_limits!
|
||||
// elected-for elect-start-before elect-end-before stakes-frozen-for
|
||||
400000 200000 4000 400000 config.election_params!
|
||||
// 400000 200000 4000 400000 config.election_params!
|
||||
// 4000 2000 500 1000 config.election_params! // DEBUG
|
||||
65536 32768 8192 32768 config.election_params! // TestNet DEBUG
|
||||
// config-addr = -1:5555...5555
|
||||
AllOnes 5 * constant config_addr
|
||||
config_addr config.config_smc!
|
||||
// elector-addr
|
||||
elector_addr config.elector_smc!
|
||||
|
||||
1 sg* 100 sg* 1000 sg* 1000000 sg* config.storage_prices!
|
||||
// 1 sg* 100 sg* 1000 sg* 1000000 sg* config.storage_prices! // old values (too high)
|
||||
1 500 1000 500000 config.storage_prices!
|
||||
config.special!
|
||||
|
||||
// gas_price gas_limit gas_credit block_gas_limit freeze_due_limit delete_due_limit --
|
||||
1000 sg* 1000000 10000 10000000 GR$0.1 GR$1.0 config.gas_prices!
|
||||
10000 sg* 1000000 10000 10000000 GR$0.1 GR$1.0 config.mc_gas_prices!
|
||||
// gas_price gas_limit special_gas_limit gas_credit block_gas_limit freeze_due_limit delete_due_limit flat_gas_limit flat_gas_price --
|
||||
1000 sg* 1 *M dup 10000 10 *M GR$0.1 GR$1.0 1000 1000000 config.gas_prices!
|
||||
10000 sg* 1 *M 10 *M 10000 10 *M GR$0.1 GR$1.0 1000 10000000 config.mc_gas_prices!
|
||||
// lump_price bit_price cell_price ihr_factor first_frac next_frac
|
||||
1000000 1000 sg* 100000 sg* 3/2 sg*/ 1/3 sg*/ 1/3 sg*/ config.fwd_prices!
|
||||
10000000 10000 sg* 1000000 sg* 3/2 sg*/ 1/3 sg*/ 1/3 sg*/ config.mc_fwd_prices!
|
||||
// mc-cc-lifetime sh-cc-lifetime sh-val-lifetime sh-val-num
|
||||
250 250 1000 7 config.catchain_params!
|
||||
// mc-cc-lifetime sh-cc-lifetime sh-val-lifetime sh-val-num mc-shuffle
|
||||
250 250 1000 7 true config.catchain_params!
|
||||
// round-candidates next-cand-delay-ms consensus-timeout-ms fast-attempts attempt-duration cc-max-deps max-block-size max-collated-size new-cc-ids
|
||||
3 2000 16000 3 8 4 2 *Mi 2 *Mi true config.consensus_params!
|
||||
|
||||
128 *Ki 512 *Ki 1 *Mi triple // [ underload soft hard ] : block bytes limit
|
||||
100000 500000 1000000 triple // gas limits
|
||||
1000 5000 10000 triple // lt limits
|
||||
|
||||
128 *Ki 512 *Ki 1 *Mi triple // [ underload soft hard ] : block bytes limit
|
||||
2000000 10000000 20000000 triple // gas limits
|
||||
1000 5000 10000 triple // lt limits
|
||||
triple dup untriple config.mc_block_limits!
|
||||
untriple config.block_limits!
|
||||
|
||||
GR$1.7 GR$1 config.block_create_fees!
|
||||
smc1_addr config.collector_smc!
|
||||
// smc1_addr config.collector_smc!
|
||||
smc1_addr config.minter_smc!
|
||||
|
||||
1000000000000 -17 of-cc 666666666666 239 of-cc cc+ config.to_mint!
|
||||
|
||||
( 0 1 9 10 12 14 15 16 17 18 20 21 22 23 24 25 28 34 ) config.mandatory_params!
|
||||
( -999 -1000 -1001 0 1 9 10 12 14 15 16 17 32 34 36 ) config.critical_params!
|
||||
|
||||
// [ min_tot_rounds max_tot_rounds min_wins max_losses min_store_sec max_store_sec bit_pps cell_pps ]
|
||||
// first for ordinary proposals, then for critical proposals
|
||||
_( 2 3 2 2 1000000 10000000 1 500 )
|
||||
_( 4 7 4 2 5000000 20000000 2 1000 )
|
||||
config.param_proposals_setup!
|
||||
|
||||
// deposit bit_pps cell_pps
|
||||
GR$100 1 500 config.complaint_prices!
|
||||
|
||||
"validator-keys" +suffix +".pub" file>B
|
||||
{ dup Blen } { 32 B| swap dup ."Validator public key = " Bx. cr
|
||||
17 add-validator } while drop
|
||||
|
@ -173,66 +221,57 @@ smc1_addr config.minter_smc!
|
|||
// 17 add-validator
|
||||
// newkeypair nip dup ."Validator #2 public key = " Bx. cr
|
||||
// 239 add-validator
|
||||
now dup 1000000 + 0 config.validators!
|
||||
100000 =: orig_vset_valid_for // original validator set valid 100000 seconds
|
||||
now dup orig_vset_valid_for + 0 config.validators!
|
||||
|
||||
// SmartContract #5 (Config)
|
||||
PROGRAM{
|
||||
recv_internal x{} PROC
|
||||
recv_external PROC:<{
|
||||
512 INT LDSLICEX DUP 32 LDU 32 PLDU // sign cs cnt valid-until
|
||||
NOW LEQ 35 THROWIF // ( fail if now >= valid-until )
|
||||
c4 PUSH CTOS LDREF 32 LDU 256 LDU ENDS // sign cs cnt dict cnt' pubk
|
||||
s1 s3 XCPU // sign cs cnt dict pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s3 PUSH HASHSU // sign cs cnt dict pubk hash
|
||||
s0 s5 s5 XC2PU // pubk cs cnt dict hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt dict ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
ROT 64 LDU NIP 32 LDI LDREF ENDS // pubk cnt dict index value
|
||||
s0 s2 XCHG 32 INT // pubk cnt value index dict 32
|
||||
DICTISETREF ROTREV // dict' pubk cnt
|
||||
INC NEWC 32 STU 256 STU STREF ENDC c4 POP
|
||||
}>
|
||||
run_ticktock PROC:<{
|
||||
// store (now >> 8) into config param #-17, if the new value is different
|
||||
c4 PUSH CTOS LDREF SWAP // s' D
|
||||
NOW 8 RSHIFT# TUCK // s' t D t
|
||||
NEWC 32 STU ENDC // s' t D c
|
||||
-17 INT ROT 32 INT // s' t c -17 D 32
|
||||
DICTISETGETREF // s' t D' c' -1 or s' t D' 0
|
||||
IF:<{ CTOS 32 LDU ENDS }>ELSE<{ ZERO }> // s' t D' y'
|
||||
ROT EQUAL IFNOT: // s' D'
|
||||
NEWC STREF STSLICE ENDC // c
|
||||
c4 POP
|
||||
}>
|
||||
}END>c
|
||||
// code
|
||||
<b 0 32 u,
|
||||
/*
|
||||
*
|
||||
* SmartContract #5 (Configuration smart contract)
|
||||
*
|
||||
*/
|
||||
"auto/config-code.fif" include // code in separate source file
|
||||
<b configdict ref, // initial configuration
|
||||
0 32 u, // seqno
|
||||
"config-master" +suffix +".pk" load-generate-keypair drop
|
||||
B,
|
||||
configdict ref,
|
||||
dictnew dict, // vote dict
|
||||
b> // data
|
||||
empty_cell // libraries
|
||||
1 // balance
|
||||
0 1 2 register_smc // tock
|
||||
GR$10 // balance
|
||||
0 1 config_addr 6 register_smc // tock
|
||||
dup set_config_smc
|
||||
Masterchain swap
|
||||
."config smart contract address = " 2dup .addr cr 2dup 7 .Addr cr
|
||||
"config-master" +suffix +".addr" save-address-verbose
|
||||
// Other data
|
||||
|
||||
/*
|
||||
*
|
||||
* Initial wallets (test)
|
||||
*
|
||||
*/
|
||||
|
||||
// pubkey amount `create-wallet1` or pubkey amount `create-wallet2`
|
||||
PK'PuZPPXK5Rff9SvtoS7Y9lUuEixvy-J6aishYFj3Qn6P0pJMb GR$1000000000 create-wallet1
|
||||
PK'PuYiB1zAWzr4p8j6I681+sGUrRGcn6Ylf7vXl0xaUl/w6Xfg GR$1700000000 create-wallet0
|
||||
|
||||
/*
|
||||
*
|
||||
* Create state
|
||||
*
|
||||
*/
|
||||
|
||||
create_state
|
||||
cr cr ."new state is:" cr dup <s csr. cr
|
||||
dup 31 boc+>B dup Bx. cr
|
||||
dup "zerostate" +suffix +".boc" tuck B>file
|
||||
."(Initial masterchain state saved to file " type .")" cr
|
||||
Bhashu dup =: zerostate_fhash
|
||||
."file hash=" dup x. space 256 u>B dup B>base64url type cr
|
||||
."file hash= " dup X. space 256 u>B dup B>base64url type cr
|
||||
"zerostate" +suffix +".fhash" B>file
|
||||
hashu dup =: zerostate_rhash ."root hash=" dup x. space 256 u>B dup B>base64url type cr
|
||||
hashu dup =: zerostate_rhash ."root hash= " dup X. space 256 u>B dup B>base64url type cr
|
||||
"zerostate" +suffix +".rhash" B>file
|
||||
basestate0_rhash ."Basestate0 root hash=" dup x. space 256 u>B B>base64url type cr
|
||||
basestate0_fhash ."Basestate0 file hash=" dup x. space 256 u>B B>base64url type cr
|
||||
zerostate_rhash ."Zerostate root hash=" dup x. space 256 u>B B>base64url type cr
|
||||
zerostate_fhash ."Zerostate file hash=" dup x. space 256 u>B B>base64url type cr
|
||||
basestate0_rhash ."Basestate0 root hash= " dup X. space 256 u>B B>base64url type cr
|
||||
basestate0_fhash ."Basestate0 file hash= " dup X. space 256 u>B B>base64url type cr
|
||||
zerostate_rhash ."Zerostate root hash= " dup X. space 256 u>B B>base64url type cr
|
||||
zerostate_fhash ."Zerostate file hash= " dup X. space 256 u>B B>base64url type cr
|
||||
|
|
|
@ -8,7 +8,8 @@ def? $1 { @' $1 } { "" } cond constant suffix
|
|||
256 1<<1- 15 / constant AllOnes
|
||||
|
||||
wc_master setworkchain
|
||||
-239 setglobalid // negative value means a test instance of the blockchain
|
||||
13 setglobalid // negative value means a test instance of the blockchain
|
||||
0x11EF55AA default-subwallet-id! // use this subwallet id in user wallets by default
|
||||
|
||||
// Initial state of Workchain 0 (Basic workchain)
|
||||
|
||||
|
@ -29,110 +30,57 @@ hashu dup =: basestate0_rhash
|
|||
basestate0_rhash basestate0_fhash now 0 4 8 0 add-std-workchain
|
||||
config.workchains!
|
||||
|
||||
// SmartContract #1 (Simple wallet)
|
||||
/*
|
||||
*
|
||||
* Initial wallets (test)
|
||||
*
|
||||
*/
|
||||
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP 8 LDU LDREF ENDS // pubk cnt mode msg
|
||||
SWAP SENDRAWMSG // pubk cnt ; ( message sent )
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
}>c
|
||||
// code
|
||||
<b 0 32 u,
|
||||
// Stage 1 wallets
|
||||
|
||||
PK'Puasxr0QfFZZnYISRphVse7XHKfW7pZU5SJarVHXvQ+rpzkD rwallet-init-pubkey !
|
||||
-86400 rwallet-start-at +!
|
||||
|
||||
{ swap create-wallet3 } : stage1
|
||||
{ bl word $>GR bl word parse-pubkey } : parse-amount-pubkey
|
||||
{ parse-amount-pubkey stage1 } : StA
|
||||
|
||||
// test
|
||||
StA 1001 PuZ8WoEOTgSR8-HopmCIVlOVSL94tNn9zgraiJqMk1SnioEQ
|
||||
|
||||
// Stage 2 wallets
|
||||
|
||||
{ swap create-wallet0 } : stage2
|
||||
{ parse-amount-pubkey stage2 } : StB
|
||||
|
||||
// test
|
||||
StB 999. PubMMGvqM08jx_6BibYldMclwjl-D88r7-u0_IEcDXHA30-G
|
||||
|
||||
// Lockdowns
|
||||
|
||||
{ swap create-wallet3b } : stage3
|
||||
{ parse-amount-pubkey stage3 } : StC
|
||||
|
||||
// SmartContract #1 (Advanced wallet)
|
||||
|
||||
// Create new advanced wallet; code adapted from `auto/wallet3-code.fif`
|
||||
WCode3 // code
|
||||
<b 0 32 u, 0 32 u, // subwallet-id=0
|
||||
"main-wallet" +suffix +".pk" load-generate-keypair drop
|
||||
B,
|
||||
b> // data
|
||||
Libs{
|
||||
x{ABACABADABACABA} s>c public_lib
|
||||
x{1234} x{5678} |_ s>c private_lib
|
||||
}Libs // libraries
|
||||
GR$4999990000 // balance
|
||||
empty_cell // libs
|
||||
GR$4999999000 allocated-balance - // balance
|
||||
0 // split_depth
|
||||
0 // ticktock
|
||||
AllOnes 0 * // address
|
||||
AllOnes 1 * // address
|
||||
6 // mode: create+setaddr
|
||||
register_smc
|
||||
dup make_special dup constant smc1_addr
|
||||
Masterchain over
|
||||
2dup ."wallet address = " .addr cr 2dup 6 .Addr cr
|
||||
2dup ."main wallet address = " .addr cr 2dup 6 .Addr cr
|
||||
"main-wallet" +suffix +".addr" save-address-verbose
|
||||
|
||||
// SmartContract #2 (Simple money giver for test network)
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
32 LDU SWAP // cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU ENDS // cs cnt cnt'
|
||||
TUCK EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
ACCEPT // cs cnt'
|
||||
SWAP 8 LDU LDREF ENDS // cnt'' mode msg
|
||||
GR$20 INT 3 INT RAWRESERVE // reserve all but 20 Grams from the balance
|
||||
SWAP SENDRAWMSG
|
||||
INC NEWC 32 STU ENDC c4 POPCTR // store cnt''
|
||||
}>c
|
||||
// code
|
||||
<b 0 32 u, b> // data
|
||||
empty_cell // libraries
|
||||
GR$1000 // initial balance (1k test Grams)
|
||||
0 0 AllOnes 6 * 6 register_smc
|
||||
dup make_special dup constant smc2_addr
|
||||
Masterchain over
|
||||
2dup ."free test gram giver address = " .addr cr 2dup 6 .Addr cr
|
||||
"testgiver" +suffix +".addr" save-address-verbose
|
||||
|
||||
// SmartContract #3
|
||||
PROGRAM{
|
||||
recv_internal x{} PROC
|
||||
run_ticktock PROC:<{
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS
|
||||
NEWC ROT INC 32 STUR OVER 256 STUR ENDC
|
||||
c4 POPCTR
|
||||
// first 32 bits of persistent data have been increased
|
||||
// remaining 256 bits with an address have been fetched
|
||||
// create new empty message with 0.1 Grams to that address
|
||||
NEWC b{00100010011111111} STSLICECONST TUCK 256 STU
|
||||
100000000 INT STGRAMS // store 0.1 Grams
|
||||
1 4 + 4 + 64 + 32 + 1+ 1+ INT STZEROES ENDC
|
||||
// send raw message from Cell
|
||||
ZERO SENDRAWMSG
|
||||
-17 INT 256 STIR 130000000 INT STGRAMS
|
||||
107 INT STZEROES ENDC
|
||||
ZERO // another message with 0.13 Grams to account -17
|
||||
NEWC b{11000100100000} "test" $>s |+ STSLICECONST
|
||||
123456789 INT STGRAMS
|
||||
107 INT STZEROES "Hello, world!" $>s STSLICECONST ENDC
|
||||
ZERO SENDRAWMSG SENDRAWMSG // external message to address "test"
|
||||
}>
|
||||
}END>c
|
||||
// code
|
||||
<b x{11EF55AA} s, smc1_addr 256 u, b> // data
|
||||
// empty_cell // libraries
|
||||
Libs{
|
||||
x{ABACABADABACABA} s>c public_lib
|
||||
x{1234} x{5678} |_ s>c public_lib
|
||||
}Libs // libraries
|
||||
GR$666 // balance
|
||||
0 // split_depth
|
||||
3 // ticktock: tick
|
||||
2 // mode: create
|
||||
register_smc
|
||||
dup make_special dup constant smc3_addr
|
||||
."address = " 64x. cr
|
||||
|
||||
/*
|
||||
*
|
||||
* SmartContract #4 (elector)
|
||||
|
@ -141,7 +89,7 @@ dup make_special dup constant smc3_addr
|
|||
"auto/elector-code.fif" include // code in separate source file
|
||||
<b 0 1 1+ 1+ 4 + 32 + u, 0 256 u, b> // data: dict dict dict grams uint32 uint256
|
||||
empty_cell // libraries
|
||||
GR$10 // balance: 10 grams
|
||||
GR$500 // balance: 500 grams
|
||||
0 // split_depth
|
||||
2 // ticktock: tick
|
||||
AllOnes 3 * // address: -1:333...333
|
||||
|
@ -196,7 +144,7 @@ config.special!
|
|||
triple dup untriple config.mc_block_limits!
|
||||
untriple config.block_limits!
|
||||
|
||||
GR$1.7 GR$1 config.block_create_fees!
|
||||
GR$160 GR$100 config.block_create_fees!
|
||||
// smc1_addr config.collector_smc!
|
||||
smc1_addr config.minter_smc!
|
||||
|
||||
|
@ -214,14 +162,26 @@ config.param_proposals_setup!
|
|||
// deposit bit_pps cell_pps
|
||||
GR$100 1 500 config.complaint_prices!
|
||||
|
||||
"validator-keys" +suffix +".pub" file>B
|
||||
{ dup Blen } { 32 B| swap dup ."Validator public key = " Bx. cr
|
||||
17 add-validator } while drop
|
||||
{ file>B { dup Blen } {
|
||||
32 B| swap dup ."Validator public key = " Bx. cr
|
||||
17 add-validator
|
||||
} while drop
|
||||
} : load-keys-from-file
|
||||
|
||||
false =: keys-from-file
|
||||
keys-from-file
|
||||
{ "validator-keys" +suffix +".pub" load-keys-from-file
|
||||
} {
|
||||
VPK'xrQTSOn2F9RjLgeHdSS0uIvde4Lv49l+/KXfJe0I7wYatz6e
|
||||
B64{8E9AbL8blhRiBUoZt/b/vIo3+iZzglLKiL8MTf0g6Sg=} 256 B>u@
|
||||
1 add-adnl-validator
|
||||
} cond
|
||||
// newkeypair nip dup ."Validator #1 public key = " Bx. cr
|
||||
// 17 add-validator
|
||||
// newkeypair nip dup ."Validator #2 public key = " Bx. cr
|
||||
// 239 add-validator
|
||||
100000 =: orig_vset_valid_for // original validator set valid 100000 seconds
|
||||
|
||||
3000 =: orig_vset_valid_for // original validator set valid 3000 seconds
|
||||
now dup orig_vset_valid_for + 0 config.validators!
|
||||
|
||||
/*
|
||||
|
@ -237,24 +197,14 @@ now dup orig_vset_valid_for + 0 config.validators!
|
|||
dictnew dict, // vote dict
|
||||
b> // data
|
||||
empty_cell // libraries
|
||||
GR$10 // balance
|
||||
GR$500 // balance
|
||||
0 1 config_addr 6 register_smc // tock
|
||||
dup set_config_smc
|
||||
Masterchain swap
|
||||
."config smart contract address = " 2dup .addr cr 2dup 7 .Addr cr
|
||||
"config-master" +suffix +".addr" save-address-verbose
|
||||
// Other data
|
||||
|
||||
/*
|
||||
*
|
||||
* Initial wallets (test)
|
||||
*
|
||||
*/
|
||||
|
||||
// pubkey amount `create-wallet1` or pubkey amount `create-wallet2`
|
||||
PK'PuZPPXK5Rff9SvtoS7Y9lUuEixvy-J6aishYFj3Qn6P0pJMb GR$1000000000 create-wallet1
|
||||
PK'PuYiB1zAWzr4p8j6I681+sGUrRGcn6Ylf7vXl0xaUl/w6Xfg GR$1700000000 create-wallet0
|
||||
|
||||
/*
|
||||
*
|
||||
* Create state
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
null =: subwallet-id
|
||||
86400 =: expires-in
|
||||
now =: start-at
|
||||
0x5EA62080 =: start-at
|
||||
0x4BA92D8A =: subwallet-base
|
||||
// 0x11EF55AA =: subwallet-base
|
||||
|
||||
begin-options
|
||||
" <creator-filename-base> <public-key> <amount> [-w<workchain>][-r<restrict-mode>][-i<subwallet-id>][-t<start-at>] [<savefile>]" +cr +tab
|
||||
|
@ -27,8 +26,8 @@ begin-options
|
|||
"x" "--expires-in" { parse-int =: expires-in } short-long-option-arg
|
||||
"Expiration time of the initialization message (" expires-in (.) $+
|
||||
+" seconds by default)" option-help
|
||||
"t" "--start-at" { parse-int =: start-at } short-long-option-arg
|
||||
"Restriction start Unixtime (now by default)" option-help
|
||||
"t" "--start-at" { dup "now" $= { drop now } { parse-int } cond =: start-at } short-long-option-arg
|
||||
"Restriction start Unixtime (`now` by default)" option-help
|
||||
"h" "--help" { usage } short-long-option
|
||||
"Shows a help message" option-help
|
||||
parse-options
|
||||
|
@ -50,7 +49,7 @@ wc 8 fits not abort"invalid workchain id"
|
|||
subwallet-id 32 fits not abort"invalid subwallet-id"
|
||||
expires-at 32 ufits not abort"invalid expiration time"
|
||||
start-at 32 ufits not abort"invalid restriction start time"
|
||||
restrict-mode dup 1 < swap 2 > or abort"unknown restriction mode"
|
||||
restrict-mode dup 0 < swap 2 > or abort"unknown restriction mode"
|
||||
filename-base +".pk" load-keypair =: init_pk =: init_pubkey
|
||||
|
||||
."Creating new restricted lockup wallet v3 in workchain " wc .
|
||||
|
@ -79,9 +78,16 @@ filename-base +".pk" load-keypair =: init_pk =: init_pubkey
|
|||
swap .2225 */ 3 years* rdict-entry
|
||||
0 4 years* 86400 + rdict-entry
|
||||
} : make-rdict2
|
||||
{ dictnew
|
||||
swap 31 -1<< rdict-entry
|
||||
0 0 rdict-entry
|
||||
} : make-rdict0
|
||||
|
||||
amount
|
||||
restrict-mode 1 = { make-rdict1 } { make-rdict2 } cond =: rdict
|
||||
restrict-mode ?dup {
|
||||
1 = { make-rdict1 } { make-rdict2 } cond
|
||||
} { make-rdict0 } cond
|
||||
=: rdict
|
||||
|
||||
."Restrictions start at " start-at ._ .": " cr
|
||||
rdict 32 { swap . ."-> " Gram@ .GR cr true } idictforeach cr
|
||||
|
|
|
@ -17,29 +17,8 @@ $3 "new-wallet" replace-if-null =: file-base
|
|||
."with unique wallet id " subwallet-id . cr
|
||||
|
||||
// Create new advanced wallet; code adapted from `auto/wallet3-code.fif`
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL OVER 78748 INT EQUAL OR IFJMP:<{ // "seqno" and "get_public_key" get-methods
|
||||
1 INT AND c4 PUSHCTR CTOS 32 LDU 32 LDU NIP 256 PLDU CONDSEL // cnt or pubk
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
9 PUSHPOW2 LDSLICEX DUP 32 LDU 32 LDU 32 LDU // signature in_msg subwallet_id valid_until msg_seqno cs
|
||||
NOW s1 s3 XCHG LEQ 35 THROWIF // signature in_msg subwallet_id cs msg_seqno
|
||||
c4 PUSH CTOS 32 LDU 32 LDU 256 LDU ENDS // signature in_msg subwallet_id cs msg_seqno stored_seqno stored_subwallet public_key
|
||||
s3 s2 XCPU EQUAL 33 THROWIFNOT // signature in_msg subwallet_id cs public_key stored_seqno stored_subwallet
|
||||
s4 s4 XCPU EQUAL 34 THROWIFNOT // signature in_msg stored_subwallet cs public_key stored_seqno
|
||||
s0 s4 XCHG HASHSU // signature stored_seqno stored_subwallet cs public_key msg_hash
|
||||
s0 s5 s5 XC2PU // public_key stored_seqno stored_subwallet cs msg_hash signature public_key
|
||||
CHKSIGNU 35 THROWIFNOT // public_key stored_seqno stored_subwallet cs
|
||||
ACCEPT
|
||||
WHILE:<{
|
||||
DUP SREFS // public_key stored_seqno stored_subwallet cs _51
|
||||
}>DO<{ // public_key stored_seqno stored_subwallet cs
|
||||
8 LDU LDREF s0 s2 XCHG // public_key stored_seqno stored_subwallet cs _56 mode
|
||||
SENDRAWMSG
|
||||
}> // public_key stored_seqno stored_subwallet cs
|
||||
ENDS SWAP INC // public_key stored_subwallet seqno'
|
||||
NEWC 32 STU 32 STU 256 STU ENDC c4 POP
|
||||
}>c // >libref
|
||||
"wallet-v3-code.fif" include
|
||||
// >libref
|
||||
// code
|
||||
<b 0 32 u, subwallet-id 32 u,
|
||||
file-base +".pk" load-generate-keypair
|
||||
|
|
27
crypto/smartcont/wallet-v3-code.fif
Normal file
27
crypto/smartcont/wallet-v3-code.fif
Normal file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/fift -s
|
||||
"Asm.fif" include
|
||||
|
||||
// New advanced wallet code adapted from `auto/wallet3-code.fif`
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL OVER 78748 INT EQUAL OR IFJMP:<{ // "seqno" and "get_public_key" get-methods
|
||||
1 INT AND c4 PUSHCTR CTOS 32 LDU 32 LDU NIP 256 PLDU CONDSEL // cnt or pubk
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
9 PUSHPOW2 LDSLICEX DUP 32 LDU 32 LDU 32 LDU // signature in_msg subwallet_id valid_until msg_seqno cs
|
||||
NOW s1 s3 XCHG LEQ 35 THROWIF // signature in_msg subwallet_id cs msg_seqno
|
||||
c4 PUSH CTOS 32 LDU 32 LDU 256 LDU ENDS // signature in_msg subwallet_id cs msg_seqno stored_seqno stored_subwallet public_key
|
||||
s3 s2 XCPU EQUAL 33 THROWIFNOT // signature in_msg subwallet_id cs public_key stored_seqno stored_subwallet
|
||||
s4 s4 XCPU EQUAL 34 THROWIFNOT // signature in_msg stored_subwallet cs public_key stored_seqno
|
||||
s0 s4 XCHG HASHSU // signature stored_seqno stored_subwallet cs public_key msg_hash
|
||||
s0 s5 s5 XC2PU // public_key stored_seqno stored_subwallet cs msg_hash signature public_key
|
||||
CHKSIGNU 35 THROWIFNOT // public_key stored_seqno stored_subwallet cs
|
||||
ACCEPT
|
||||
WHILE:<{
|
||||
DUP SREFS // public_key stored_seqno stored_subwallet cs _51
|
||||
}>DO<{ // public_key stored_seqno stored_subwallet cs
|
||||
8 LDU LDREF s0 s2 XCHG // public_key stored_seqno stored_subwallet cs _56 mode
|
||||
SENDRAWMSG
|
||||
}> // public_key stored_seqno stored_subwallet cs
|
||||
ENDS SWAP INC // public_key stored_subwallet seqno'
|
||||
NEWC 32 STU 32 STU 256 STU ENDC c4 POP
|
||||
}>c
|
Loading…
Add table
Add a link
Reference in a new issue