webjs execution reverting when calling deployed contract: var err = new Error('Returned error: ' + message) - solidity

I'm running the following javascript file and using web3js to call a smart contract (0xF3885ca057a42B10b6cb432B816FE11426a2E369) on Goerli:
const Web3 = require("web3");
// Loading the contract ABI
// (the results of a previous compilation step)
const fs = require("fs");
const { abi } = JSON.parse(fs.readFileSync("EtherSplitter.json"));
async function main() {
// Configuring the connection to an Ethereum node
const network = process.env.ETHEREUM_NETWORK;
const web3 = new Web3(
new Web3.providers.HttpProvider(
`https://${network}.infura.io/v3/${process.env.INFURA_PROJECT_ID}`
)
);
// Creating a signing account from a private key
const signer = web3.eth.accounts.privateKeyToAccount(
process.env.SIGNER_PRIVATE_KEY
);
web3.eth.accounts.wallet.add(signer);
// Creating a Contract instance
const contract = new web3.eth.Contract(
abi,
// Replace this with the address of your deployed contract
process.env.ETHERSPLITTER_CONTRACT
);
// Issuing a transaction that calls the splitEther method
const tx = contract.methods.splitEther(["0xdF8b511C3682b093736318A67Fcc2FEC6772D1a6","0x1E2eBeBB3348B1FeFC29239c20Df1c78668180Cc"]);
const receipt = await tx
.send({
from: signer.address,
value: 1e15, // IS THIS CORRECT? IF NOT, HOW DO I SPECIFY VALUE FOR SEND
gas: await tx.estimateGas(),
})
.once("transactionHash", (txhash) => {
console.log(`Mining transaction ...`);
console.log(`https://${network}.etherscan.io/tx/${txhash}`);
});
// The transaction is now on chain!
console.log(`Mined in block ${receipt.blockNumber}`);
}
require("dotenv").config();
main();
The smart contract is:
contract EtherSplitter {
function splitEther(address payable[] memory recipients) public payable {
uint fee = 10;
recipients[0].transfer(msg.value * fee / 100);
recipients[1].transfer(msg.value * (100 - fee) / 100);
}
receive() external payable {
}
}
Execution is reverting with the following error:
users/myusername/demo-eth-tx/node_modules/web3-core-helpers/lib/errors.js:28
var err = new Error('Returned error: ' + message);
I think I'm using send incorrectly, and incorrectly specifying the send value. How do I fix that?

Based on your code, seems like you mixed up some ether.js into your web3.js code coz in web3.js there when executing contract because in web3.js, function parameters doesn't need to be in an array like in ether.js
Try this
const tx = contract.methods.splitEther("0xdF8b511C3682b093736318A67Fcc2FEC6772D1a6","0x1E2eBeBB3348B1FeFC29239c20Df1c78668180Cc");

Related

CONTRACT_REVERT_EXECUTED Hedera Smart Contract

