Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
austinabell committed Jan 19, 2022
0 parents commit ce623ce
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ft-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
7 changes: 7 additions & 0 deletions ft-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "ft-api"
version = "0.1.0"
edition = "2021"

[dependencies]
near-sdk = "4.0.0-pre.5"
69 changes: 69 additions & 0 deletions ft-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use near_sdk::AccountId;

pub trait Contract: Send + Sync {
fn transfer(&mut self, from: AccountId, to: AccountId, amount: u64);
fn balance(&self, of: AccountId) -> u64;
}

// Blockchain-side API *and* implementation of the contract. Physically, "API"
// is some `(func (export "name"))` in WASM, which is represented as `extern
// "C"` in Rust.
//
// Note that this is an actual **implementation** of the said API -- these are
// functions declared & defined in the upstream crate, which use "dynamic"
// dispatch internally to call downstream code
pub extern "C" fn transfer() {
#[derive(near_sdk::serde::Deserialize)]
#[serde(crate = "near_sdk::serde")]
struct Input {
from: AccountId,
to: AccountId,
amount: u64,
}
let Input { from, to, amount }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");

unsafe { ft_get_vtable() }.transfer(from, to, amount)
}

pub extern "C" fn balance() {
#[derive(near_sdk::serde::Deserialize)]
#[serde(crate = "near_sdk::serde")]
struct Input {
of: AccountId,
}
let Input { of }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");

let result = unsafe { ft_get_vtable() }.balance(of);

let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}

// This is the hook which is defined upstream, but whose implementation is going
// to be defined downstream.
extern "C" {
#[allow(improper_ctypes)]
fn ft_get_vtable() -> Box<dyn Contract>;
}

// This allows the user to register their contract as the implementation for the
// singleton instance.
//
// The salient point here is that method signatures don't have to be specified,
// they are encoded solely by the trait.
#[macro_export]
macro_rules! register {
($e:ty) => {
#[no_mangle]
extern "C" fn ft_get_vtable() -> Box<$e> {
Box::<$e>::new(near_sdk::env::state_read().unwrap_or_default())
}
};
}
2 changes: 2 additions & 0 deletions my-token/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.wasm32-unknown-unknown]
rustflags = ["-C", "link-arg=-s"]
2 changes: 2 additions & 0 deletions my-token/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
19 changes: 19 additions & 0 deletions my-token/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "my-token"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
ft-api = { path = "../ft-api" }
near-sdk = "4.0.0-pre.5"

[profile.release]
codegen-units = 1
# Tell `rustc` to optimize for small code size.
opt-level = "z"
lto = true
debug = false
panic = "abort"
27 changes: 27 additions & 0 deletions my-token/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use near_sdk::{
borsh::{self, BorshDeserialize, BorshSerialize},
AccountId,
};

#[derive(Default, BorshDeserialize, BorshSerialize)]
struct MyContract {
data: u8,
}

impl ft_api::Contract for MyContract {
fn transfer(&mut self, from: AccountId, to: AccountId, amount: u64) {
near_sdk::log!("from: {}, to: {}, amount: {}", from, to, amount);
}

fn balance(&self, of: AccountId) -> u64 {
near_sdk::log!("balance {}", of);
8
}
}

ft_api::register!(MyContract);

// #[no_mangle]
// extern "C" fn ft_get_vtable() -> Box<MyContract> {
// Box::<MyContract>::new(near_sdk::env::state_read().unwrap_or_default())
// }

0 comments on commit ce623ce

Please sign in to comment.