Browse Source

verifying signature & parsing input

dev/signature-instant-buy
Lev 2 years ago
parent
commit
0c2565304e
  1. 57
      contracts/imports/dns-utils.fc
  2. 3
      contracts/main.ts
  3. 16
      contracts/nft-collection.fc

57
contracts/imports/dns-utils.fc

@ -82,10 +82,10 @@ int check_domain_string(slice domain) {
if (~ need_break) { if (~ need_break) {
int char = str~load_uint(8); int char = str~load_uint(8);
need_break = char == 59; ;; ';' need_break = char == 59; ;; ';'
if (~ need_break) {
i += 8; i += 8;
} if (~ need_break) {
result1~store_uint(char, 8); result1~store_uint(char, 8);
}
if (~ need_break & (i >= len)) { if (~ need_break & (i >= len)) {
throw(259); ;; no ';' found throw(259); ;; no ';' found
} }
@ -94,6 +94,59 @@ int check_domain_string(slice domain) {
return (result1.end_cell().begin_parse(), str~load_bits(len - i)); return (result1.end_cell().begin_parse(), str~load_bits(len - i));
} }
(slice) decode_asciicode(slice str) {
;; Decode the signature encoded into a slice of [a-zA-Z0-9_-] characters
;; into a slice of bytes.
;; Each byte of the input encodes 8 bytes of the output
int len = slice_bits(str);
int need_break = 0;
builder result = begin_cell();
do {
need_break = len == 0;
if (~ need_break) {
int char = str~load_uint(8);
int byte = 0;
if (char >= 65) {
if (char <= 90) { ;; a-z -> 0-25
byte = char - 65;
} else {
if (char >= 97) { ;; A-Z -> 26-51
if (char <= 122) {
byte = char - 71;
} else {
if (char >= 48) { ;; 0-9 -> 52-61
if (char <= 57) {
byte = char + 4;
} else {
if (char == 45) { ;; - -> 62
byte = 62;
} else {
if (char == 95) { ;; _ -> 63
byte = 63;
} else {
throw(260); ;; invalid character
}
}
}
} else {
throw(260); ;; invalid character
}
}
} else {
throw(260); ;; invalid character
}
}
} else {
throw(260); ;; invalid character
}
result~store_uint(byte, 6);
len -= 8;
}
} until (need_break);
return result.end_cell().begin_parse();
}
(int, int) get_min_price_config(int domain_char_count) { (int, int) get_min_price_config(int domain_char_count) {
if (domain_char_count == 4) { if (domain_char_count == 4) {
return (1000, 100); return (1000, 100);

3
contracts/main.ts

@ -63,9 +63,10 @@ export function transferOwnership(params: { newOwnerAddress: Address }): Cell {
} }
export function createItem(params: { domain: String }): Cell { export function createItem(params: { domain: String }): Cell {
let signature = '000';
return beginCell() return beginCell()
.storeUint(0, 32) .storeUint(0, 32)
.storeRef(makeSnakeCell(Buffer.from(params.domain))) .storeRef(makeSnakeCell(Buffer.from(params.domain + ';' + signature)))
.endCell(); .endCell();
} }

16
contracts/nft-collection.fc

@ -4,7 +4,7 @@
#include "imports/params.fc"; #include "imports/params.fc";
;; -1 if needed, 0 if not ;; -1 if needed, 0 if not
const signature_needed = -1; const signature_needed = 0;
;; storage scheme ;; storage scheme
;; cell collection_content ;; cell collection_content
@ -71,9 +71,9 @@ 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 send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
} }
int verify_signature(cell signature, slice sender_address, slice domain, int owner_key) { int verify_signature(slice signature, slice sender_address, slice domain, int owner_key) {
cell option_data = begin_cell().store_slice(domain).store_slice(sender_address).end_cell(); cell option_data = begin_cell().store_slice(my_address()).store_slice(domain).store_slice(sender_address).end_cell();
return check_signature(slice_hash(option_data.begin_parse()), signature.begin_parse(), owner_key); return check_signature(slice_hash(option_data.begin_parse()), signature, owner_key);
} }
() 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 {
@ -93,7 +93,8 @@ int verify_signature(cell signature, slice sender_address, slice domain, int own
if (op == 0) { ;; deploy new nft if (op == 0) { ;; deploy new nft
int now_time = now(); int now_time = now();
slice domain = read_domain_from_comment(in_msg_body); slice body = read_comment(in_msg_body);
(slice domain, slice signature_encoded) = split_by_semicolon(body);
int len = slice_bits(domain); int len = slice_bits(domain);
int price = calcprice(domain, pricing); int price = calcprice(domain, pricing);
throw_unless(204, msg_value >= price); throw_unless(204, msg_value >= price);
@ -102,9 +103,8 @@ int verify_signature(cell signature, slice sender_address, slice domain, int own
slice sender_address = cs~load_msg_addr(); slice sender_address = cs~load_msg_addr();
if (signature_needed) { if (signature_needed) {
;; todo: do stuff here slice signature = decode_asciicode(signature_encoded);
;; cell signature = in_msg_body~load_ref(); throw_unless(205, verify_signature(signature, sender_address, domain, key));
;; throw_unless(205, verify_signature(signature, sender_address, domain, key));
} }
cell nft_content = begin_cell() cell nft_content = begin_cell()

Loading…
Cancel
Save