diff --git a/move-dapp/addr-aggregator/Move.toml b/move-dapp/addr-aggregator/Move.toml index f6c10c0..ace1c4b 100644 --- a/move-dapp/addr-aggregator/Move.toml +++ b/move-dapp/addr-aggregator/Move.toml @@ -7,4 +7,4 @@ StarcoinFramework = "0x1" MyAddr = "0x1168e88ffc5cec53b398b42d61885bbb" [dependencies] -StarcoinFramework = {git = "https://github.com/starcoinorg/starcoin-framework.git", rev="cf1deda180af40a8b3e26c0c7b548c4c290cd7e7"} \ No newline at end of file +StarcoinFramework = {git = "https://github.com/starcoinorg/starcoin-framework.git", rev="9ea61ce1429070c945002b26ef5f5ea6b72884e4"} \ No newline at end of file diff --git a/move-dapp/addr-aggregator/sources/AddrAggregator.move b/move-dapp/addr-aggregator/sources/AddrAggregator.move index de9cc16..8e9a898 100644 --- a/move-dapp/addr-aggregator/sources/AddrAggregator.move +++ b/move-dapp/addr-aggregator/sources/AddrAggregator.move @@ -1,28 +1,81 @@ module MyAddr::AddrAggregator { use StarcoinFramework::Vector; use StarcoinFramework::Signer; + use StarcoinFramework::Timestamp; + use StarcoinFramework::Signature; + use StarcoinFramework::BCS; use StarcoinFramework::Option::{Self, Option}; + #[test_only] + use StarcoinFramework::Debug; struct AddrInfo has store, copy, drop { addr: address, description: vector, chain_name: vector, - signature: vector + signature: vector, + id : u64 } struct AddrAggregator has key { key_addr: address, - addr_infos: vector + addr_infos: vector, + max_id : u64 } public fun create_addr_aggregator(acct: &signer){ let addr_aggr = AddrAggregator{ key_addr: Signer::address_of(acct), - addr_infos: Vector::empty() + addr_infos: Vector::empty(), + max_id : 0 }; move_to(acct, addr_aggr); } + //split string by char + public fun split_char(v: &vector, ch: u8) : vector> { + let result = Vector::empty>(); + + // let len = Vector::length(&string.bytes); + let len = Vector::length(v); + let i = 0; + // let flag = false; + let buffer = Vector::empty(); + while ( i < len ) { + let byte = *Vector::borrow(v, i); + if (byte != ch) { + Vector::push_back(&mut buffer, byte); + } else { + Vector::push_back(&mut result, buffer); + buffer = Vector::empty(); + }; + + i = i+1; + }; + if (Vector::length(&buffer) != 0) { + Vector::push_back(&mut result, buffer); + }; + + result + } + + // vector transfter to timestamp + public fun transfer_timestamp(timestamp_vec: vector): u64{ + let prev_time = 0; + let prev_time_length = Vector::length(×tamp_vec); + if (prev_time_length != 10) { + abort 1002 + }; + let i=0; + while (i < prev_time_length) { + let char = Vector::borrow(&mut timestamp_vec, i); + if (*char >= 48 && *char <= 57) { + prev_time = prev_time*10 + ((*char - 48) as u64); + }; + i = i+1; + }; + prev_time + } + /// add addr without signature is permitted, and the owner can add signature later. public fun add_addr( acct: &signer, @@ -32,10 +85,31 @@ module MyAddr::AddrAggregator { msg: Option>, signature: Option>) acquires AddrAggregator{ if (Option::is_some>(&signature) && Option::is_some>(&msg)) { - // TODO: + let msg_bytes = Option::borrow(&msg); + let signature_bytes = Option::borrow(&signature); + let split_vec = split_char(msg_bytes, 0x5f); + // verify the format of msg is valid + if (Vector::length(&mut split_vec) != 3) { + abort 1001 + }; + // verify the signature for the msg addr_chain_name_timestamp + let addr_bytes =BCS::to_bytes
(&addr); + if (!Signature::secp256k1_verify(*signature_bytes, addr_bytes, *msg_bytes)) { + abort 1002 + }; + + let timestamp_vec = Vector::borrow(&split_vec, 2); + let prev_time = transfer_timestamp(*timestamp_vec); + let now_time = Timestamp::now_seconds(); + let elapsed_time = now_time - prev_time; + // verify the timestamp - timestamp_now >= 2h is true + if (elapsed_time < 2*60*60) { + abort 1003 + }; + // then add addr do_add_addr(acct, addr, chain_name, description, Option::destroy_some>(signature)); } else { @@ -49,18 +123,102 @@ module MyAddr::AddrAggregator { chain_name: vector, description: vector, signature: vector) acquires AddrAggregator{ - let addr_aggr = borrow_global_mut(Signer::address_of(acct)); + let addr_aggr = borrow_global_mut(Signer::address_of(acct)); + let id = addr_aggr.max_id + 1; + let addr_info = AddrInfo{ addr: addr, chain_name: chain_name, description: description, - signature: signature + signature: signature, + id : id, }; Vector::push_back(&mut addr_aggr.addr_infos, addr_info); + addr_aggr.max_id = addr_aggr.max_id + 1; } - // TODO: + // public fun update addr with sig + public fun update_addr_with_sig( + acct: &signer, + addr: address, + signature: vector) acquires AddrAggregator{ + let addr_aggr = borrow_global_mut(Signer::address_of(acct)); + let length = Vector::length(&mut addr_aggr.addr_infos); + let i = 0; + while (i < length) { + let addr_info = Vector::borrow_mut(&mut addr_aggr.addr_infos, i); + if (addr_info.addr == addr) { + addr_info.signature = signature; + break + } + }; + } + // public fun update addr with description and sig + public fun update_addr_with_description_and_sig( + acct: &signer, + addr: address, + signature: vector, + description: vector) acquires AddrAggregator{ + let addr_aggr = borrow_global_mut(Signer::address_of(acct)); + let length = Vector::length(&mut addr_aggr.addr_infos); + let i = 0; + while (i < length) { + let addr_info = Vector::borrow_mut(&mut addr_aggr.addr_infos, i); + if (addr_info.addr == addr) { + addr_info.signature = signature; + addr_info.description = description; + break + } + }; + } + // public fun delete addr + public fun delete_addr( + acct: &signer, + addr: address) acquires AddrAggregator{ + let addr_aggr = borrow_global_mut(Signer::address_of(acct)); + let length = Vector::length(&mut addr_aggr.addr_infos); + let i = 0; + while (i < length) { + let addr_info = Vector::borrow(&mut addr_aggr.addr_infos, i); + if (addr_info.addr == addr) { + Vector::remove(&mut addr_aggr.addr_infos, i); + } + } + } -} + + #[test] + public fun split_char_test(){ + let origin = b"a_b_c"; + Debug::print(&origin); + let result = split_char(&mut origin, 0x5f); // _ ansci is 0x5f + Debug::print(&result); + assert!(Vector::length(&mut result) == 3, 101); + + let origin = b"a_b_"; + Debug::print(&origin); + let result = split_char(&mut origin, 0x5f); // _ ansci is 0x5f + Debug::print(&result); + assert!(Vector::length(&mut result) == 2, 101); + + let origin = b"a"; + Debug::print(&origin); + let result = split_char(&mut origin, 0x5f); // _ ansci is 0x5f + Debug::print(&result); + assert!(Vector::length(&mut result) == 1, 101); + } + + #[test] + public fun transfer_timestamp_test() { + let ts_str = b"1661049255"; + // let length = Vector::length(&ts_str); + Debug::print(&ts_str); + + let expected_ts = 1661049255; + let real_ts = transfer_timestamp(ts_str); + Debug::print(&real_ts); + assert!( real_ts==expected_ts, 110); + } +} \ No newline at end of file