parent
ad68337113
commit
7da5b64cfd
|
@ -2,7 +2,7 @@ use std::fmt;
|
|||
|
||||
use crate::types::U256;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Chain {
|
||||
Mainnet,
|
||||
Ropsten,
|
||||
|
@ -15,6 +15,9 @@ pub enum Chain {
|
|||
Avalanche,
|
||||
AvalancheFuji,
|
||||
Sepolia,
|
||||
Moonbeam,
|
||||
MoonbeamDev,
|
||||
Moonriver,
|
||||
}
|
||||
|
||||
impl fmt::Display for Chain {
|
||||
|
@ -37,6 +40,9 @@ impl From<Chain> for u32 {
|
|||
Chain::Avalanche => 43114,
|
||||
Chain::AvalancheFuji => 43113,
|
||||
Chain::Sepolia => 11155111,
|
||||
Chain::Moonbeam => 1287,
|
||||
Chain::MoonbeamDev => 1281,
|
||||
Chain::Moonriver => 1285,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,3 +52,9 @@ impl From<Chain> for U256 {
|
|||
u32::from(chain).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Chain> for u64 {
|
||||
fn from(chain: Chain) -> Self {
|
||||
u32::from(chain).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@ mod geth;
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use geth::{Geth, GethInstance};
|
||||
|
||||
/// Moonbeam utils
|
||||
pub mod moonbeam;
|
||||
|
||||
mod hash;
|
||||
pub use hash::{hash_message, id, keccak256, serialize};
|
||||
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
//! Moonbeam utilities
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use k256::SecretKey;
|
||||
|
||||
/// Returns the private developer keys https://docs.moonbeam.network/snippets/code/setting-up-node/dev-accounts/
|
||||
pub fn dev_keys() -> Vec<SecretKey> {
|
||||
MoonbeamDev::default().into_keys().collect()
|
||||
}
|
||||
|
||||
/// Holds private developer keys with their names
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MoonbeamDev {
|
||||
keys: BTreeMap<&'static str, SecretKey>,
|
||||
}
|
||||
|
||||
impl MoonbeamDev {
|
||||
pub fn keys(&self) -> impl Iterator<Item = &SecretKey> {
|
||||
self.keys.values()
|
||||
}
|
||||
|
||||
pub fn into_keys(self) -> impl Iterator<Item = SecretKey> {
|
||||
self.keys.into_values()
|
||||
}
|
||||
|
||||
/// Get a key by then, like `Alith`
|
||||
pub fn get(&self, name: impl AsRef<str>) -> Option<&SecretKey> {
|
||||
self.keys.get(name.as_ref())
|
||||
}
|
||||
|
||||
pub fn alith(&self) -> &SecretKey {
|
||||
self.get("Alith").unwrap()
|
||||
}
|
||||
|
||||
pub fn baltathar(&self) -> &SecretKey {
|
||||
self.get("Baltathar").unwrap()
|
||||
}
|
||||
|
||||
pub fn charleth(&self) -> &SecretKey {
|
||||
self.get("Charleth").unwrap()
|
||||
}
|
||||
|
||||
pub fn ethan(&self) -> &SecretKey {
|
||||
self.get("Ethan").unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MoonbeamDev {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
keys: BTreeMap::from([
|
||||
(
|
||||
"Alith",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Baltathar",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"8075991ce870b93a8870eca0c0f91913d12f47948ca0fd25b49c6fa7cdbeee8b",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Charleth",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"0b6e18cafb6ed99687ec547bd28139cafdd2bffe70e6b688025de6b445aa5c5b",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Dorothy",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"39539ab1876910bbf3a223d84a29e28f1cb4e2e456503e7e91ed39b2e7223d68",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Faith",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"b9d2ea9a615f3165812e8d44de0d24da9bbd164b65c4f0573e1ce2c8dbd9c8df",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Goliath",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"96b8a38e12e1a31dee1eab2fffdf9d9990045f5b37e44d8cc27766ef294acf18",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Heath",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"0d6dcaaef49272a5411896be8ad16c01c35d6f8c18873387b71fbc734759b0ab",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Ida",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"4c42532034540267bf568198ccec4cb822a025da542861fcb146a5fab6433ff8",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
(
|
||||
"Judith",
|
||||
SecretKey::from_bytes(
|
||||
hex::decode(
|
||||
"94c49300a58d576011096bcb006aa06f5a91b34b4383891e8029c21dc39fbb8b",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -78,7 +78,11 @@ impl Client {
|
|||
Chain::Mainnet | Chain::Ropsten | Chain::Kovan | Chain::Rinkeby | Chain::Goerli => {
|
||||
std::env::var("ETHERSCAN_API_KEY")?
|
||||
}
|
||||
|
||||
Chain::XDai | Chain::Sepolia => String::default(),
|
||||
Chain::Moonbeam | Chain::MoonbeamDev | Chain::Moonriver => {
|
||||
std::env::var("MOONSCAN_API_KEY")?
|
||||
}
|
||||
};
|
||||
Self::new(chain, api_key)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
use anyhow::Result;
|
||||
use ethers::prelude::*;
|
||||
use std::{convert::TryFrom, path::Path, sync::Arc, time::Duration};
|
||||
|
||||
abigen!(
|
||||
SimpleContract,
|
||||
"./examples/contract_abi.json",
|
||||
event_derives(serde::Deserialize, serde::Serialize)
|
||||
);
|
||||
|
||||
const MOONBEAM_DEV_ENDPOINT: &str = "http://localhost:9933";
|
||||
|
||||
/// This requires a running moonbeam dev instance on `localhost:9933`
|
||||
/// See `https://docs.moonbeam.network/builders/get-started/moonbeam-dev/` for reference
|
||||
///
|
||||
/// This has been tested against:
|
||||
///
|
||||
/// ```bash
|
||||
/// docker run --rm --name moonbeam_development -p 9944:9944 -p 9933:9933 purestake/moonbeam:v0.14.2 --dev --ws-external --rpc-external
|
||||
/// ```
|
||||
///
|
||||
/// Also requires the `legacy` feature to send Legacy transaction instead of an EIP-1559
|
||||
#[tokio::main]
|
||||
#[cfg(feature = "legacy")]
|
||||
async fn main() -> Result<()> {
|
||||
// set the path to the contract, `CARGO_MANIFEST_DIR` points to the directory containing the
|
||||
// manifest of `ethers`. which will be `../` relative to this file
|
||||
let source = Path::new(&env!("CARGO_MANIFEST_DIR")).join("examples/contract.sol");
|
||||
let compiled = Solc::default().compile_source(source).expect("Could not compile contracts");
|
||||
let (abi, bytecode, _runtime_bytecode) =
|
||||
compiled.find("SimpleStorage").expect("could not find contract").into_parts_or_default();
|
||||
|
||||
// 1. get a moonbeam dev key
|
||||
let key = ethers::core::utils::moonbeam::dev_keys()[0].clone();
|
||||
|
||||
// 2. instantiate our wallet with chain id
|
||||
let wallet: LocalWallet = LocalWallet::from(key).with_chain_id(Chain::MoonbeamDev);
|
||||
|
||||
// 3. connect to the network
|
||||
let provider =
|
||||
Provider::<Http>::try_from(MOONBEAM_DEV_ENDPOINT)?.interval(Duration::from_millis(10u64));
|
||||
|
||||
// 4. instantiate the client with the wallet
|
||||
let client = SignerMiddleware::new(provider, wallet);
|
||||
let client = Arc::new(client);
|
||||
|
||||
// 5. create a factory which will be used to deploy instances of the contract
|
||||
let factory = ContractFactory::new(abi, bytecode, client.clone());
|
||||
|
||||
// 6. deploy it with the constructor arguments, note the `legacy` call
|
||||
let contract = factory.deploy("initial value".to_string())?.legacy().send().await?;
|
||||
|
||||
// 7. get the contract's address
|
||||
let addr = contract.address();
|
||||
|
||||
// 8. instantiate the contract
|
||||
let contract = SimpleContract::new(addr, client.clone());
|
||||
|
||||
// 9. call the `setValue` method
|
||||
// (first `await` returns a PendingTransaction, second one waits for it to be mined)
|
||||
let _receipt = contract.set_value("hi".to_owned()).legacy().send().await?.await?;
|
||||
|
||||
// 10. get all events
|
||||
let logs = contract.value_changed_filter().from_block(0u64).query().await?;
|
||||
|
||||
// 11. get the new value
|
||||
let value = contract.get_value().call().await?;
|
||||
|
||||
println!("Value: {}. Logs: {}", value, serde_json::to_string(&logs)?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "legacy"))]
|
||||
fn main() {}
|
Loading…
Reference in New Issue