diff --git a/lib/Cargo.lock b/lib/Cargo.lock index b29ffffde6..88daa544de 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -84,6 +84,7 @@ name = "ain-contracts" version = "0.1.0" dependencies = [ "anyhow", + "ethabi", "ethereum", "ethereum-types", "ethers", diff --git a/lib/ain-contracts/Cargo.toml b/lib/ain-contracts/Cargo.toml index bbfc25c5d4..47e9064d1a 100644 --- a/lib/ain-contracts/Cargo.toml +++ b/lib/ain-contracts/Cargo.toml @@ -14,6 +14,7 @@ hex.workspace = true sha3.workspace = true sp-core.workspace = true lazy_static.workspace = true +ethabi.workspace = true [build-dependencies] ethers.workspace = true diff --git a/lib/ain-contracts/src/lib.rs b/lib/ain-contracts/src/lib.rs index 6e5e6ec6c0..45242deaf7 100644 --- a/lib/ain-contracts/src/lib.rs +++ b/lib/ain-contracts/src/lib.rs @@ -39,6 +39,30 @@ fn get_bytecode(input: &str) -> Result> { hex::decode(&bytecode_raw[2..]).map_err(|e| format_err!(e.to_string())) } +pub fn get_dst20_deploy_input(init_bytecode: Vec, name: &str, symbol: &str) -> Result> { + let name = ethabi::Token::String(name.to_string()); + let symbol = ethabi::Token::String(symbol.to_string()); + + let constructor = ethabi::Constructor { + inputs: vec![ + ethabi::Param { + name: String::from("name"), + kind: ethabi::ParamType::String, + internal_type: None, + }, + ethabi::Param { + name: String::from("symbol"), + kind: ethabi::ParamType::String, + internal_type: None, + }, + ], + }; + + constructor + .encode_input(init_bytecode, &[name, symbol]) + .map_err(|e| format_err!(e)) +} + pub fn dst20_address_from_token_id(token_id: u64) -> Result { let number_str = format!("{:x}", token_id); let padded_number_str = format!("{number_str:0>38}"); @@ -112,9 +136,9 @@ lazy_static::lazy_static! { let bytecode = solc_artifact_bytecode_str!( "dst20", "deployed_bytecode.json" ); - let input = get_bytecode(include_str!( - "../dst20/input.json" - )).unwrap(); + let input = solc_artifact_bytecode_str!( + "dst20", "bytecode.json" + ); Contract { codehash: Blake2Hasher::hash(&bytecode), diff --git a/lib/ain-evm/src/contract.rs b/lib/ain-evm/src/contract.rs index fc5ea91b16..8e42327c49 100644 --- a/lib/ain-evm/src/contract.rs +++ b/lib/ain-evm/src/contract.rs @@ -100,8 +100,8 @@ pub fn transfer_domain_contract() -> Result { pub fn dst20_contract( backend: &EVMBackend, address: H160, - name: String, - symbol: String, + name: &str, + symbol: &str, ) -> Result { match backend.get_account(&address) { None => {} @@ -117,14 +117,8 @@ pub fn dst20_contract( runtime_bytecode, .. } = get_dst20_contract(); let storage = vec![ - ( - H256::from_low_u64_be(3), - get_abi_encoded_string(name.as_str()), - ), - ( - H256::from_low_u64_be(4), - get_abi_encoded_string(symbol.as_str()), - ), + (H256::from_low_u64_be(3), get_abi_encoded_string(name)), + (H256::from_low_u64_be(4), get_abi_encoded_string(symbol)), ]; Ok(DeployContractInfo { diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index a642c2f126..60e042c32c 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -1,7 +1,8 @@ use std::{path::PathBuf, sync::Arc}; use ain_contracts::{ - get_dst20_contract, get_reserved_contract, get_transferdomain_contract, Contract, FixedContract, + get_dst20_contract, get_dst20_deploy_input, get_reserved_contract, get_transferdomain_contract, + Contract, FixedContract, }; use anyhow::format_err; use ethereum::{ @@ -426,12 +427,13 @@ impl EVMServices { address, bytecode, storage, - } = dst20_contract(executor.backend, address, name, symbol)?; + } = dst20_contract(executor.backend, address, &name, &symbol)?; if let Err(e) = executor.deploy_contract(address, bytecode.clone(), storage) { debug!("[construct_block] EvmOut failed with {e}"); } - let (tx, receipt) = dst20_deploy_contract_tx(token_id, &base_fee)?; + let (tx, receipt) = + dst20_deploy_contract_tx(token_id, &base_fee, &name, &symbol)?; (tx, Vec::new(), (receipt, Some(address))) } @@ -659,14 +661,28 @@ impl EVMServices { } } -fn dst20_deploy_contract_tx(token_id: u64, base_fee: &U256) -> Result<(Box, ReceiptV3)> { +fn dst20_deploy_contract_tx( + token_id: u64, + base_fee: &U256, + name: &str, + symbol: &str, +) -> Result<(Box, ReceiptV3)> { + debug!("DST20 Deploy Input"); + debug!( + "{:#?}", + hex::encode( + get_dst20_deploy_input(get_dst20_contract().init_bytecode, name, symbol) + .map_err(|e| format_err!(e))? + ) + ); let tx = TransactionV2::Legacy(LegacyTransaction { nonce: U256::from(token_id), gas_price: *base_fee, gas_limit: U256::from(u64::MAX), action: TransactionAction::Create, value: U256::zero(), - input: get_dst20_contract().init_bytecode, + input: get_dst20_deploy_input(get_dst20_contract().init_bytecode, name, symbol) + .map_err(|e| format_err!(e))?, signature: TransactionSignature::new(27, LOWER_H256, LOWER_H256) .ok_or(format_err!("Invalid transaction signature format"))?, })