Skip to content

Commit

Permalink
add event support (ontio#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucas7788 authored and laizy committed Oct 23, 2019
1 parent c302606 commit 3ac2003
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 21 deletions.
35 changes: 22 additions & 13 deletions examples/red-envlope/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ostd::abi::{Sink, Source};
use ostd::contract::{ong, ont};
use ostd::database;
use ostd::macros::base58;
use ostd::macros::event;
use ostd::prelude::*;
use ostd::runtime;

Expand All @@ -19,20 +20,20 @@ const CLAIM_PREFIX: &str = "CLAIM_PREFIX_";
#[derive(Encoder, Decoder)]
struct ReceiveRecord {
account: Address,
amount: u64,
amount: u128,
}

#[derive(Encoder, Decoder)]
struct EnvlopeStruct {
token_addr: Address,
total_amount: u64,
total_package_count: u64,
remain_amount: u64,
remain_package_count: u64,
total_amount: u128,
total_package_count: u128,
remain_amount: u128,
remain_package_count: u128,
records: Vec<ReceiveRecord>,
}

fn create_red_envlope(owner: Address, pack_count: u64, amount: u64, token_addr: Address) -> bool {
fn create_red_envlope(owner: Address, pack_count: u128, amount: u128, token_addr: Address) -> bool {
if !runtime::check_witness(&owner) {
return false;
}
Expand All @@ -49,18 +50,18 @@ fn create_red_envlope(owner: Address, pack_count: u64, amount: u64, token_addr:
let re_key = [RE_PREFIX.as_bytes(), hash_bytes].concat();
let self_addr = runtime::address();
if is_ont_address(&token_addr) {
let res = ont::transfer(&owner, &self_addr, amount as u128);
let res = ont::transfer(&owner, &self_addr, amount);
if !res {
return false;
}
} else if is_ong_address(&token_addr) {
let res = ong::transfer(&owner, &self_addr, amount as u128);
let res = ong::transfer(&owner, &self_addr, amount);
if !res {
return false;
}
} else {
let mut sink = Sink::new(16);
sink.write(("transfer", self_addr, owner, amount as u128));
sink.write(("transfer", self_addr, owner, amount));
let res = runtime::call_contract(&token_addr, sink.bytes());
if res.is_none() {
return false;
Expand All @@ -75,7 +76,7 @@ fn create_red_envlope(owner: Address, pack_count: u64, amount: u64, token_addr:
records: Vec::new(),
};
database::put(&re_key, es);
runtime::notify(hash_bytes);
create_red_envlope_event(owner.as_ref(), pack_count, amount, token_addr.as_ref());
true
}

Expand Down Expand Up @@ -126,7 +127,7 @@ fn claim_envlope(account: &Address, hash: &str) -> bool {
part.copy_from_slice(&random.as_bytes()[..8]);
let random_num = U128::from_le_bytes(part) as u64;
let percent = random_num % 100 + 1;
let mut claim_amount = est.remain_amount * percent / 100;
let mut claim_amount = est.remain_amount * percent as u128 / 100;

if claim_amount == 0 {
claim_amount = 1;
Expand All @@ -142,9 +143,9 @@ fn claim_envlope(account: &Address, hash: &str) -> bool {
est.records.push(record);
let self_addr = runtime::address();
if is_ont_address(&est.token_addr) {
return ont::transfer(&self_addr, &account, claim_amount as u128);
return ont::transfer(&self_addr, &account, claim_amount);
} else if is_ong_address(&est.token_addr) {
return ong::transfer(&self_addr, &account, claim_amount as u128);
return ong::transfer(&self_addr, &account, claim_amount);
} else {
let mut sink = Sink::new(16);
sink.write(("transfer", self_addr, account, claim_amount));
Expand All @@ -155,6 +156,7 @@ fn claim_envlope(account: &Address, hash: &str) -> bool {
}
database::put(claim_key, claim_amount);
database::put(re_key, est);
claim_envlope_event(account, hash);
true
}

Expand All @@ -166,6 +168,13 @@ fn is_ont_address(contract_addr: &Address) -> bool {
contract_addr == &ONT_CONTRACT_ADDRESS
}

#[event]
fn create_red_envlope_event(owner: &Address, pack_count: U128, amount: U128, token_addr: &Address) {
}

#[event]
fn claim_envlope_event(account: &Address, hash: &str) {}

#[no_mangle]
pub fn invoke() {
let input = runtime::input();
Expand Down
34 changes: 26 additions & 8 deletions examples/token/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#![no_std]
#![feature(proc_macro_hygiene)]
extern crate ontio_std as ostd;

use ostd::abi::{Encoder, Sink, Source};
use ostd::abi::{Sink, Source};
use ostd::macros::event;
use ostd::prelude::*;
use ostd::{database, runtime};

Expand All @@ -10,8 +12,11 @@ const NAME: &str = "wasm_token";
const SYMBOL: &str = "WTK";
const TOTAL_SUPPLY: U128 = 100_000_000_000;

const _ADDR_ADMIN: Address = ostd::macros::base58!("ANT97HNwurK2LE2LEiU72MsSD684nPyJMX");

fn initialize() -> bool {
database::put(KEY_TOTAL_SUPPLY, TOTAL_SUPPLY);
database::put(_ADDR_ADMIN, TOTAL_SUPPLY);
true
}

Expand All @@ -30,14 +35,33 @@ fn transfer(from: &Address, to: &Address, amount: U128) -> bool {

database::put(from, frmbal - amount);
database::put(to, tobal + amount);
notify(("Transfer", from, to, amount));
notify::transfer(from, to, amount);
notify::transfer_name(from, to, amount);
notify::transfer_test(from, to, amount);
let h = runtime::sha256("test");
notify::event_test(true, b"test", "test", h);
true
}

fn total_supply() -> U128 {
database::get(KEY_TOTAL_SUPPLY).unwrap()
}

mod notify {
use super::*;
#[event]
pub fn transfer(from: &Address, to: &Address, amount: U128) {}

#[event(name = mytransfer)]
pub fn transfer_name(from: &Address, to: &Address, amount: U128) {}

#[event]
pub fn transfer_test(from: &Address, to: &Address, amount: U128) {}

#[event]
pub fn event_test(boo: bool, bs: &[u8], ss: &str, h: H256) {}
}

#[no_mangle]
pub fn invoke() {
let input = runtime::input();
Expand All @@ -62,9 +86,3 @@ pub fn invoke() {

runtime::ret(sink.bytes())
}

fn notify<T: Encoder>(msg: T) {
let mut sink = Sink::new(16);
sink.write(msg);
runtime::notify(sink.bytes());
}
1 change: 1 addition & 0 deletions ontio-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ quote = "1.0"
proc-macro2 = "1.0"
sha2 = { version = "0.8", default-features = false }
num = { version = "0.2"}
heck = {version = "0.3.1",default-features = false}

[dev-dependencies]
ontio-std = {path="../ontio-std"}
Expand Down
49 changes: 49 additions & 0 deletions ontio-codegen/src/event.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use quote::quote;
use quote::ToTokens;
use syn::FnArg;

pub fn quote(method_name: String, func: &syn::ItemFn) -> proc_macro2::TokenStream {
let name = func.sig.ident.clone();
let inputs = func.sig.inputs.iter().map(|v| {
quote! { #v }
});
// Extract parameters, which may be multiple
let params: Vec<_> = func
.sig
.inputs
.iter()
.filter_map(|i| {
match i {
// https://docs.rs/syn/1.0.1/syn/struct.PatType.html
FnArg::Typed(ref val) => Some((val.pat.clone(), val.ty.clone())),
_ => unreachable!("it's not gonna happen."),
}
})
.collect();
let head = quote! {
let mut es = ontio_std::abi::EventBuilder::new();
es = es.string(#method_name);
};
let body = params.iter().map(|&(ref pat, ref ty)| {
let mut param_type = ty.into_token_stream().to_string();
param_type = param_type.replace(" ", "");
match param_type.as_str() {
"Address" | "&Address" => quote! {es = es.address(#pat)},
"U128" => quote! {es = es.number(#pat)},
"&str" => quote! {es = es.string(#pat)},
"&[u8]" => quote! {es = es.bytearray(#pat)},
"bool" => quote! {es = es.bool(#pat)},
"H256" => quote! {es = es.h256(#pat)},
_ => panic!("not support type: {}", param_type.as_str()),
}
});

let gen = quote! {
pub fn #name ( #( #inputs),* ) {
#head
#(#body;)*
es.notify();
}
};
gen.into_token_stream()
}
38 changes: 38 additions & 0 deletions ontio-codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
#![feature(proc_macro_hygiene)]

extern crate proc_macro;
use heck::MixedCase;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Lit};

mod base58;
mod contract;
mod event;

#[proc_macro_attribute]
pub fn contract(_metadata: TokenStream, input: TokenStream) -> TokenStream {
Expand All @@ -17,6 +19,27 @@ pub fn contract(_metadata: TokenStream, input: TokenStream) -> TokenStream {
stream.into()
}

#[proc_macro_attribute]
pub fn event(metadata: TokenStream, input: TokenStream) -> TokenStream {
match syn::parse::<syn::Item>(input).unwrap() {
syn::Item::Fn(ref func) => {
use quote::ToTokens;
let mut method_name;
if metadata.is_empty() {
method_name = func.sig.ident.clone().into_token_stream().to_string();
} else {
method_name = metadata.to_string();
method_name = method_name.replace("name", "");
method_name = method_name.replace("=", "");
}
method_name = method_name.to_mixed_case();
let stream = event::quote(method_name, func);
stream.into()
}
_ => panic!("Only fn is allowed"),
}
}

#[proc_macro]
pub fn base58(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as Lit);
Expand Down Expand Up @@ -61,4 +84,19 @@ mod tests {
fn base58() {
const _ADDR: Address = ontio_std::macros::base58!("AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM");
}

mod notify {
use ontio_std::types::{Address, U128};
#[ontio_std::macros::event]
fn transfer(from: &Address, to: &Address, amount: U128) {}

#[ontio_std::macros::event]
fn transfer_name(from: &Address) {}

#[ontio_std::macros::event(name=transfer_test)]
fn transfer_name2(from: &Address) {}
}

#[test]
fn event() {}
}
1 change: 1 addition & 0 deletions ontio-std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub mod types;
pub mod macros {
pub use ontio_codegen::base58;
pub use ontio_codegen::contract;
pub use ontio_codegen::event;
}

#[cfg(feature = "mock")]
Expand Down

0 comments on commit 3ac2003

Please sign in to comment.