Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "imports/stdlib.fc";
- #include "imports/op-codes.fc";
- ;; NFT sale smart contract
- int min_gas_amount() asm "1000000000 PUSHINT"; ;; 1 TON
- (slice, slice, slice, int, cell, int) load_data() inline {
- var ds = get_data().begin_parse();
- return
- (ds~load_msg_addr(), ;; marketplace_address
- ds~load_msg_addr(), ;; nft_address
- ds~load_msg_addr(), ;; nft_owner_address
- ds~load_coins(), ;; full_price
- ds~load_ref(), ;; fees_cell
- ds~load_uint(32) ;; sale_count
- );
- }
- (int, slice, int) load_fees(cell fees_cell) inline {
- var ds = fees_cell.begin_parse();
- return
- (ds~load_coins(), ;; marketplace_fee,
- ds~load_msg_addr(), ;; royalty_address
- ds~load_coins() ;; royalty_amount
- );
- }
- () save_data(slice marketplace_address, slice nft_address, slice nft_owner_address, int full_price, cell fees_cell, int sale_count) impure inline {
- set_data(begin_cell()
- .store_slice(marketplace_address)
- .store_slice(nft_address)
- .store_slice(nft_owner_address)
- .store_coins(full_price)
- .store_ref(fees_cell)
- .store_uint(sale_count, 32)
- .end_cell());
- }
- () buy(int my_balance, slice marketplace_address, slice nft_address, slice nft_owner_address, int full_price, cell fees_cell, int msg_value, slice sender_address, int query_id, int sale_count) impure {
- throw_unless(450, msg_value >= full_price + min_gas_amount());
- var (marketplace_fee, royalty_address, royalty_amount) = load_fees(fees_cell);
- var owner_msg = begin_cell()
- .store_uint(0x10, 6) ;; nobounce
- .store_slice(nft_owner_address)
- .store_coins(full_price - marketplace_fee - royalty_amount + (my_balance - msg_value))
- .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
- send_raw_message(owner_msg.end_cell(), 1);
- var royalty_msg = begin_cell()
- .store_uint(0x10, 6) ;; nobounce
- .store_slice(royalty_address)
- .store_coins(royalty_amount)
- .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
- send_raw_message(royalty_msg.end_cell(), 1);
- var marketplace_msg = begin_cell()
- .store_uint(0x10, 6) ;; nobounce
- .store_slice(marketplace_address)
- .store_coins(marketplace_fee)
- .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
- send_raw_message(marketplace_msg.end_cell(), 1);
- var nft_msg = begin_cell()
- .store_uint(0x18, 6)
- .store_slice(nft_address)
- .store_coins(0)
- .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
- .store_uint(op::transfer(), 32)
- .store_uint(query_id, 64)
- .store_slice(sender_address) ;; new_owner_address
- .store_slice(sender_address) ;; response_address
- .store_int(0, 1) ;; empty custom_payload
- .store_coins(0) ;; forward amount to new_owner_address
- .store_int(0, 1); ;; empty forward_payload
- send_raw_message(nft_msg.end_cell(), 128 + 32);
- sale_count = sale_count + 1;
- save_data(marketplace_address,nft_address,nft_owner_address,full_price,fees_cell,sale_count);
- }
- () recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
- 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();
- var (marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, sale_count) = load_data();
- var is_initialized = nft_owner_address.slice_bits() > 2; ;; not initialized if null address
- if (~ is_initialized) { ;; initialization
- if (equal_slices(sender_address, marketplace_address)) {
- return (); ;; just accept coins on deploy
- }
- throw_unless(500, equal_slices(sender_address, nft_address));
- int op = in_msg_body~load_uint(32);
- throw_unless(501, op == op::ownership_assigned());
- int query_id = in_msg_body~load_uint(64);
- slice prev_owner_address = in_msg_body~load_msg_addr();
- save_data(marketplace_address, nft_address, prev_owner_address, full_price, fees_cell, sale_count);
- return ();
- }
- if (in_msg_body.slice_empty?()) {
- buy(my_balance, marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, msg_value, sender_address, 0, 0);
- return ();
- }
- int op = in_msg_body~load_uint(32);
- int query_id = in_msg_body~load_uint(64);
- if (op == 1) { ;; just accept coins
- return ();
- }
- if (op == 2) { ;; buy by admin
- throw_unless(458, equal_slices(sender_address, marketplace_address));
- buy(my_balance, marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, msg_value, sender_address, query_id, sale_count);
- return ();
- }
- if (op == 3) { ;; cancel sale (remove)
- throw_unless(457, msg_value >= min_gas_amount());
- throw_unless(458, equal_slices(sender_address, marketplace_address));
- var msg = begin_cell()
- .store_uint(0x10, 6) ;; nobounce
- .store_slice(nft_address)
- .store_coins(0)
- .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
- .store_uint(op::transfer(), 32)
- .store_uint(query_id, 64)
- .store_slice(nft_owner_address) ;; new_owner_address
- .store_slice(nft_owner_address) ;; response_address;
- .store_int(0, 1) ;; empty custom_payload
- .store_coins(0) ;; forward amount to new_owner_address
- .store_int(0, 1); ;; empty forward_payload
- send_raw_message(msg.end_cell(), 128 + 32);
- return ();
- }
- if (op == 4) { ;; update price
- throw_unless(457, msg_value >= min_gas_amount());
- throw_unless(458, equal_slices(sender_address, marketplace_address));
- int new_price = in_msg_body~load_coins();
- full_price = new_price;
- save_data(marketplace_address,nft_address,nft_owner_address,full_price,fees_cell,sale_count);
- return ();
- }
- throw(0xffff);
- }
- () recv_external(slice in_msg) impure {
- }
- (slice, slice, slice, int, int, slice, int) get_sale_data() method_id {
- var (marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, sale_count) = load_data();
- var (marketplace_fee, royalty_address, royalty_amount) = load_fees(fees_cell);
- return (marketplace_address, nft_address, nft_owner_address, full_price, marketplace_fee, royalty_address, royalty_amount);
- }
- (slice) get_admin() method_id {
- (slice marketplace_address,_,_,_,_,_) = load_data();
- return marketplace_address;
- }
- (int) get_sale_count() method_id {
- (_,_,_,_,_, int sale_count) = load_data();
- return sale_count;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement