-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from disintar/dev-nightly
Add func
- Loading branch information
Showing
7 changed files
with
464 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
;; | ||
;; TON NFT Item Smart Contract | ||
;; | ||
|
||
{- | ||
|
||
NOTE that this tokens can be transferred within the same workchain. | ||
|
||
This is suitable for most tokens, if you need tokens transferable between workchains there are two solutions: | ||
|
||
1) use more expensive but universal function to calculate message forward fee for arbitrary destination (see `misc/forward-fee-calc.cs`) | ||
|
||
2) use token holder proxies in target workchain (that way even 'non-universal' token can be used from any workchain) | ||
|
||
-} | ||
|
||
int min_tons_for_storage() asm "50000000 PUSHINT"; ;; 0.05 TON | ||
|
||
;; | ||
;; Storage | ||
;; | ||
;; uint64 index | ||
;; MsgAddressInt collection_address | ||
;; MsgAddressInt owner_address | ||
;; cell content | ||
;; | ||
|
||
(int, int, slice, slice, cell) load_data() { | ||
slice ds = get_data().begin_parse(); | ||
var (index, collection_address) = (ds~load_uint(64), ds~load_msg_addr()); | ||
if (ds.slice_bits() > 0) { | ||
return (-1, index, collection_address, ds~load_msg_addr(), ds~load_ref()); | ||
} else { | ||
return (0, index, collection_address, null(), null()); ;; nft not initialized yet | ||
} | ||
} | ||
|
||
() store_data(int index, slice collection_address, slice owner_address, cell content) impure { | ||
set_data( | ||
begin_cell() | ||
.store_uint(index, 64) | ||
.store_slice(collection_address) | ||
.store_slice(owner_address) | ||
.store_ref(content) | ||
.end_cell() | ||
); | ||
} | ||
|
||
() send_msg(slice to_address, int amount, int op, int query_id, builder payload, int send_mode) impure inline { | ||
var msg = begin_cell() | ||
.store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 010000 | ||
.store_slice(to_address) | ||
.store_coins(amount) | ||
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) | ||
.store_uint(op, 32) | ||
.store_uint(query_id, 64); | ||
|
||
if (~ builder_null?(payload)) { | ||
msg = msg.store_builder(payload); | ||
} | ||
|
||
send_raw_message(msg.end_cell(), send_mode); | ||
} | ||
|
||
() transfer_ownership(int my_balance, int index, slice collection_address, slice owner_address, cell content, slice sender_address, int query_id, slice in_msg_body, int fwd_fees) impure inline { | ||
throw_unless(401, equal_slices(sender_address, owner_address)); | ||
|
||
slice new_owner_address = in_msg_body~load_msg_addr(); | ||
force_chain(new_owner_address); | ||
slice response_destination = in_msg_body~load_msg_addr(); | ||
in_msg_body~load_int(1); ;; this nft don't use custom_payload | ||
int forward_amount = in_msg_body~load_coins(); | ||
throw_unless(708, slice_bits(in_msg_body) >= 1); | ||
|
||
int rest_amount = my_balance - min_tons_for_storage(); | ||
if (forward_amount) { | ||
rest_amount -= (forward_amount + fwd_fees); | ||
} | ||
int need_response = response_destination.preload_uint(2) != 0; ;; if NOT addr_none: 00 | ||
if (need_response) { | ||
rest_amount -= fwd_fees; | ||
} | ||
|
||
throw_unless(402, rest_amount >= 0); ;; base nft spends fixed amount of gas, will not check for response | ||
|
||
if (forward_amount) { | ||
send_msg(new_owner_address, forward_amount, op::ownership_assigned(), query_id, begin_cell().store_slice(owner_address).store_slice(in_msg_body), 1); ;; paying fees, revert on errors | ||
} | ||
if (need_response) { | ||
force_chain(response_destination); | ||
send_msg(response_destination, rest_amount, op::excesses(), query_id, null(), 1); ;; paying fees, revert on errors | ||
} | ||
|
||
store_data(index, collection_address, new_owner_address, content); | ||
} | ||
|
||
() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure { | ||
if (in_msg_body.slice_empty?()) { ;; ignore empty messages | ||
return (); | ||
} | ||
|
||
slice cs = in_msg_full.begin_parse(); | ||
int flags = cs~load_uint(4); | ||
|
||
if (flags & 1) { ;; ignore all bounced messages | ||
return (); | ||
} | ||
slice sender_address = cs~load_msg_addr(); | ||
|
||
cs~load_msg_addr(); ;; skip dst | ||
cs~load_coins(); ;; skip value | ||
cs~skip_bits(1); ;; skip extracurrency collection | ||
cs~load_coins(); ;; skip ihr_fee | ||
int fwd_fee = muldiv(cs~load_coins(), 3, 2); ;; we use message fwd_fee for estimation of forward_payload costs | ||
|
||
|
||
(int init?, int index, slice collection_address, slice owner_address, cell content) = load_data(); | ||
if (~ init?) { | ||
throw_unless(405, equal_slices(collection_address, sender_address)); | ||
store_data(index, collection_address, in_msg_body~load_msg_addr(), in_msg_body~load_ref()); | ||
return (); | ||
} | ||
|
||
int op = in_msg_body~load_uint(32); | ||
int query_id = in_msg_body~load_uint(64); | ||
|
||
if (op == op::transfer()) { | ||
transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, in_msg_body, fwd_fee); | ||
return (); | ||
} | ||
if (op == op::get_static_data()) { | ||
send_msg(sender_address, 0, op::report_static_data(), query_id, begin_cell().store_uint(index, 256).store_slice(collection_address), 64); ;; carry all the remaining value of the inbound message | ||
return (); | ||
} | ||
throw(0xffff); | ||
} | ||
|
||
;; | ||
;; GET Methods | ||
;; | ||
|
||
(int, int, slice, slice, cell) get_nft_data() method_id { | ||
(int init?, int index, slice collection_address, slice owner_address, cell content) = load_data(); | ||
return (init?, index, collection_address, owner_address, content); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
int op::transfer() asm "0x5fcc3d14 PUSHINT"; | ||
int op::ownership_assigned() asm "0x05138d91 PUSHINT"; | ||
int op::excesses() asm "0xd53276db PUSHINT"; | ||
int op::get_static_data() asm "0x2fcb26a2 PUSHINT"; | ||
int op::report_static_data() asm "0x8b771735 PUSHINT"; | ||
int op::get_royalty_params() asm "0x693d3950 PUSHINT"; | ||
int op::report_royalty_params() asm "0xa8cb00ad PUSHINT"; | ||
|
||
;; NFTEditable | ||
int op::edit_content() asm "0x1a0b9d51 PUSHINT"; | ||
int op::transfer_editorship() asm "0x1c04412a PUSHINT"; | ||
int op::editorship_assigned() asm "0x511a4463 PUSHINT"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
int workchain() asm "0 PUSHINT"; | ||
|
||
() force_chain(slice addr) impure { | ||
(int wc, _) = parse_std_addr(addr); | ||
throw_unless(333, wc == workchain()); | ||
} |
Oops, something went wrong.