-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
157 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,4 @@ | ||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
fn it_works() { | ||
assert_eq!(2 + 2, 4); | ||
} | ||
} | ||
#[cfg(feature = "token")] | ||
pub mod token; | ||
#[cfg(feature = "token")] | ||
pub use token::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
//! ERC20 contract handler | ||
//! The handler helps you deploy/generate ERC20 token, just like manipulating a | ||
//! database. | ||
//! | ||
//! The general way we connect to a DB is to use the connection string | ||
//! > postgres://user:password@127.0.0.1:5432 | ||
//! | ||
//! This handler mimic the database connecting way for ERC20 contract, and | ||
//! automatically deploy the contract if needed | ||
//! >>> | ||
//! erc20://sender_address@node_ip:node_port/ERC20_contract_config_file_path | ||
//! erc20://sender_address@node_ip:node_port/contract_address | ||
//! >>> | ||
|
||
use crate::token::errors::ContractError as Error; | ||
use anyhow::Result; | ||
use ethereum_types::Address; | ||
use serde_derive::{Deserialize, Serialize}; | ||
use std::path::PathBuf; | ||
|
||
/// ERC20ContractHandler helps you deploy or interactive with the existing | ||
/// ERC 20 contract | ||
#[derive(Debug, Clone, Deserialize, Serialize, Default)] | ||
pub struct ERC20ContractHandler { | ||
/// The contract address, when the contract is not deployed, | ||
/// the `connect` function called the contract will be automatically | ||
/// deployed and the address field of the config will be filled | ||
pub address: Option<Address>, | ||
|
||
#[serde(skip_serializing)] | ||
/// The contract data in hex literal for eWasm binary, or a file path to | ||
/// the .ewasm file | ||
pub call_data: Option<String>, | ||
|
||
/// If the ERC20_contract_config_file_path pass from the connection string, | ||
/// this field will be filled | ||
#[serde(skip)] | ||
pub(crate) config_file_path: Option<PathBuf>, | ||
} | ||
|
||
impl ERC20ContractHandler { | ||
/// Reach the contract, if the contract is not exist, then deploy it first | ||
pub fn connect(&mut self) -> Result<()> { | ||
if self.address.is_none() { | ||
return self.deploy(); | ||
} | ||
Ok(()) | ||
} | ||
|
||
/// deploy the contract from call data store contract address into config | ||
fn deploy(&mut self) -> Result<()> { | ||
if let Some(_config_file_path) = self.config_file_path.take() { | ||
if let Some(call_data) = self.call_data.take() { | ||
if let Some(call_data) = ERC20ContractHandler::get_call_data(call_data) { | ||
if call_data.len() < 4 { | ||
return Err(Error::ContractSizeError(call_data.len()).into()); | ||
} | ||
return Ok(()); | ||
} | ||
} | ||
return Err(Error::InsufficientContractInfoError.into()); | ||
} | ||
panic!("config_file_path should be update when ERC20ContractHandler construct") | ||
} | ||
/// Return the call data binary from hex literal or from a ewasm file | ||
fn get_call_data(_call_data_info: String) -> Option<Vec<u8>> { | ||
Some(vec![0, 0]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use thiserror::Error; | ||
|
||
#[derive(Error, Debug, PartialEq)] | ||
pub enum ContractError { | ||
#[error("the size of contract `{0}` is not correct")] | ||
ContractSizeError(usize), | ||
#[error("contract address and call data are both absent")] | ||
InsufficientContractInfoError, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pub mod erc20; | ||
pub mod errors; | ||
|
||
#[cfg(test)] | ||
mod tests; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use crate::erc20::ERC20ContractHandler; | ||
use crate::errors::ContractError as Error; | ||
use ethereum_types::H160; | ||
use toml; | ||
|
||
#[test] | ||
fn test_config_serde() { | ||
let c1 = ERC20ContractHandler { | ||
address: Some(H160::from_low_u64_be(15)), | ||
call_data: Some("0x12345678".into()), | ||
..Default::default() | ||
}; | ||
assert_eq!( | ||
toml::to_string(&c1).unwrap(), | ||
"address = \"0x000000000000000000000000000000000000000f\"\n" | ||
); | ||
|
||
let c2: ERC20ContractHandler = | ||
toml::from_str("address = \"0x000000000000000000000000000000000000000f\"\n").unwrap(); | ||
assert_eq!(c2.address, c1.address); | ||
|
||
let c3: ERC20ContractHandler = toml::from_str("call_data = \"0x12345678\"\n").unwrap(); | ||
assert_eq!(c3.address, None); | ||
assert_eq!(c3.call_data.unwrap(), "0x12345678".to_string()); | ||
} | ||
|
||
#[test] | ||
fn test_handle_error_config() { | ||
let mut c1 = ERC20ContractHandler { | ||
address: None, | ||
call_data: None, | ||
config_file_path: Some("/path/to/config".into()), | ||
}; | ||
let connect_result = c1.connect(); | ||
assert!(connect_result.is_err()); | ||
if let Err(error) = connect_result { | ||
assert_eq!( | ||
error.downcast_ref::<Error>().unwrap(), | ||
&Error::InsufficientContractInfoError | ||
); | ||
} | ||
|
||
let mut c2 = ERC20ContractHandler { | ||
address: None, | ||
call_data: Some("0xabcd".to_string()), | ||
config_file_path: Some("/path/to/config".into()), | ||
}; | ||
let connect_result = c2.connect(); | ||
assert!(connect_result.is_err()); | ||
if let Err(error) = connect_result { | ||
assert_eq!( | ||
error.downcast_ref::<Error>().unwrap(), | ||
&Error::ContractSizeError(2), | ||
); | ||
} | ||
} |
Submodule ssvm-evmc
updated
from 9cf46a to cf84df