diff --git a/ethers-contract/tests/abigen.rs b/ethers-contract/tests/abigen.rs index 801df914..49eb6811 100644 --- a/ethers-contract/tests/abigen.rs +++ b/ethers-contract/tests/abigen.rs @@ -2,8 +2,10 @@ //! Test cases to validate the `abigen!` macro use ethers_contract::{abigen, AbiDecode, AbiEncode, EthEvent}; use ethers_core::abi::{Address, Tokenizable}; -use ethers_core::types::U256; +use ethers_core::types::{transaction::eip2718::TypedTransaction, Eip1559TransactionRequest, U256}; +use ethers_core::utils::Solc; use ethers_providers::Provider; +use std::convert::TryFrom; use std::sync::Arc; #[test] @@ -266,3 +268,76 @@ fn can_handle_overloaded_functions() { assert_eq!(contract_call, decoded_enum); assert_eq!(encoded_call, contract_call.encode().unwrap()); } + +#[tokio::test] +async fn can_handle_underscore_functions() { + abigen!( + SimpleStorage, + r#"[ + _hashPuzzle() (uint256) + ]"#; + + SimpleStorage2, + "ethers-contract/tests/solidity-contracts/simplestorage_abi.json", + ); + + // launcht the network & connect to it + let ganache = ethers_core::utils::Ganache::new().spawn(); + let from = ganache.addresses()[0].clone(); + let provider = Provider::try_from(ganache.endpoint()) + .unwrap() + .with_sender(from) + .interval(std::time::Duration::from_millis(10)); + let client = Arc::new(provider); + + let compiled = Solc::new("./tests/solidity-contracts/SimpleStorage.sol") + .build() + .unwrap(); + let compiled = compiled.get("SimpleStorage").unwrap(); + let factory = ethers_contract::ContractFactory::new( + compiled.abi.clone(), + compiled.bytecode.clone(), + client.clone(), + ); + let addr = factory + .deploy("hi".to_string()) + .unwrap() + .legacy() + .send() + .await + .unwrap() + .address(); + + // connect to the contract + let contract = SimpleStorage::new(addr, client.clone()); + let contract2 = SimpleStorage2::new(addr, client.clone()); + + let res = contract.hash_puzzle().call().await.unwrap(); + let res2 = contract2.hash_puzzle().call().await.unwrap(); + let res3 = contract + .method::<_, U256>("_hashPuzzle", ()) + .unwrap() + .call() + .await + .unwrap(); + let res4 = contract2 + .method::<_, U256>("_hashPuzzle", ()) + .unwrap() + .call() + .await + .unwrap(); + + // Manual call construction + use ethers_providers::Middleware; + // TODO: How do we handle underscores for calls here? + let data = simplestorage_mod::HashPuzzleCall.encode().unwrap(); + let tx = Eip1559TransactionRequest::new().data(data).to(addr); + let tx = TypedTransaction::Eip1559(tx); + let res5 = client.call(&tx, None).await.unwrap(); + let res5 = U256::from(res5.as_ref()); + assert_eq!(res, 100.into()); + assert_eq!(res, res2); + assert_eq!(res, res3); + assert_eq!(res, res4); + assert_eq!(res, res5); +} diff --git a/ethers-contract/tests/solidity-contracts/SimpleStorage.sol b/ethers-contract/tests/solidity-contracts/SimpleStorage.sol index 52f781cd..85f92db6 100644 --- a/ethers-contract/tests/solidity-contracts/SimpleStorage.sol +++ b/ethers-contract/tests/solidity-contracts/SimpleStorage.sol @@ -28,4 +28,8 @@ contract SimpleStorage { _otherValue = value2; lastSender = msg.sender; } + + function _hashPuzzle() public view returns (uint256) { + return 100; + } } diff --git a/ethers-contract/tests/solidity-contracts/simplestorage_abi.json b/ethers-contract/tests/solidity-contracts/simplestorage_abi.json new file mode 100644 index 00000000..6e5edf3f --- /dev/null +++ b/ethers-contract/tests/solidity-contracts/simplestorage_abi.json @@ -0,0 +1,77 @@ +[ + { + "inputs": [{ "internalType": "string", "name": "value", "type": "string" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "author", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oldAuthor", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "oldValue", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "newValue", + "type": "string" + } + ], + "name": "ValueChanged", + "type": "event" + }, + { + "inputs": [], + "name": "_hashPuzzle", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValue", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastSender", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "string", "name": "value", "type": "string" }], + "name": "setValue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "value", "type": "string" }, + { "internalType": "string", "name": "value2", "type": "string" } + ], + "name": "setValues", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] +