Skip to content

Commit 8ac1c9b

Browse files
authored
feat: add a possibility to deploy ERC-20 tokens (#105)
1 parent c6200c7 commit 8ac1c9b

File tree

3 files changed

+98
-35
lines changed

3 files changed

+98
-35
lines changed

cli/src/cli/simple/command/mod.rs

Lines changed: 78 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ use aurora_engine_types::parameters::connector::{
99
PausedMask, SetErc20MetadataArgs, SetEthConnectorContractAccountArgs, WithdrawSerializeType,
1010
};
1111
use aurora_engine_types::parameters::engine::{
12-
CallArgs, FunctionCallArgsV2, GetStorageAtArgs, NewCallArgs, NewCallArgsV2,
13-
PausePrecompilesCallArgs, RelayerKeyArgs, RelayerKeyManagerArgs, SetOwnerArgs,
12+
CallArgs, DeployErc20TokenArgs, FunctionCallArgsV2, GetStorageAtArgs, NewCallArgs,
13+
NewCallArgsV2, PausePrecompilesCallArgs, RelayerKeyArgs, RelayerKeyManagerArgs, SetOwnerArgs,
1414
SetUpgradeDelayBlocksArgs, SubmitResult, TransactionStatus,
1515
};
1616
use aurora_engine_types::parameters::xcc::FundXccArgs;
1717
use aurora_engine_types::public_key::{KeyType, PublicKey};
18+
use aurora_engine_types::types::Address;
1819
use aurora_engine_types::{H256, U256, types::Wei};
1920
use clap::ValueEnum;
2021
use near_primitives::hash::CryptoHash;
@@ -126,32 +127,19 @@ pub async fn init(
126127
upgrade_delay_blocks: Option<u64>,
127128
) -> anyhow::Result<()> {
128129
let owner_id = to_account_id(owner_id, &context)?;
129-
130130
let aurora_init_args = borsh::to_vec(&NewCallArgs::V2(NewCallArgsV2 {
131131
chain_id: H256::from_low_u64_be(chain_id).into(),
132132
owner_id,
133133
upgrade_delay_blocks: upgrade_delay_blocks.unwrap_or_default(),
134134
}))?;
135135

136-
match context
137-
.client
138-
.near()
139-
.contract_call("new", aurora_init_args)
140-
.await?
141-
.status
142-
{
143-
FinalExecutionStatus::Failure(e) => {
144-
anyhow::bail!("Error while initializing Aurora EVM: {e}")
145-
}
146-
FinalExecutionStatus::Started | FinalExecutionStatus::NotStarted => {
147-
anyhow::bail!("Error while initializing Aurora EVM: Bad status of the transaction")
148-
}
149-
FinalExecutionStatus::SuccessValue(_) => {}
150-
}
151-
152-
println!("Aurora EVM has been initialized successfully");
153-
154-
Ok(())
136+
contract_call!(
137+
"new",
138+
"Aurora EVM has been initialized successfully",
139+
"Error while initializing Aurora EVM"
140+
)
141+
.proceed(context, aurora_init_args)
142+
.await
155143
}
156144

157145
/// Deploy EVM byte code.
@@ -677,7 +665,7 @@ pub async fn set_key_manager(
677665
.await
678666
}
679667

680-
/// Add relayer public key.
668+
/// Add relayer's public key.
681669
pub async fn add_relayer_key(
682670
context: Context,
683671
public_key: PublicKey,
@@ -688,7 +676,7 @@ pub async fn add_relayer_key(
688676
contract_call!(
689677
"add_relayer_key",
690678
"The public key: {public_key} has been added successfully",
691-
"Error while adding public key"
679+
"Error while adding a public key"
692680
)
693681
.proceed_with_deposit(context, args, allowance)
694682
.await
@@ -701,7 +689,7 @@ pub async fn remove_relayer_key(context: Context, public_key: PublicKey) -> anyh
701689
contract_call!(
702690
"remove_relayer_key",
703691
"The public key: {public_key} has been removed successfully",
704-
"Error while removing public key"
692+
"Error while removing a public key"
705693
)
706694
.proceed(context, args)
707695
.await
@@ -728,7 +716,7 @@ pub async fn get_erc20_from_nep141(context: Context, account_id: String) -> anyh
728716
get_value::<HexString>(context, "get_erc20_from_nep141", Some(args)).await
729717
}
730718

731-
/// Get NEP-141 account id from address of ERC-20.
719+
/// Get NEP-141 account id from the address of ERC-20.
732720
pub async fn get_nep141_from_erc20(context: Context, address: String) -> anyhow::Result<()> {
733721
let args = hex_to_address(&address)?.as_bytes().to_vec();
734722
get_value::<AccountId>(context, "get_nep141_from_erc20", Some(args)).await
@@ -778,6 +766,28 @@ pub async fn set_erc20_metadata(
778766
.await
779767
}
780768

769+
/// Deploy a new ERC-20 contract.
770+
pub async fn deploy_erc20_token(
771+
context: Context,
772+
nep141: String,
773+
with_metadata: bool,
774+
) -> anyhow::Result<()> {
775+
let nep141_account_id = nep141.parse().map_err(|e| anyhow::anyhow!("{e}"))?;
776+
let args = borsh::to_vec(&if with_metadata {
777+
DeployErc20TokenArgs::WithMetadata(nep141_account_id)
778+
} else {
779+
DeployErc20TokenArgs::Legacy(nep141_account_id)
780+
})?;
781+
782+
contract_call!(
783+
"deploy_erc20_token",
784+
"ERC-20 token has been deployed successfully",
785+
"Error while deploying ERC-20 token"
786+
)
787+
.proceed_with_output(context, args, erc20_output)
788+
.await
789+
}
790+
781791
/// Mirror ERC-20 contract.
782792
pub async fn mirror_erc20_token(
783793
context: Context,
@@ -794,7 +804,7 @@ pub async fn mirror_erc20_token(
794804
"ERC-20 token has been mirrored successfully",
795805
"Error while mirroring ERC-20 token"
796806
)
797-
.proceed(context, args)
807+
.proceed_with_output(context, args, erc20_output)
798808
.await
799809
}
800810

@@ -1015,39 +1025,66 @@ impl ContractCall<'_> {
10151025
self.proceed_with_deposit(context, args, 0.0).await
10161026
}
10171027

1028+
async fn proceed_with_output(
1029+
&self,
1030+
context: Context,
1031+
args: Vec<u8>,
1032+
output: fn(&[u8]) -> String,
1033+
) -> anyhow::Result<()> {
1034+
self.proceed_with_deposit_and_output(context, args, 0.0, Some(output))
1035+
.await
1036+
}
1037+
10181038
async fn proceed_with_deposit(
10191039
&self,
10201040
context: Context,
10211041
args: Vec<u8>,
10221042
deposit: f64,
1043+
) -> anyhow::Result<()> {
1044+
self.proceed_with_deposit_and_output(context, args, deposit, None)
1045+
.await
1046+
}
1047+
1048+
async fn proceed_with_deposit_and_output(
1049+
&self,
1050+
context: Context,
1051+
args: Vec<u8>,
1052+
deposit: f64,
1053+
output: Option<fn(&[u8]) -> String>,
10231054
) -> anyhow::Result<()> {
10241055
let yocto = near_to_yocto(deposit);
1025-
let result = context
1056+
let outcome = context
10261057
.client
10271058
.near()
10281059
.contract_call_with_deposit(self.method, args, yocto)
10291060
.await?;
10301061

1031-
match result.status {
1062+
match outcome.status {
10321063
FinalExecutionStatus::NotStarted | FinalExecutionStatus::Started => {
10331064
anyhow::bail!("{}: Bad transaction status", self.error_message)
10341065
}
10351066
FinalExecutionStatus::Failure(e) => {
10361067
anyhow::bail!("{}: {e}", self.error_message)
10371068
}
1038-
FinalExecutionStatus::SuccessValue(output) => match context.output_format {
1069+
FinalExecutionStatus::SuccessValue(result) => match context.output_format {
10391070
// TODO: The output could be serialized with JSON or Borsh.
10401071
// TODO: In the case of Borsh we should provide a type for deserializing the output in the corresponding object.
1041-
OutputFormat::Plain => match to_string_pretty(&output) {
1042-
Ok(msg) if !output.is_empty() => println!("{}\n{msg}", self.success_message),
1072+
OutputFormat::Plain => match to_string_pretty(&result) {
1073+
Ok(msg) if !result.is_empty() => {
1074+
if let Some(output) = output {
1075+
println!("{}, {}", self.success_message, output(&result));
1076+
} else {
1077+
println!("{}: {msg}", self.success_message);
1078+
}
1079+
}
10431080
Ok(_) | Err(_) => println!("{}", self.success_message),
10441081
},
10451082
OutputFormat::Json => {
1046-
let formatted = to_string_pretty(&result.transaction_outcome)?;
1083+
let formatted = to_string_pretty(&outcome.transaction_outcome)?;
10471084
println!("{formatted}");
10481085
}
10491086
OutputFormat::Toml => {
1050-
let formatted = toml::to_string_pretty(&result.transaction_outcome)?;
1087+
let formatted = toml::to_string_pretty(&outcome.transaction_outcome)?;
10511088
println!("{formatted}");
10521089
}
10531090
},
@@ -1086,3 +1123,10 @@ pub async fn add_relayer(
10861123
);
10871124
Ok(())
10881125
}
1126+
1127+
fn erc20_output(bytes: &[u8]) -> String {
1128+
let raw_bytes: Vec<u8> = BorshDeserialize::try_from_slice(bytes).unwrap();
1129+
let erc20_address = Address::try_from_slice(&raw_bytes).unwrap();
1130+
1131+
format!("token address: 0x{}", erc20_address.encode())
1132+
}

cli/src/cli/simple/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub enum Command {
7272
/// Owner of the Aurora EVM
7373
#[arg(long)]
7474
owner_id: Option<String>,
75-
/// How many blocks after staging upgrade can deploy it
75+
/// Delay in blocks between staging and updating the contract
7676
#[arg(long)]
7777
upgrade_delay_blocks: Option<u64>,
7878
},
@@ -346,6 +346,15 @@ pub enum Command {
346346
#[arg(long)]
347347
decimals: u8,
348348
},
349+
/// Deploy ERC-20 token
350+
DeployErc20Token {
351+
/// Account ID of corresponding NEP-141
352+
#[arg(long)]
353+
nep141: String,
354+
/// With ERC-20 metadata received from the corresponding NEP-141
355+
#[arg(long, default_value_t = false)]
356+
with_metadata: bool,
357+
},
349358
/// Mirror ERC-20 token
350359
MirrorErc20Token {
351360
/// Account of contract where ERC-20 has been deployed
@@ -620,6 +629,12 @@ pub async fn run(args: Cli) -> anyhow::Result<()> {
620629
} => {
621630
command::set_erc20_metadata(context, erc20_id, name, symbol, decimals).await?;
622631
}
632+
Command::DeployErc20Token {
633+
nep141,
634+
with_metadata,
635+
} => {
636+
command::deploy_erc20_token(context, nep141, with_metadata).await?;
637+
}
623638
Command::MirrorErc20Token {
624639
contract_id,
625640
nep141,

scripts/simple.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ echo "$version"
123123
aurora-cli --engine $ENGINE_ACCOUNT set-eth-connector-contract-account --account-id eth.connector.near || error_exit
124124
wait_for_block
125125

126+
# Deploy ERC-20 token contract
127+
aurora-cli --engine $ENGINE_ACCOUNT deploy-erc20-token --nep141 eth.token.near || error_exit
128+
wait_for_block
129+
126130
# Create account id for key manager
127131
aurora-cli create-account --account $MANAGER_ACCOUNT --balance 10 > $MANAGER_KEY_PATH || error_exit
128132
wait_for_block

0 commit comments

Comments
 (0)