I was able to create and deploy a contract locally to Ganache using Truffle. I could set and get a value successfully as well. I deployed this contract to both Rinkeby and Ropsten and was able to call the get function, but the set function failed with the error:
Error: Invalid JSON RPC response: ""
Using MyEtherWallet/MetaMask, I was able to call both get and set functions successfully on Rinkeby. Is there anything that jumps out as to why it would work locally, but not on the testnets?
Set function:
ProcessHistoryStoreInstance.setStore(
uuid,
attribute,
value,
{from: account}
).then(function(result) {
console.log('TX Hash: ' + result.tx);
response.status(200).json({success: true, msg: result.tx});
}, function(error) {
console.log('Error setting attribute: ' + error);
response.status(500).json({success: false, msg: error});
});
Get function:
ProcessHistoryStoreInstance.getFromStore.call(uuid, attribute).then(function(result) {
console.log('Result: ' + result);
response.status(200).json({success: true, msg: result});
}, function(error) {
console.log('Error getting attribute: ' + error);
response.status(500).json({success: false, msg: error});
});
Solidity contract:
pragma solidity^0.4.11;
import "./AttributeStore.sol";
contract ProcessHistoryStore {
AttributeStore.Data store;
function getFromStore(bytes32 _UUID, string _attrName) public constant returns (uint) {
return AttributeStore.getAttribute(store, _UUID, _attrName);
}
function setStore(bytes32 _UUID, string _attrName, uint _attrVal) public {
AttributeStore.setAttribute(store, _UUID, _attrName, _attrVal);
}
}
Figured it out. I was using web3 to set my provider instead of truffle-hdwallet-provider.
web3 (wasn't working):
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545"));
}
truffle-hdwallet-provider (now works):
new HDWalletProvider(mnemonic, "http://127.0.0.1:7545");
Related
Following the guide from https://ethereum.org/vi/developers/tutorials/hello-world-smart-contract/
I am getting this error when trying to run my deploy script. I am absolutely lost as to why this is not working as I have copied every piece of code directly from the guide.
My hardhat.config.js
require('dotenv').config();
require("#nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
/**
* #type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.7.3",
defaultNetwork: "ropsten",
networks: {
hardhat: {},
ropsten: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`]
}
},
}
My deploy.js
async function main() {
const HelloWorld = await ethers.getContractFactory("HelloWorld");
// Start deployment, returning a promise that resolves to a contract object
const hello_world = await HelloWorld.deploy("Hello World!");
console.log("Contract deployed to address:", hello_world.address);}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
my .env
API_URL = "https://eth-ropsten.alchemyapi.io/v2/[REDACTED]"
PRIVATE_KEY = "[REDACTED]". // my private key goes here, not including the 0x
It compiles fine but gives me the error when I use the command
npx hardhat run scripts/deploy.js --network ropsten
You don't need the 0x in the private key, just put the exact key you got from metamask :)
https://github.com/ethereumjs/ethereumjs-tx
As per usage example we need to add chain name while creating Transaction.
const tx = new Tx(txObject , { chain: 'rinkeby' })
[error saying web3 is not defined][1]<script>
var myContract;
async function CheckMetamaskConnection() {
// Modern dapp browsers...
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await ethereum.enable();
// Acccounts now exposed
return true;
} catch (error) {
// User denied account access...
return false;
}
}
// Legacy dapp browsers...
else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
// Acccounts always exposed
return true;
}
// Non-dapp browsers...
else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
return false;
}
}
$(document).ready(async function () {
var IsMetamask = await CheckMetamaskConnection();
if (IsMetamask) {
myContract = await web3.eth.contract(SmartContractABI).at(SmartContractAddress);
getCandidate(1);
getCandidate(2);
await myContract.eventVote({
fromBlock:0
}, function(err, event){
console.log("event :", event);
getCandidate(event.args._candidateid.toNumber());
});
console.log("myContract :", myContract);
console.log("Metamask detected!")
} else {
console.log("Metamask not detected");
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Metamask not detected!',
onClose() {
location.reload();
}
});
}
});
async function getCandidate(cad){
await myContract.candidates(cad, function(err, result){
if (!err) {
console.log("result : ", result);
document.getElementById("cad" + cad).innerHTML = result[1];
document.getElementById("cad"+cad+'count').innerHTML = result[2].toNumber();
}
});
}
async function Vote(cad){
await myContract.vote(cad, function(err, result){
if(!err){
console.log("We are winning!");
} else{
console.log("Can not connect to the smart contract");
}
})
}
</script>`
i have node.js and metamask in my system(windows 10)
i cloned you project from github and runned it by following command
npm install
node index.js
the UI deployed perfectly in localhost:3000 but when i try to vote the transaction is not working!!!
then i saw content on smart contract is not rendering!!!
then i checked metamask , which was connected and have 1 ether on ropsten network!!!
then i try ganache (local blockchain provider) and still the transaction is not working!!!
then i paste the smart contract in remix and get the ABI and smart contract address and still not working!!!
then i goto developer tool of browser and saw below error!!!!...i have no idea of this error!!!!...how can i solve this???
The error can be happening because the loading of Web3. Please, try this function:
async loadWeb3(){
if(window.ethereum){
window.web3 = new Web3(window.ethereum)
await window.ethereum.request({ method: 'eth_requestAccounts' })
}
else if(window.web3){
window.web3 = new Web3(window.ethereum)
}
else{
window.alert("Non-Ethereum browser detected. You should consider trying MetaMask!")
}
}
Also, do not forget to add the import on your javascript class:
import Web3 from 'web3'
and install the import with the npm:
npm i web3 --save
I have created a test contract which has been compiled successfully and want to broadcast on ropsten test network using web3js. I have a metmask account which i am using. I would like to know how can i call constructor of my contract and then broadcast on ropsten.
I did broadcast one of my contract without constructor and do have my transaction hash key which is 0xf7e5a8e93db9989b033b85323cdff713ba88b547ef64a544550e145961999aac but i am getting a following error Error encountered during contract execution [Reverted] and Transaction has been reverted by the EVM on console. I would like to know also why i am getting this error after broadcast has been done
const fs = require('fs')
var Tx = require('ethereumjs-tx').Transaction
const Web3 = require('web3')
const web3 = new Web3('https://ropsten.infura.io/v3/KEY')
deploy()
function deploy () {
const privateKey = 'PRIVATE_KEY'
const account1 = 'ACCOUNT_NUMBER'
const privateKey1 = Buffer.from(privateKey, 'hex')
const contractData = fs.readFileSync('../../build/contracts/Testcontract.json')
const contract = JSON.parse(contractData)
const byteCode = contract['bytecode']
web3.eth.getTransactionCount(account1, (err, txCount) => {
const txObject = {
nonce: web3.utils.toHex(txCount),
gasLimit: web3.utils.toHex(100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('0.004', 'gwei')),
data: byteCode
}
let tx = new Tx(txObject, {'chain':'ropsten'})
tx.sign(privateKey1)
const serializedTx = tx.serialize()
const raw = '0x' + serializedTx.toString('hex')
web3.eth.sendSignedTransaction(raw, (err, txHash) => {
console.log('err: ', err, 'txHash: ', txHash)
})
})
}
My contract with constructor looks like this
pragma solidity ^0.5.11;
contract Testcontract {
string public senderName;
string public receiverName;
uint public transferAmount;
constructor (string memory _sender, string memory _receiver, uint _amount) public {
senderName = _sender;
receiverName = _receiver;
transferAmount = _amount;
}
}
UPDATE
A simple way to deploy a contract through an Infura node is using Truffle. In your project's root directory
$ npm install truffle
$ truffle init
Here is a tutorial on how to configure Truffle to use your Infura project. In short, install Truffle's hd-wallet-provider
$ npm install #truffle/hdwallet-provider
Replace truffle-config.js with
const HDWalletProvider = require("#truffle/hdwallet-provider");
const mnemonic = "orange apple banana...";
module.exports = {
networks: {
ropsten: {
provider: () => new HDWalletProvider(mnemonic, 'https://ropsten.infura.io/v3/<YOUR INFURA PROJECT ID>'),
network_id: 3, // Ropsten's id
},
},
compilers: {
solc: {
version: "0.5.11", // Fetch exact version from solc-bin (default: truffle's version)
}
}
}
The previous code configures Truffle to connect to Infura an use your account. In ./migrations directory (created by truffle init) create a new file 2_deploy_testContrac.js where you can define how to deploy your contract and provide the arguments needed by TestContract.
var TestContract = artifacts.require("./TestContract");
module.exports = function(deployer) {
deployer.deploy(TestContract, "AliceSender", "BobSender", 120);
}
Finally, deploy your contract by executing
$ truffle migrate --network ropsten
The reason why your transaction has been reverted is because the constructor of TestContract expected three arguments but you have given zero. Since the constructor couldn't be executed, your deploying transaction was reverted as well.
Instead of manually creating your deploying transaction, you can use web3.eth.Contract.deploy. With this method you can conveniently provide all parameters required by the contract's constructor.
UPDATE: The solution below won't work with Infura because the Infura API does not expose web3.eth.personal functions and it only allows sending rawTranscations.
You should be able to deploy your contract with the following code. Note that it was mainly copy-pasted from the official web3 documentation.
var contractData = fs.readFileSync('../../build/contracts/Testcontract.json');
var contract = JSON.parse(contractData);
var abi = contract['abi'];
var bytecode = contract['bytecode'];
var testContract = eth3.eth.Contract(abi);
var account = ...;
var password = ...;
web3.eth.personal.unlockAccount(account, password);
testContract.deploy({
data: bytecode,
arguments: ['SenderAlice', 'ReceiverBob', 120]
})
.send({
from: account,
gas: 1500000,
gasPrice: '30000000000000'
}, function(error, transactionHash){
console.log(error, transactionHash);
})
.on('error', function(error){
console.log(error);
})
.on('transactionHash', function(transactionHash){
console.log(transactionHash);
})
.on('receipt', function(receipt){
console.log(receipt.contractAddress) // contains the new contract address
})
.on('confirmation', function(confirmationNumber, receipt){
console.log(confirmationNumber, transactionHash);
})
.then(function(newContractInstance){
console.log(newContractInstance.options.address) // instance with the new contract address
});
As per requirement, I need to turn on device registration to Always. However, our SRP flow starts failing with the below issue.
{ code: 'UnknownError', message: 'Unknown error, the response body from fetch is: undefined' }
After doing some research, I found one similar post, but it seems like the only solution is to turn device registration off.
It's failing while running node get-token.js script to retrieve token for our CI/CD testing pipeline.
cognitoUser.authenticateUser(authCfg, {
onSuccess: function (result) {
console.log("Result : ", result);
const token = result.getAccessToken().getJwtToken();
resolve(token)
},
onFailure: function(err) {
console.error("Failure : ", err);
console.log(new Error().stack);
reject(new Error("An error occurred: " + err))
},
newPasswordRequired: function (userAttributes, requiredAttributes) {
cognitoUser.completeNewPasswordChallenge(p, userAttributes, this);
},
});
Seems like I missed the point mentioned in this post . Adding the below code works.
const WindowMock = require('window-mock');
global.window = {localStorage: WindowMock.localStorage};
global.navigator = () => null;
I am new to web3.js and solidity. My question is related to the way we search on the block-chain. Its easy to search for a particular contract if we know the contract address. However, how can we find and identify a specific type of contract using the from address used to create the contracts in the first place.
For eg.
I have a contract ContractA which is created by 'from' address AddressA using web3.js. Now I want to find all the instances of ContractA created by AddressA.
I tried searching using web3.eth.filter API but noting ever returns. Please help.
I also read about using registry pattern to store all the contracts and ask the registry, but couldn't find any useful example.
For those who are looking for a way, as Adam said in his post, there is no direct way to find contracts created by wallet address. Hence, we have to implement registry pattern as shown below to keep track of things and just ask that contract in web3.js, also shown below....
This is how my contract look like
contract ContractA {
bool public is_approved;
address public visa_details;
uint public artifact_count;
// constructors
function ContractA() public {
owner = msg.sender;
}
}
Here is the registry pattern contract
contract ContractARegistry {
mapping(address => address[]) user_contracts;
function registerContract(address contractA) public {
user_applications[msg.sender].push(contractA) - 1; // -1 is very important
}
function findContract(address user) view public returns (address[]){
return user_contracts[user];
}
}
In web3.js you may search like this (I am using Angular4)
import * as ContractA from '../../../../build/contracts/ContractA.json';
import * as UserContracts from '../../../../build/contracts/UserContracts.json';
import * as TruffleContract from 'truffle-contract';
import {Observable} from "rxjs/Observable";
declare var window: any;
#Injectable()
export class AppWeb3ContractAService {
CONTRACT_A = TruffleContract(ContractA);
USER_CONTRACTS = TruffleContract(UserContracts);
constructor(private appWeb3Svc: AppWeb3Service) {
console.log("Injecting the provider");
this.CONTRACT_A.setProvider(this.appWeb3Svc.currentProvider());
this.USER_CONTRACTS.setProvider(this.appWeb3Svc.currentProvider());
}
create(ethAddress): Observable<any> {
return Observable.create(observer => {
this.CONTRACT_A
.new({
from: ethAddress
})
.then(application => {
this.USER_CONTRACTS
.deployed()
.then(registry => {
registry.registerContractA(application.address, {from: ethAddress})
.then(result => observer.next(application))
.catch(error => observer.error(error));
})
.catch(error => observer.error(error));
})
.catch(error => observer.error(error));
});
}
findAll(ethAddress: string):
Observable<any[]> {
return Observable.create(observer => {
this.USER_CONTRACTS
.deployed()
.then(registry => {
registry.findUserContracts(ethAddress, {from: ethAddress})
.then(addresses => {
addresses.forEach(address => observer.next(this.CONTRACT_A.at(address)));
})
.catch(error => observer.error(error));
})
.catch(error => observer.error(error));
});
}
}
This is how my appWeb3Svc looks like
import {Injectable} from '#angular/core';
import {environment} from '../../../environments/environment';
import * as Web3 from 'web3';
declare var window: any;
#Injectable()
export class AppWeb3Service {
public web3: Web3;
checkAndInstantiateWeb3 = () => {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof window.web3 !== 'undefined') {
console.warn(
'Using web3 detected from external source. If you find that your accounts don\'t appear or you have 0 MetaCoin, ensure you\'ve configured that source properly. If using MetaMask, see the following link. Feel free to delete this warning. :) http://truffleframework.com/tutorials/truffle-and-metamask'
);
// Use Mist/MetaMask's provider
this.web3 = new Web3(window.web3.currentProvider);
} else {
console.warn(
'No web3 detected. Falling back to ${environment.HttpProvider}. You should remove this fallback when you deploy live, as it\'s inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask'
);
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
this.web3 = new Web3(
new Web3.providers.HttpProvider(environment.HttpProvider)
);
}
};
constructor() {
this.checkAndInstantiateWeb3();
}
currentProvider() {
return this.web3.currentProvider;
}
eth() {
return this.web3.eth;
}
isAddress(ethAddress: string): boolean {
if (this.web3) {
return this.web3.isAddress(ethAddress);
}
return false
}
}
Hope this helps!
Unfortunately, there's no easy way to do this exact thing. web3.eth.filter can be used to apply filters on contract address, or they can be used to search across transaction logs (events emitted by a contract) where the sender is in the topic list.
If you want all transactions submitted by a specific address, you pretty much have to traverse each block on the chain and examine each transaction within each block to see if from is set to the address you're interested in.
// while looping through the block numbers you're interested in
web3.eth.getBlock(blockNum, (err, block) => {
if (block != null) {
block.transactions.forEach(tx => {
if (tx.from === myAddress) {
// Do something
}
}
}
});