|
|
@ -3,10 +3,13 @@ |
|
|
|
#include "imports/op-codes.fc"; |
|
|
|
#include "imports/op-codes.fc"; |
|
|
|
#include "imports/params.fc"; |
|
|
|
#include "imports/params.fc"; |
|
|
|
|
|
|
|
|
|
|
|
int min_tons_for_storage() asm "1000000000 PUSHINT"; ;; 1 TON |
|
|
|
int min_tons_for_storage() asm "500000000 PUSHINT"; ;; 0.5 TON |
|
|
|
|
|
|
|
|
|
|
|
;; sha256('uri') |
|
|
|
;; sha256('uri') |
|
|
|
const uri_key = 51065135818459385347574250312853146822620586594996463797054414300406918686668; |
|
|
|
const uri_key = 51065135818459385347574250312853146822620586594996463797054414300406918686668; |
|
|
|
|
|
|
|
const name_key = 59089242681608890680090686026688704441792375738894456860693970539822503415433; |
|
|
|
|
|
|
|
const image_key = 43884663033947008978309661017057008345326326811558777475113826163084742639165; |
|
|
|
|
|
|
|
const description_key = 90922719342317012409671596374183159143637506542604000676488204638996496437508; |
|
|
|
|
|
|
|
|
|
|
|
;; |
|
|
|
;; |
|
|
|
;; === Storage === |
|
|
|
;; === Storage === |
|
|
@ -15,26 +18,28 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
;; MsgAddressInt collection_address |
|
|
|
;; MsgAddressInt collection_address |
|
|
|
;; MsgAddressInt owner_address |
|
|
|
;; MsgAddressInt owner_address |
|
|
|
;; cell content |
|
|
|
;; cell content |
|
|
|
|
|
|
|
;; cell uri |
|
|
|
;; cell domain - e.g contains "alice" (without ending \0) for "alice.ton" domain |
|
|
|
;; cell domain - e.g contains "alice" (without ending \0) for "alice.ton" domain |
|
|
|
;; int last_fill_up_time |
|
|
|
;; int last_fill_up_time |
|
|
|
|
|
|
|
|
|
|
|
(int, int, slice, slice, cell, cell, int) load_data() { |
|
|
|
(int, int, slice, slice, cell, cell, cell, int) load_data() { |
|
|
|
slice ds = get_data().begin_parse(); |
|
|
|
slice ds = get_data().begin_parse(); |
|
|
|
var (index, collection_address) = (ds~load_uint(256), ds~load_msg_addr()); |
|
|
|
var (index, collection_address) = (ds~load_uint(256), ds~load_msg_addr()); |
|
|
|
if (ds.slice_bits() > 0) { |
|
|
|
if (ds.slice_bits() > 0) { |
|
|
|
return (-1, index, collection_address, ds~load_msg_addr(), ds~load_ref(), ds~load_ref(), ds~load_uint(64)); |
|
|
|
return (-1, index, collection_address, ds~load_msg_addr(), ds~load_ref(), ds~load_ref(), ds~load_ref(), ds~load_uint(64)); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return (0, index, collection_address, null(), null(), null(), 0); ;; nft not initialized yet |
|
|
|
return (0, index, collection_address, null(), null(), null(), null(), 0); ;; nft not initialized yet |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
() store_data(int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) impure { |
|
|
|
() store_data(int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) impure { |
|
|
|
set_data( |
|
|
|
set_data( |
|
|
|
begin_cell() |
|
|
|
begin_cell() |
|
|
|
.store_uint(index, 256) |
|
|
|
.store_uint(index, 256) |
|
|
|
.store_slice(collection_address) |
|
|
|
.store_slice(collection_address) |
|
|
|
.store_slice(owner_address) |
|
|
|
.store_slice(owner_address) |
|
|
|
.store_ref(content) |
|
|
|
.store_ref(content) |
|
|
|
|
|
|
|
.store_ref(uri) |
|
|
|
.store_ref(domain) |
|
|
|
.store_ref(domain) |
|
|
|
.store_uint(last_fill_up_time, 64) |
|
|
|
.store_uint(last_fill_up_time, 64) |
|
|
|
.end_cell() |
|
|
|
.end_cell() |
|
|
@ -57,7 +62,7 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
send_raw_message(msg.end_cell(), send_mode); |
|
|
|
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, cell domain) impure inline { |
|
|
|
() transfer_ownership(int my_balance, int index, slice collection_address, slice owner_address, cell content, cell uri, slice sender_address, int query_id, slice in_msg_body, int fwd_fees, cell domain) impure inline { |
|
|
|
slice new_owner_address = in_msg_body~load_msg_addr(); |
|
|
|
slice new_owner_address = in_msg_body~load_msg_addr(); |
|
|
|
force_chain(new_owner_address); |
|
|
|
force_chain(new_owner_address); |
|
|
|
slice response_destination = in_msg_body~load_msg_addr(); |
|
|
|
slice response_destination = in_msg_body~load_msg_addr(); |
|
|
@ -83,7 +88,7 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
send_msg(response_destination, rest_amount, op::excesses(), query_id, null(), 1); ;; paying fees, revert on errors |
|
|
|
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, domain, now()); |
|
|
|
store_data(index, collection_address, new_owner_address, content, uri, domain, now()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { |
|
|
|
() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { |
|
|
@ -102,16 +107,27 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
cs~load_coins(); ;; skip ihr_fee |
|
|
|
cs~load_coins(); ;; skip ihr_fee |
|
|
|
int fwd_fee = cs~load_coins(); ;; we use message fwd_fee for estimation of forward_payload costs |
|
|
|
int fwd_fee = cs~load_coins(); ;; we use message fwd_fee for estimation of forward_payload costs |
|
|
|
|
|
|
|
|
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
if (~ init?) { |
|
|
|
if (~ init?) { |
|
|
|
throw_unless(405, equal_slices(collection_address, sender_address)); |
|
|
|
throw_unless(405, equal_slices(collection_address, sender_address)); |
|
|
|
slice from_address = in_msg_body~load_msg_addr(); |
|
|
|
slice from_address = in_msg_body~load_msg_addr(); |
|
|
|
cell domain = in_msg_body~load_ref(); |
|
|
|
cell domain = in_msg_body~load_ref(); |
|
|
|
cell uri = in_msg_body~load_ref(); |
|
|
|
slice attachment = in_msg_body~load_ref().begin_parse(); |
|
|
|
|
|
|
|
cell uri = attachment~load_ref(); |
|
|
|
|
|
|
|
cell img_uri = attachment~load_ref(); |
|
|
|
|
|
|
|
cell name = attachment~load_ref(); |
|
|
|
|
|
|
|
cell description = attachment~load_ref(); |
|
|
|
cell content_dict = new_dict(); |
|
|
|
cell content_dict = new_dict(); |
|
|
|
content_dict~udict_set_ref(256, uri_key, uri); |
|
|
|
;; content_dict~udict_set_ref(256, uri_key, uri); |
|
|
|
|
|
|
|
content_dict~udict_set_ref(256, image_key, img_uri); |
|
|
|
|
|
|
|
content_dict~udict_set_ref(256, name_key, name); |
|
|
|
|
|
|
|
content_dict~udict_set_ref(256, description_key, description); |
|
|
|
cell content = begin_cell().store_uint(0, 8).store_dict(content_dict).end_cell(); |
|
|
|
cell content = begin_cell().store_uint(0, 8).store_dict(content_dict).end_cell(); |
|
|
|
store_data(index, collection_address, from_address, content, domain, now()); |
|
|
|
store_data(index, collection_address, from_address, content, uri, domain, now()); |
|
|
|
|
|
|
|
int rest_amount = msg_value - fwd_fee - min_tons_for_storage(); |
|
|
|
|
|
|
|
if (rest_amount > 0) { |
|
|
|
|
|
|
|
send_msg(collection_address, rest_amount, op::excesses(), 0, null(), 1); ;; paying fees, revert on errors |
|
|
|
|
|
|
|
} |
|
|
|
return (); |
|
|
|
return (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -125,7 +141,7 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (op == 0) { |
|
|
|
if (op == 0) { |
|
|
|
store_data(index, collection_address, owner_address, content, domain, now()); |
|
|
|
store_data(index, collection_address, owner_address, content, uri, domain, now()); |
|
|
|
return (); |
|
|
|
return (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -134,12 +150,12 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
|
|
|
|
|
|
|
|
if (op == op::transfer()) { |
|
|
|
if (op == op::transfer()) { |
|
|
|
throw_unless(401, equal_slices(sender_address, owner_address)); |
|
|
|
throw_unless(401, equal_slices(sender_address, owner_address)); |
|
|
|
transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, in_msg_body, fwd_fee, domain); |
|
|
|
transfer_ownership(my_balance, index, collection_address, owner_address, content, uri, sender_address, query_id, in_msg_body, fwd_fee, domain); |
|
|
|
return (); |
|
|
|
return (); |
|
|
|
} |
|
|
|
} |
|
|
|
if (op == op::edit_content()) { ;; owner can change content and dns records |
|
|
|
if (op == op::edit_content()) { ;; owner can change content and dns records |
|
|
|
throw_unless(410, equal_slices(sender_address, owner_address)); |
|
|
|
throw_unless(410, equal_slices(sender_address, owner_address)); |
|
|
|
store_data(index, collection_address, owner_address, in_msg_body~load_ref(), domain, now()); |
|
|
|
store_data(index, collection_address, owner_address, in_msg_body~load_ref(), in_msg_body~load_ref(), domain, now()); |
|
|
|
return (); |
|
|
|
return (); |
|
|
|
} |
|
|
|
} |
|
|
|
if (op == op::change_dns_record) { ;; change dns record |
|
|
|
if (op == op::change_dns_record) { ;; change dns record |
|
|
@ -161,7 +177,7 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
|
|
|
|
|
|
|
|
content = begin_cell().store_uint(0, 8).store_dict(keyvalue_map).end_cell(); |
|
|
|
content = begin_cell().store_uint(0, 8).store_dict(keyvalue_map).end_cell(); |
|
|
|
|
|
|
|
|
|
|
|
store_data(index, collection_address, owner_address, content, domain, now()); |
|
|
|
store_data(index, collection_address, owner_address, content, uri, domain, now()); |
|
|
|
return (); |
|
|
|
return (); |
|
|
|
} |
|
|
|
} |
|
|
|
if (op == op::process_governance_decision) { ;; governance |
|
|
|
if (op == op::process_governance_decision) { ;; governance |
|
|
@ -172,7 +188,7 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
int config_op = config_value~load_uint(8); |
|
|
|
int config_op = config_value~load_uint(8); |
|
|
|
throw_unless(416, (config_op == 0) | (config_op == 1)); |
|
|
|
throw_unless(416, (config_op == 0) | (config_op == 1)); |
|
|
|
if (config_op == 0) { ;; transfer |
|
|
|
if (config_op == 0) { ;; transfer |
|
|
|
transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, config_value, fwd_fee, domain); |
|
|
|
transfer_ownership(my_balance, index, collection_address, owner_address, content, uri, sender_address, query_id, config_value, fwd_fee, domain); |
|
|
|
} |
|
|
|
} |
|
|
|
if (config_op == 1) { ;; destroy |
|
|
|
if (config_op == 1) { ;; destroy |
|
|
|
send_msg(collection_address, 0, op::fill_up, query_id, null(), 128 + 32); ;; carry all the remaining balance + destroy |
|
|
|
send_msg(collection_address, 0, op::fill_up, query_id, null(), 128 + 32); ;; carry all the remaining balance + destroy |
|
|
@ -191,22 +207,22 @@ const uri_key = 5106513581845938534757425031285314682262058659499646379705441430 |
|
|
|
;; |
|
|
|
;; |
|
|
|
|
|
|
|
|
|
|
|
(int, int, slice, slice, cell) get_nft_data() method_id { |
|
|
|
(int, int, slice, slice, cell) get_nft_data() method_id { |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
return (init?, index, collection_address, owner_address, content); |
|
|
|
return (init?, index, collection_address, owner_address, uri); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
slice get_editor() method_id { |
|
|
|
slice get_editor() method_id { |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
return owner_address; |
|
|
|
return owner_address; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
slice get_domain() method_id { |
|
|
|
slice get_domain() method_id { |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
return domain.begin_parse(); |
|
|
|
return domain.begin_parse(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int get_last_fill_up_time() method_id { |
|
|
|
int get_last_fill_up_time() method_id { |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
return last_fill_up_time; |
|
|
|
return last_fill_up_time; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -215,7 +231,7 @@ int get_last_fill_up_time() method_id { |
|
|
|
|
|
|
|
|
|
|
|
throw_unless(70, mod(subdomain_bits, 8) == 0); |
|
|
|
throw_unless(70, mod(subdomain_bits, 8) == 0); |
|
|
|
|
|
|
|
|
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell my_domain_cell, int last_fill_up_time) = load_data(); |
|
|
|
(int init?, int index, slice collection_address, slice owner_address, cell content, cell uri, cell domain, int last_fill_up_time) = load_data(); |
|
|
|
|
|
|
|
|
|
|
|
slice cs = content.begin_parse(); |
|
|
|
slice cs = content.begin_parse(); |
|
|
|
throw_unless(412, cs~load_uint(8) == 0); ;; data onchain tag |
|
|
|
throw_unless(412, cs~load_uint(8) == 0); ;; data onchain tag |
|
|
|