CONTRACT_REVERT_EXECUTED
Not sure what I'm doing wrong but I'm trying to call a function and it takes in one parameter and I made sure it was correct but it still reverts. This is hedera-hashgraph using HederaTokenService.
Smart Contract:
pragma solidity ^0.8.11;
import "./hip-206/HederaTokenService.sol";
import "./hip-206/HederaResponseCodes.sol";
contract Minting is HederaTokenService {
address tokenAddress;
bytes metadata;
string baseURI = "abc";
uint64 mintPrice;
function mintNonFungibleToken(uint64 _amount) external payable {
bytes[] memory nftMetadatas = generateBytesArrayForHTS(
baseURI,
_amount
);
(
int256 response,
uint64 newTotalSupply,
) = HederaTokenService.mintToken(tokenAddress, _amount, metadata);
if (response != HederaResponseCodes.SUCCESS) {
revert("Mint Failed");
}
}
// #dev Helper function which generates array of addresses required for HTSPrecompiled
function generateAddressArrayForHTS(address _address, uint256 _items)
internal
pure
returns (address[] memory _addresses)
{
_addresses = new address[](_items);
for (uint256 i = 0; i < _items; i++) {
_addresses[i] = _address;
}
}
// #dev Helper function which generates array required for metadata by HTSPrecompiled
function generateBytesArrayForHTS(bytes memory _bytes, uint256 _items)
internal
pure
returns (bytes[] memory _bytesArray)
{
_bytesArray = new bytes[](_items);
for (uint256 i = 0; i < _items; i++) {
_bytesArray[i] = _bytes;
}
}
Calling the transaction in js:
const contractMint = await new ContractExecuteTransaction()
.setContractId(contractId)
.setGas(3000000)
.setFunction(
"mintFungibleToken",
new ContractFunctionParameters().addUint64(1)
)
.setMaxTransactionFee(new Hbar(2));
Also note that a REVERT does usually contain useful information, you can navigate to hashscan.io to look up the response from your smart contract, for example
https://hashscan.io/testnet/transaction/1675427464.278782297?tid=0.0.1189-1675427451-309271560
shows a contract that reverted, the error message is 0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001b52656d697420746f6b656e20616c726561647920637265617465640000000000
with the error message starting with 0x08c379a, we know it's a string, so we can decode it
Hacky way:
Navigate to: https://www.rapidtables.com/convert/number/hex-to-ascii.html
Paste the above (remove the 0x)
Choose ASCII for character encoding
Press convert
Output: Ãy  Remit token already created
In Javascript
const {ethers} = require("ethers");
async function main() {
const error = "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001b52656d697420746f6b656e20616c726561647920637265617465640000000000";
const reason = ethers.utils.defaultAbiCoder.decode(
['string'],
ethers.utils.hexDataSlice(error, 4)
)
console.log(reason);
};
void main();
It looks like you're trying to call mintFungibleToken from JS, but the smart contract doesn't have a mintFungibleToken function; the smart contract function name is mintNonFungibleToken.

Calling a solidity payable function with etherjs

I have a basic Solidity smart contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TestContract {
uint256 public _blockTimestamp;
function accumulated() public payable returns (uint256) {
_blockTimestamp = block.timestamp;
return 1;
}
}
And using remix IDE I can compile it and check the value of _blockTimestamp changing after executing the accumulated function.
Now, I can deploy the contract and check the value of the public variable without any problem with etherjs:
const provider = new providers.JsonRpcProvider(getEnv('RINKEBY_NODE_URL'));
const wallet = new Wallet(getEnv('ROPSTEN_PRIVATE_KEY'), provider);
const TestContract = TestContract__factory.connect(getEnv('TEST_CONTRACT'), provider);
const _blockTimestamp = await NFTLTokenContract._blockTimestamp();
The problem is when I try to execute the function accumulated. Being a payable function I need a signer:
const provider = new providers.JsonRpcProvider(getEnv('RINKEBY_NODE_URL'));
const wallet = new Wallet(getEnv('ROPSTEN_PRIVATE_KEY'), provider);
const TestContract = TestContract__factory.connect(getEnv('TEST_CONTRACT'), provider);
const _blockTimestamp = await TestContract._blockTimestamp();
const accumulated = await TestContract.accumulated('1', wallet);
But I still get the error:
Error: sending a transaction requires a signer
(operation="sendTransaction", code=UNSUPPORTED_OPERATION,
version=contracts/5.5.0)
What am I missing?
You are trying to call a non-view function by using only a provider, you must provide a signer in order to call the function.
Try connecting to the contract using the wallet as the signer:
const TestContract = TestContract__factory.connect(getEnv('TEST_CONTRACT'), wallet);

Upgreadable ERC20 TypeError: Cannot create property 'kind' on string

I created 2 smart contracts.
contract A is ERC20 token and B is a contract that accepts ERC20 A as payment method. When deploying, contract A got deployed but when I passed its proxy address to the initialize function in contract B for deployment it shows this error:
TypeError: Cannot create property 'kind' on string '0x814bd9012bD1e51b86890343b9731501875502e8'
what could be the problem?
hardhat deploy script
const token = await ethers.getContractFactory("Token");
console.log("Deploying token...");
const tokeninit= await upgrades.deployProxy(token , {
initializer: "initialize",
});
await tokeninit.deployed();
const tokenaddr = tokeninit.address;
console.log("token deployed at :", tokenaddr );
const SmartB= await ethers.getContractFactory("SmartB");
const SmartBInit= await upgrades.deployProxy(SmartB,tokenaddr, {
initializer: "initialize",
});
Smart contract B shorten code:
contract SamrtB is Initializable, UUPSUpgradeable, OwnableUpgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
CountersUpgradeable.Counter private _tokenIdCounter;
IERC20Upgradeable public tokenAccepted;
constructor() initializer {}
function initialize(address _token) initializer public {
__Ownable_init();
__UUPSUpgradeable_init();
tokenAccepted =IERC20Upgradeable(_token);
}
I was passing the parameters in the next smart contract the wrong way, it should be
const SmartBInit= await upgrades.deployProxy(SmartB,[tokenaddr],{}
Instead of
const SmartBInit= await upgrades.deployProxy(SmartB,tokenaddr, {}

ERC777 Deployment with Transaction Reverted Error

I'm working to deploy an ERC777 token using hardhat, ethers in typescript. My deployment script is as follows
import { MarketSvc, ProductSvc } from '../libs/deployment-service/src';
import hre from 'hardhat';
async function main() {
const marketAddress = await MarketSvc.deployContract(contractType);
const productAddress = await ProductSvc.deployContract(contractType, marketAddress);
}
my execution function looks like this
async deployContract(
contractType: ContractType,
...args: any[]
): Promise<string> {
const contractFactory = await hre.ethers.getContractFactory(contractType);
const contract =
args === undefined
? await contractFactory.deploy()
: await contractFactory.deploy(...args);
await contract.deployed();
console.log(contractType + ' Contract deployed to:', contract.address);
return contract.address;
}
The first deployment succeeds. The second deployment fails with and error of
MarketContract Contract deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
ProviderError: Error: Transaction reverted: function call to a non-contract account
at HttpProvider.request (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\core\providers\http.ts:49:19)
at GanacheGasMultiplierProvider.request (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\core\providers\gas-providers.ts:312:34)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
In the ERC777 contract it is failing in the method below (#openzeppelin\contracts\token\ERC777\ERC777.sol:75)
/**
* #dev `defaultOperators` may be an empty array.
*/
constructor(
string memory name_,
string memory symbol_,
address[] memory defaultOperators_
) {
_name = name_;
_symbol = symbol_;
_defaultOperatorsArray = defaultOperators_;
for (uint256 i = 0; i < defaultOperators_.length; i++) {
_defaultOperators[defaultOperators_[i]] = true;
}
console.log("added operators");
// register interfaces - It is failing here
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
console.log("registered ERC777");
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
}
the constructor to my contract is this
constructor(address defaultOperator)
ERC777("SOMEtoken", "TKN", _defaultOps(defaultOperator)) {
console.log(defaultOperator);
_mint(_msgSender(), 1000000, "Initial Mint", "defaultOps");
}
my solidity log is
Error: Transaction reverted: function call to a non-contract account
at GParticle.constructor (#openzeppelin/contracts/token/ERC777/ERC777.sol:75)
at EthModule._estimateGasAction (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\hardhat-network\provider\modules\eth.ts:425:7)
at HardhatNetworkProvider._sendWithLogging (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\hardhat-network\provider\provider.ts:138:22)
at HardhatNetworkProvider.request (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\hardhat-network\provider\provider.ts:115:18)
at JsonRpcHandler._handleRequest (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\hardhat-network\jsonrpc\handler.ts:188:20)
at JsonRpcHandler._handleSingleRequest (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\hardhat-network\jsonrpc\handler.ts:167:17)
at Server.JsonRpcHandler.handleHttp (C:\src\trae\gbc\exchange\exchange_ui\node_modules\hardhat\src\internal\hardhat-network\jsonrpc\handler.ts:52:21)
the operator address I'm giving it, is defiantly deployed and is a contract. but so I'm a bit baffled about what could possibly be happening in the 777 contract specifically. I have a ERC20 and 1155 that deploy perfectly...
If anyone has any insight, all information is appreciated.
The root of the issue is that if you're working on a localnet, like hardhat... you will have to deploy your own ERC1820_REGISTRY, because it does not exist.
openzepplin has some utilites you can use to enable this pretty simply..
const { singletons } = require('#openzeppelin/test-helpers');
require('#openzeppelin/test-helpers/configure')
async function main() {
const signers = await hre.ethers.getSigners();
const address = signers[0].address;
const erc1820 = await singletons.ERC1820Registry(address);
... deploy your ERC777
}
I implemented a full deployment of ERC1820 & ERC777,
my code checks if it's not deployed, deploys it, and then deploys the ERC777 and registers the recipient,
It's implemented with hardhat and I put the guide in the readme.md
This is my repo :
https://github.com/EhsanParsania/ERC777

Sending eth from contract to wallet address

I have this contract deployed that is meant to send ether from itself to an another account
pragma solidity ^0.8.0;
contract Contract {
address public owner;
address public admin;
constructor(address _admin) public {
owner = msg.sender;
admin = _admin;
}
modifier onlyOwner(address sender) {
require(
sender == admin,
"Only the admin of the contract can perform this operation."
);_;
}
function sendTo (
address toAddress
) public payable onlyOwner(msg.sender) {
payable(toAddress).transfer(msg.value);
}
}
and I try to interact with it like so on the client side:
var contract = new web3.eth.Contract(abi, Address, null);
const transaction = {
from: mainAcct,
to: dummyAcct,
value: '10000000000000000',
gas: 30000
};
await contract.methods.sendTo(dummyAcct).send(
transaction , function(err, hash){
if(!err){
console.log("Transaction hash:", hash);
}else{
console.log(err);
}
});
} catch (e) {
console.log(e);
}
why do I get this error in the console:
Error: Transaction has been reverted by the EVM
Looks like you need to fund the contract before sending the amount out
I did something like below hre is hardhat object, but there will be way to add funds while deploying
const waveContractFactory = await hre.ethers.getContractFactory('contract_name');
const waveContract = await waveContractFactory.deploy({
value: hre.ethers.utils.parseEther('0.1'),
});
The problem could be with transfer, transfer limit the gas and that could be the reason of the error, try using call instead of transfer, check this web to see how to use it https://solidity-by-example.org/sending-ether/