1
;; Simple wallet smart contract
3
cell create_state(int seqno, int public_key) {
4
return begin_cell().store_uint(seqno, 32).store_uint(public_key, 256).end_cell();
7
(int, int) load_state() {
8
var cs2 = begin_parse(get_data());
9
return (cs2~load_uint(32), cs2~load_uint(256));
12
() save_state(int seqno, int public_key) impure {
13
set_data(create_state(seqno, public_key));
16
() recv_internal(slice in_msg) impure {
17
;; do nothing for internal messages
20
slice do_verify_message(slice in_msg, int seqno, int public_key) {
21
var signature = in_msg~load_bits(512);
23
int msg_seqno = cs~load_uint(32);
24
throw_unless(33, msg_seqno == seqno);
25
throw_unless(34, check_signature(slice_hash(in_msg), signature, public_key));
29
() recv_external(slice in_msg) impure {
30
(int stored_seqno, int public_key) = load_state();
31
var cs = do_verify_message(in_msg, stored_seqno, public_key);
34
if (cs.slice_refs()) {
35
var mode = cs~load_uint(8);
36
send_raw_message(cs~load_ref(), mode);
39
save_state(stored_seqno + 1, public_key);
44
int seqno() method_id {
45
return get_data().begin_parse().preload_uint(32);
48
int get_public_key() method_id {
49
var (seqno, public_key) = load_state();
53
cell create_init_state(int public_key) method_id {
54
return create_state(0, public_key);
57
cell prepare_send_message_with_seqno(int mode, cell msg, int seqno) method_id {
58
return begin_cell().store_uint(seqno, 32).store_uint(mode, 8).store_ref(msg).end_cell();
61
cell prepare_send_message(int mode, cell msg) method_id {
62
return prepare_send_message_with_seqno(mode, msg, seqno());
65
slice verify_message(slice msg) method_id {
66
var (stored_seqno, public_key) = load_state();
67
return do_verify_message(msg, stored_seqno, public_key);