Skip to content

Commit

Permalink
add ont ong decimals (#118)
Browse files Browse the repository at this point in the history
* add ont ong decimals

* update ont ong v2 code

* update
  • Loading branch information
lucas7788 authored Nov 11, 2021
1 parent ff266d4 commit 2e6dfda
Show file tree
Hide file tree
Showing 2 changed files with 340 additions and 5 deletions.
50 changes: 45 additions & 5 deletions examples/call_native/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#![no_std]
#![feature(proc_macro_hygiene)]
extern crate ontio_std as ostd;

use ostd::abi::{Sink, Source};
use ostd::contract::ontid;
use ostd::contract::ong;
use ostd::contract::ont;
use ostd::runtime;
use ostd::runtime::panic;

#[no_mangle]
pub fn invoke() {
Expand All @@ -12,11 +15,48 @@ pub fn invoke() {
let action: &[u8] = source.read().unwrap();
let mut sink = Sink::new(12);
match action {
b"verifySignature" => {
let (ont_id, index) = source.read().unwrap();
sink.write(ontid::verify_signature(ont_id, index));
b"ontTransferV2" => {
let (from, to, amount) = source.read().unwrap();
sink.write(ont::v2::transfer(from, to, amount));
}
b"ontBalanceOfV2" => {
let from = source.read().unwrap();
sink.write(ont::v2::balance_of(from));
}
b"ontApproveV2" => {
let (from, to, amount) = source.read().unwrap();
sink.write(ont::v2::approve(from, to, amount));
}
b"ontAllowanceV2" => {
let (from, to) = source.read().unwrap();
sink.write(ont::v2::allowance(from, to));
}
b"ontTransferFromV2" => {
let (spender, from, to, amount) = source.read().unwrap();
sink.write(ont::v2::transfer_from(spender, from, to, amount));
}

b"ongTransferV2" => {
let (from, to, amount) = source.read().unwrap();
sink.write(ong::v2::transfer(from, to, amount));
}
b"ongBalanceOfV2" => {
let from = source.read().unwrap();
sink.write(ong::v2::balance_of(from));
}
b"ongApproveV2" => {
let (from, to, amount) = source.read().unwrap();
sink.write(ong::v2::approve(from, to, amount));
}
b"ongAllowanceV2" => {
let (from, to) = source.read().unwrap();
sink.write(ong::v2::allowance(from, to));
}
b"ongTransferFromV2" => {
let (spender, from, to, amount) = source.read().unwrap();
sink.write(ong::v2::transfer_from(spender, from, to, amount));
}
_ => panic!("unsupported action!"),
_ => panic("unsupported action!"),
}

runtime::ret(sink.bytes())
Expand Down
295 changes: 295 additions & 0 deletions ontio-std/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,112 @@ pub mod ont {
pub fn transfer_from(sender: &Address, from: &Address, to: &Address, amount: U128) -> bool {
super::util::transfer_from_inner(&ONT_CONTRACT_ADDRESS, sender, from, to, amount)
}

pub mod v2 {
use super::*;
use crate::contract::util;

///Transfer method of ont assets, Transfer ont assets from the from address to the to address
/// # Example
/// ```no_run
/// # use ontio_std::contract::ont;
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input= input();
/// let mut source = Source::new(&input);
/// let (from, to, amount) = source.read().unwrap();
/// ont::transfer(from,to, amount);
/// ```
pub fn transfer(from: &Address, to: &Address, val: U128) -> bool {
let state = [TransferParam { from: *from, to: *to, amount: val }];
util::transfer_inner_v2(&ONT_CONTRACT_ADDRESS, state.as_ref())
}

///transfer_multi method of ont assets,Multiple transfers in one transaction
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ont,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// # use ontio_std::types::{Address, U128};
/// let input = input();
/// let mut source = Source::new(&input);
/// let trs: Vec<(Address,Address,U128)> = source.read().unwrap();
/// let mut ts = Vec::<TransferParam>::new();
/// for tr in trs.iter() {
/// let trans = TransferParam{
/// from:tr.0,
/// to:tr.1,
/// amount:tr.2,
/// };
/// ts.push(trans)
/// }
/// ont::transfer_multi(ts.as_slice());
/// ```
pub fn transfer_multi(transfer: &[TransferParam]) -> bool {
util::transfer_inner_v2(&ONT_CONTRACT_ADDRESS, transfer)
}

///from-address can allow to-address to transfer a certain amount of assets from from-address.
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ont,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let (from,to,amount) = source.read().unwrap();
/// ont::approve(from, to, amount);
/// ```
pub fn approve(from: &Address, to: &Address, amount: U128) -> bool {
util::approve_inner_v2(&ONT_CONTRACT_ADDRESS, from, to, amount)
}

///Query the balance of ont assets
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ont,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let addr = source.read().unwrap();
/// ont::balance_of(addr);
/// ```
pub fn balance_of(address: &Address) -> U128 {
util::balance_of_inner_v2(&ONT_CONTRACT_ADDRESS, address)
}

///This method is used in conjunction with the approve method to query the number of approve
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ont,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input= input();
/// let mut source = Source::new(&input);
/// let (from, to) = source.read().unwrap();
/// ont::allowance(from,to);
/// ```
pub fn allowance(from: &Address, to: &Address) -> U128 {
util::allowance_inner_v2(&ONT_CONTRACT_ADDRESS, from, to)
}

///Spender transfers a certain amount of ont from from-address to to-address
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ont,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input= input();
/// let mut source = Source::new(&input);
/// let (spender, from, to, amount) = source.read().unwrap();
/// ont::transfer_from(spender, from, to, amount);
/// ```
pub fn transfer_from(sender: &Address, from: &Address, to: &Address, amount: U128) -> bool {
util::transfer_from_inner_v2(&ONT_CONTRACT_ADDRESS, sender, from, to, amount)
}
}
}

///This module provides the operation API related to ong assets, such as balanceof, transfer, etc.
Expand Down Expand Up @@ -422,6 +528,111 @@ pub mod ong {
pub fn transfer_from(sender: &Address, from: &Address, to: &Address, amount: U128) -> bool {
super::util::transfer_from_inner(&ONG_CONTRACT_ADDRESS, sender, from, to, amount)
}

pub mod v2 {
use super::*;
use crate::contract::util;

///Transfer method of ong assets, Transfer ont assets from the from address to the to address
/// # Example
/// ```no_run
/// # use ontio_std::contract::ong;
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let (from, to, amount) = source.read().unwrap();
/// ong::transfer(from,to, amount);
/// ```
pub fn transfer(from: &Address, to: &Address, val: U128) -> bool {
let state = [TransferParam { from: *from, to: *to, amount: val }];
util::transfer_inner_v2(&ONG_CONTRACT_ADDRESS, state.as_ref())
}

///transfer_multi method of ong assets,Multiple transfers in one transaction
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ong,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// # use ontio_std::types::{Address,U128};
/// let input = input();
/// let mut source = Source::new(&input);
/// let trs: Vec<(Address,Address,U128)> = source.read().unwrap();
/// let mut transfers = Vec::<TransferParam>::new();
/// for tr in trs.iter() {
/// transfers.push(TransferParam{
/// from:tr.0,
/// to:tr.1,
/// amount:tr.2,
/// })
/// }
/// ong::transfer_multi(transfers.as_slice());
/// ```
pub fn transfer_multi(transfer: &[super::TransferParam]) -> bool {
util::transfer_inner_v2(&ONG_CONTRACT_ADDRESS, transfer)
}

///Query the balance of ong assets
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ong,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let addr = source.read().unwrap();
/// ong::balance_of(addr);
/// ```
pub fn balance_of(address: &Address) -> U128 {
util::balance_of_inner_v2(&ONG_CONTRACT_ADDRESS, address)
}

///from-address can allow to-address to transfer a certain amount of assets from from-address.
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ong,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let (from,to,amount) = source.read().unwrap();
/// ong::approve(from, to, amount);
/// ```
pub fn approve(from: &Address, to: &Address, amount: U128) -> bool {
util::approve_inner_v2(&ONG_CONTRACT_ADDRESS, from, to, amount)
}

///This method is used in conjunction with the approve method to query the number of approve
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ong};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let (from, to) = source.read().unwrap();
/// ong::allowance(from,to);
/// ```
pub fn allowance(from: &Address, to: &Address) -> U128 {
util::allowance_inner_v2(&ONG_CONTRACT_ADDRESS, from, to)
}

///Spender transfers a certain amount of ong from from-address to to-address
/// # Example
/// ```no_run
/// # use ontio_std::contract::{ong,TransferParam};
/// # use ontio_std::abi::{Sink, Source};
/// # use ontio_std::runtime::input;
/// let input = input();
/// let mut source = Source::new(&input);
/// let (spender, from, to, amount) = source.read().unwrap();
/// ong::transfer_from(spender, from, to, amount);
/// ```
pub fn transfer_from(sender: &Address, from: &Address, to: &Address, amount: U128) -> bool {
util::transfer_from_inner_v2(&ONG_CONTRACT_ADDRESS, sender, from, to, amount)
}
}
}

pub(crate) mod util {
Expand Down Expand Up @@ -514,4 +725,88 @@ pub(crate) mod util {
}
U128::new(0)
}

pub(crate) fn transfer_inner_v2(
contract_address: &Address, transfer: &[super::TransferParam],
) -> bool {
let mut sink = Sink::new(64);
sink.write_native_varuint(transfer.len() as u64);

for state in transfer.iter() {
sink.write_native_address(&state.from);
sink.write_native_address(&state.to);
sink.write(u128_to_neo_bytes(state.amount));
}
let mut sink_param = Sink::new(128);
sink_param.write(VERSION);
sink_param.write("transferV2");
sink_param.write(sink.bytes());
let output = runtime::call_contract(contract_address, sink_param.bytes());

!output.is_empty() && output[0] == 1u8
}

pub(crate) fn approve_inner_v2(
contract_address: &Address, from: &Address, to: &Address, amount: U128,
) -> bool {
let mut sink = Sink::new(64);
sink.write_native_address(from);
sink.write_native_address(to);
sink.write(u128_to_neo_bytes(amount));
let mut sink_param = Sink::new(128);
sink_param.write(VERSION);
sink_param.write("approveV2");
sink_param.write(sink.bytes());
let output = runtime::call_contract(contract_address, sink_param.bytes());

!output.is_empty() && output[0] == 1u8
}

pub(crate) fn transfer_from_inner_v2(
contract_address: &Address, sender: &Address, from: &Address, to: &Address, amount: U128,
) -> bool {
let mut sink = Sink::new(64);
sink.write_native_address(sender);
sink.write_native_address(from);
sink.write_native_address(to);
sink.write(u128_to_neo_bytes(amount));
let mut sink_param = Sink::new(128);
sink_param.write(VERSION);
sink_param.write("transferFromV2");
sink_param.write(sink.bytes());
let output = runtime::call_contract(contract_address, sink_param.bytes());

!output.is_empty() && output[0] == 1u8
}

pub(crate) fn allowance_inner_v2(
contract_address: &Address, from: &Address, to: &Address,
) -> U128 {
let mut sink = Sink::new(64);
sink.write_native_address(from);
sink.write_native_address(to);
let mut sink_param = Sink::new(64);
sink_param.write(VERSION);
sink_param.write("allowanceV2");
sink_param.write(sink.bytes());
let output = runtime::call_contract(contract_address, sink_param.bytes());
if !output.is_empty() {
return u128_from_neo_bytes(&output);
}
U128::new(0)
}

pub(crate) fn balance_of_inner_v2(contract_address: &Address, address: &Address) -> U128 {
let mut sink = Sink::new(64);
sink.write_native_address(address);
let mut sink_param = Sink::new(64);
sink_param.write(VERSION);
sink_param.write("balanceOfV2");
sink_param.write(sink.bytes());
let output = runtime::call_contract(contract_address, sink_param.bytes());
if !output.is_empty() {
return u128_from_neo_bytes(&output);
}
U128::new(0)
}
}

0 comments on commit 2e6dfda

Please sign in to comment.