2021-10-21 16:51:01 +00:00
|
|
|
use std::fs;
|
2021-11-13 17:37:31 +00:00
|
|
|
use std::path::Path;
|
2021-10-21 16:51:01 +00:00
|
|
|
|
2022-01-30 16:18:05 +00:00
|
|
|
use web3::{
|
|
|
|
api::Web3,
|
|
|
|
contract::{Contract, Options},
|
|
|
|
transports::Http,
|
|
|
|
};
|
|
|
|
|
|
|
|
use crate::config::BlockchainConfig;
|
|
|
|
use super::api::connect;
|
|
|
|
use super::errors::EthereumError;
|
|
|
|
use super::utils::parse_address;
|
|
|
|
|
2022-01-26 16:59:27 +00:00
|
|
|
pub const ADAPTER: &str = "IAdapter";
|
|
|
|
pub const ERC721: &str = "IERC721Metadata";
|
2021-10-21 16:51:01 +00:00
|
|
|
|
|
|
|
#[derive(thiserror::Error, Debug)]
|
|
|
|
pub enum ArtifactError {
|
|
|
|
#[error("io error")]
|
|
|
|
IoError(#[from] std::io::Error),
|
|
|
|
|
|
|
|
#[error("json error")]
|
|
|
|
JsonError(#[from] serde_json::Error),
|
|
|
|
|
|
|
|
#[error("key error")]
|
|
|
|
KeyError,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn load_abi(
|
2021-11-13 17:37:31 +00:00
|
|
|
contract_dir: &Path,
|
2021-10-21 16:51:01 +00:00
|
|
|
contract_name: &str,
|
|
|
|
) -> Result<Vec<u8>, ArtifactError> {
|
|
|
|
let contract_artifact_path = contract_dir.join(format!("{}.json", contract_name));
|
|
|
|
let contract_artifact = fs::read_to_string(contract_artifact_path)?;
|
2022-01-26 16:59:27 +00:00
|
|
|
let contract_artifact_value: serde_json::Value =
|
|
|
|
serde_json::from_str(&contract_artifact)?;
|
2021-10-21 16:51:01 +00:00
|
|
|
let contract_abi = contract_artifact_value.get("abi")
|
|
|
|
.ok_or(ArtifactError::KeyError)?
|
|
|
|
.to_string().as_bytes().to_vec();
|
|
|
|
Ok(contract_abi)
|
|
|
|
}
|
2022-01-30 16:18:05 +00:00
|
|
|
|
|
|
|
pub struct ContractSet {
|
|
|
|
pub web3: Web3<Http>,
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub adapter: Contract<Http>,
|
|
|
|
|
|
|
|
pub collectible: Contract<Http>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_contracts(
|
|
|
|
config: &BlockchainConfig,
|
|
|
|
) -> Result<ContractSet, EthereumError> {
|
|
|
|
let web3 = connect(&config.api_url)?;
|
|
|
|
let adapter_abi = load_abi(&config.contract_dir, ADAPTER)?;
|
|
|
|
let adapter_address = parse_address(&config.contract_address)?;
|
|
|
|
let adapter = Contract::from_json(
|
|
|
|
web3.eth(),
|
|
|
|
adapter_address,
|
|
|
|
&adapter_abi,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
let collectible_address = adapter.query(
|
|
|
|
"collectible",
|
|
|
|
(), None, Options::default(), None,
|
|
|
|
).await?;
|
|
|
|
let collectibe_abi = load_abi(&config.contract_dir, ERC721)?;
|
|
|
|
let collectible = Contract::from_json(
|
|
|
|
web3.eth(),
|
|
|
|
collectible_address,
|
|
|
|
&collectibe_abi,
|
|
|
|
)?;
|
|
|
|
log::info!("collectible item contract address is {:?}", collectible.address());
|
|
|
|
let contract_set = ContractSet {
|
|
|
|
web3,
|
|
|
|
adapter,
|
|
|
|
collectible,
|
|
|
|
};
|
|
|
|
Ok(contract_set)
|
|
|
|
}
|