Browse Source

instant buy - first attempt

dev/signature-instant-buy
igor 2 years ago
parent
commit
463e790ef7
  1. 1
      contracts/imports/op-codes.fc
  2. 106
      contracts/main.fc

1
contracts/imports/op-codes.fc

@ -17,6 +17,7 @@ int op::editorship_assigned() asm "0x511a4463 PUSHINT";
;; Collection
int op::new_nft() asm "0x1a039a51 PUSHINT";
int op::instant_buy_new_nft() asm "16c7d435 PUSHINT";
;; DNS
const int op::fill_up = 0x370fec51;

106
contracts/main.fc

@ -90,20 +90,35 @@ slice calculate_nft_item_address(int wc, cell state_init) {
.begin_parse();
}
cell pack_state(cell content, cell nft_item_code, int index, slice collection_address, slice owner_address, cell domain, cell auction, int last_fill_up_time) impure {
return begin_cell()
.store_ref(nft_item_code)
.store_uint(index, 256)
.store_slice(collection_address)
.store_slice(owner_address)
.store_ref(content)
.store_ref(domain)
.store_dict(auction)
.store_uint(last_fill_up_time, 64)
.end_cell();
}
;; Serialize the data using the storage schema
() store_data(cell content, cell nft_item_code, int index, slice collection_address, slice owner_address, cell domain, cell auction, int last_fill_up_time) impure {
set_data(
begin_cell()
.store_ref(nft_item_code)
.store_uint(index, 256)
.store_slice(collection_address)
.store_slice(owner_address)
.store_ref(content)
.store_ref(domain)
.store_dict(auction)
.store_uint(last_fill_up_time, 64)
.end_cell()
);
;; set_data(
;; begin_cell()
;; .store_ref(nft_item_code)
;; .store_uint(index, 256)
;; .store_slice(collection_address)
;; .store_slice(owner_address)
;; .store_ref(content)
;; .store_ref(domain)
;; .store_dict(auction)
;; .store_uint(last_fill_up_time, 64)
;; .end_cell()
;; );
set_data(pack_state(content, nft_item_code, index, collection_address, owner_address, domain, auction, last_fill_up_time));
}
() send_msg(slice to_address, int amount, int op, int query_id, builder payload, int send_mode) impure inline {
@ -186,6 +201,42 @@ slice calculate_nft_item_address(int wc, cell state_init) {
send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
}
cell pack_nft_item_state(cell nft_item_code, cell data) impure {
return begin_cell().store_uint(0, 2).store_dict(nft_item_code).store_dict(data).store_uint(0, 1).end_cell();
}
() deploy_bought_item(int item_index, cell code, slice owner_address, slice domain) impure {
;; cell nft_item_code
;; uint256 index --- The index of this item in the collection
;; MsgAddressInt collection_address
;; MsgAddressInt owner_address
;; cell content --- The key-value map with the content both as item and a collection)
;; cell domain --- e.g contains "alice" (without ending \0) for "alice.ton" domain
;; cell auction --- auction info: (address max_bid_address, coins max_bid, uint32 end_time)
;; int last_fill_up_time
cell init_data = begin_cell()
.store_ref(code)
.store_uint(item_index, 256)
.store_slice(my_address())
.store_slice(owner_address)
.store_dict(null())
.store_ref(begin_cell().store_uint(1, 1).store_slice(domain).end_cell()) ;; TODO: snake cell
.store_dict(null())
.store_uint(0, 64)
.end_cell();
cell state_init = pack_nft_item_state(code, init_data);
slice nft_address = calculate_nft_item_address(workchain(), state_init);
var msg = begin_cell()
.store_uint(0x18, 6)
.store_slice(nft_address)
.store_coins(0)
.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
.store_ref(state_init)
.store_uint(1, 1); ;; the content of the NFT item, will be treated as the parameter of the first incoming message
send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
}
() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure {
if (in_msg_body.slice_empty?()) { ;; bounce back empty messages
throw(0xffff);
@ -228,6 +279,10 @@ slice calculate_nft_item_address(int wc, cell state_init) {
if (months > 12) {
months = 12;
}
;; move this to auction data: auction_start_time, auction_start_duration, auction_end_duration, auction_prolongation, price_multiplicator
;; instant buy:
;; The auction duration becomes shorter over time
int duration = auction_start_duration - (auction_start_duration - auction_end_duration) * months / 12;
@ -259,6 +314,33 @@ slice calculate_nft_item_address(int wc, cell state_init) {
store_data(content, item_code, index, collection_address, owner_address, domain, auction, last_fill_up_time);
}
if (op == op::instant_buy_new_nft()) {
;; parsing of the signed 'option'
;; signature structure: (receiver_addr, collection_address, )
cell option_data = in_msg_body~load_ref();
cell signature = in_msg_body~load_ref();
slice reader = option_data.begin_parse();
slice receiver_addr = reader~load_msg_addr();
slice issued_collection_addr = reader~load_msg_addr();
int amount = reader~load_uint(256);
slice new_domain = reader;
throw_unless(411, slice_bits(new_domain) > 0);
throw_unless(412, equal_slices(receiver_addr, sender_address)); ;; TODO: Unsure here
throw_unless(413, equal_slices(issued_collection_addr, my_address()));
int success = check_data_signature(option_data.begin_parse(), signature.begin_parse(), owner_address);
throw_unless(413, success);
throw_unless(414, msg_value > amount);
amount_to_send = msg_value - amount; ;; TODO: Handle this later, reroute coins
int new_item_index = slice_hash(new_domain);
deploy_bought_item(item_index, cell item_code, slice receiver_addr, slice new_domain);
return ();
;; init_state = pack_state(... add domain here ...)
;; use modified function `deploy_nft_item` <- init_state
}
if (op == op::new_nft()) {
throw_unless(401, equal_slices(sender_address, owner_address));
;; TODO (this is like the most important part)

Loading…
Cancel
Save