Closed toriqahmads closed 2 years ago
From the code, I think bsc can support this. As you rewrite the code, so the method in the data field may have changed, I will suggest you to rewrite code first, and then send transaction after.
We have responded to the question and will proceed to close the case as we didn't get any additional question after 3days. Please proceed to join our Discord channel for more discussion at https://discord.com/invite/buildnbuild
Just to add more info, I have the same problem and this is what I do from ether.js:
import { hexValue, parseEther } from "ethers/lib/utils";
import { ethers } from "hardhat";
const PLACEHOLDER_ADDRESS = "0xae1A331eaAF7b9a44005035588C2542B0Cfe9FCf";
async function main() {
const provider = new ethers.providers.JsonRpcProvider(
"http://localhost:10000"
);
const MyContract = await ethers.getContractFactory("MyContract");
const data = MyContract.interface.encodeFunctionData("tryCall");
const params = [
{
from: "0xCC4B9142788B8D41FF908EE19940cbc3fD9fDfC4", // Source wallet
to: PLACEHOLDER_ADDRESS, // Fake contract address
value: hexValue(parseEther("0.01")),
data,
},
"latest",
{
[PLACEHOLDER_ADDRESS]: {
balance: hexValue(parseEther("1.0")),
code: MyContract.bytecode,
},
},
];
const result = await provider.send("eth_call", params);
console.log(result);
console.log(MyContract.interface.decodeFunctionResult("tryCall", result));
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
so the data should be correct. The function code is simply
function tryCall() public view returns (uint256) {
uint256 x = 1;
return x; // x has value 2
}
logs don't help either:
Served eth_call conn=127.0.0.1:39912 reqid=43 t=1.759014ms err="execution reverted"
Update: as pointed out in discord I've also tried without setting a value and with a 0 value, same error or CALL_EXCEPTION
Just to give a full example, create a new hardhat project, have a node running at localhost:1000
this is the contract
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
contract TestContract {
function tryCall() public pure returns (uint256 value) {
uint256 x = 1;
return x;
}
}
this is the script code
import { ethers } from "hardhat";
const PLACEHOLDER_ADDRESS = "0xae1A331eaAF7b9a44005035588C2542B0Cfe9FCf";
async function main() {
// We get the contract to deploy
const provider = new ethers.providers.JsonRpcProvider(
"http://localhost:10000"
);
const TestContract = await ethers.getContractFactory("TestContract");
const data = TestContract.interface.encodeFunctionData("tryCall");
const params = [
{
to: PLACEHOLDER_ADDRESS,
data,
},
"latest",
{
[PLACEHOLDER_ADDRESS]: {
code: TestContract.bytecode,
},
},
];
console.log(params);
const result = await provider.send("eth_call", params);
console.log(result);
console.log(TestContract.interface.decodeFunctionResult("tryCall", result));
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
this is the output:
[
{
to: '0xae1A331eaAF7b9a44005035588C2542B0Cfe9FCf',
data: '0x118dfb0e'
},
'latest',
{
'0xae1A331eaAF7b9a44005035588C2542B0Cfe9FCf': {
code: '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063118dfb0e14602d575b600080fd5b60336047565b604051603e91906062565b60405180910390f35b600080600190508091505090565b605c81607b565b82525050565b6000602082019050607560008301846055565b92915050565b600081905091905056fea26469706673582212206697fcd9141a9315a2c909d6245d783781cf57770fdb8fdd356e879ad0a0980b64736f6c63430008040033'
}
}
]
0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063118dfb0e14602d575b600080fd5b60336047565b604051603e91906062565b60405180910390f35b600080600190508091505090565b605c81607b565b82525050565b6000602082019050607560008301846055565b92915050565b600081905091905056fea26469706673582212206697fcd9141a9315a2c909d6245d783781cf57770fdb8fdd356e879ad0a0980b64736f6c63430008040033
Error: call revert exception (method="tryCall()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.5.0)
at Logger.makeError (/home/alex/Projects/personal/node_modules/@ethersproject/logger/src.ts/index.ts:225:28)
at Logger.throwError (/home/alex/Projects/personal/node_modules/@ethersproject/logger/src.ts/index.ts:237:20)
at Interface.decodeFunctionResult (/home/alex/Projects/personal/node_modules/@ethersproject/abi/src.ts/interface.ts:425:23)
at main (/home/alex/Projects/personal/scripts/test.ts:37:38)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: null,
code: 'CALL_EXCEPTION',
method: 'tryCall()',
errorArgs: null,
errorName: null,
errorSignature: null
}
it's interesting how the returned value seems to be very close to the contract bytecode
Update: that's the init bytecode, after using the runtime bytecode it seems to work, I'll update this in a few
Update: it seems to work but as soon there's an error somewhere I get execution reverted and no error other than that :(
@alex88 how'd you go about fixing this? I'm having the same trouble where it looks very similar to the contract bytecode.
@alex88 how'd you go about fixing this? I'm having the same trouble where it looks very similar to the contract bytecode.
you should use the runtime bytecode, I'm not sure how to take it from ethers.js but it's definitely in the json files
@alex88 Did you find a solution? Below my example. May you help me? Cheers
contract
interface IERC20 {
function balanceOf(address) external view returns (uint);
function approve(address, uint) external returns (bool);
}
interface IUniswapRouter {
function WETH() external view returns(address);
function swapExactETHForTokens(uint, address[] calldata, address, uint) external payable returns (uint[] memory);
function swapExactTokensForETH(uint, uint, address[] calldata, address, uint) external returns (uint[] memory);
}
contract Audit {
address constant public ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
uint256 constant public MAX_BUY_TAX = 10;
uint256 constant public MAX_SELL_TAX = 10;
function isHoneypot(address token) external returns(bool) {
uint256 amount = address(this).balance;
address[] memory path = new address[](2);
path[0] = IUniswapRouter(ROUTER_ADDRESS).WETH();
path[1] = token;
// save token balance before swap to ignore any scrap balance
uint256 preBalance0 = IERC20(path[1]).balanceOf(address(this));
uint256[] memory amounts0 = IUniswapRouter(ROUTER_ADDRESS).swapExactETHForTokens{value: amount}(0, path, address(this), block.timestamp * 15);
uint256 postBalance0 = IERC20(path[1]).balanceOf(address(this)) - preBalance0;
if ((amounts0[1] - postBalance0) > (amounts0[1] * MAX_BUY_TAX / 100)) {
return true;
}
path[1] = path[0];
path[0] = token;
IERC20(path[0]).approve(router, postBalance0);
uint256[] memory amounts1 = IUniswapRouter(ROUTER_ADDRESS).swapExactTokensForETH(postBalance0, 0, path, address(this), block.timestamp * 15);
uint256 balance1 = address(this).balance;
if ((amounts1[1] - balance1) > (amounts1[1] * MAX_SELL_TAX / 100)) {
return true;
}
return false;
}
}
script
const provider = new ethers.providers.JsonRpcProvider("URL");
const AuditContract = await ethers.getContractFactory("Audit");
const data = AuditContract.interface.encodeFunctionData("isHoneypot", [token]);
const result = await provider.send("eth_call", [
{
data: data,
from: '0x0000000000000000000000000000000000000124',
to: '0x0000000000000000000000000000000000000125',
gas: 1000000
},
'latest',
{
'0x0000000000000000000000000000000000000124': {
balance: ethers.parseEther('1').toHexString()
},
'0x0000000000000000000000000000000000000125': {
code: AuditContract.bytecode,
balance: ethers.parseEther('1').toHexString()
},
}
]);
const value = AuditContract.interface.decodeFunctionData("isHoneypot", result);
console.log(value);
@IronSight87 AuditContract.bytecode
is probably the deploy bytecode not the runtime one, check for that
@IronSight87
AuditContract.bytecode
is probably the deploy bytecode not the runtime one, check for that
Thanks mate. Fixed it!
Hi, I want performing an eth_call with overriding state such as balance, code, nonce, state and stateDiff. I was called with overriding balance of some account and it works fine. But, if I override the code of some account/contract it always return an error execution reverted. Does BSC doesn't support this perform?
Here is my testing parameter
Endpoint:
POST: https://bsc-dataseed1.ninicoin.io/
Body:
Response: