I used a Greeter contract and compiled it,which generate web3 deploy code as follows:
var _greeting = "This is a contract" ;
var ballot_sol_greeterContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"type":"constructor"}]);
var ballot_sol_greeter = ballot_sol_greeterContract.new(
_greeting,
{
from: web3.eth.accounts[0],
data: '0x6060604052341561000c57fe5b6040516103ac3803806103ac833981016040528080518201919050505b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b806001908051906020019061008292919061008a565b505b5061012f565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100cb57805160ff19168380011785556100f9565b828001600101855582156100f9579182015b828111156100f85782518255916020019190600101906100dd565b5b509050610106919061010a565b5090565b61012c91905b80821115610128576000816000905550600101610110565b5090565b90565b61026e8061013e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610046578063cfae321714610058575bfe5b341561004e57fe5b6100566100f1565b005b341561006057fe5b610068610185565b60405180806020018281038252838181518152602001915080519060200190808383600083146100b7575b8051825260208311156100b757602082019150602081019050602083039250610093565b505050905090810190601f1680156100e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018257600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b61018d61022e565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102235780601f106101f857610100808354040283529160200191610223565b820191906000526020600020905b81548152906001019060200180831161020657829003601f168201915b505050505090505b90565b6020604051908101604052806000815250905600a165627a7a72305820c1f3ef4f75f67078057f269b87485e55352081a112b0c1d16d369e9ec82a99b30029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
I created a javascript file which and tried to load the file using loadScript() it displayed true and then i mined which generate a hex address.
then I stopped the miner and called the contract using greeter.greet().It shows
ReferenceError: 'greeter' is not defined
at <anonymous>:1:1
and on executing
eth.getCode(greeter.address)
ReferenceError: 'greeter' is not defined
at <anonymous>:1:13
I used online solidity Compiler
and geth v1.6.6. stable version
contract mortal {
/* Define variable owner of the type address*/
address owner;
/* this function is executed at initialization and sets the owner of the contract */
function mortal() { owner = msg.sender; }
/* Function to recover the funds on the contract */
function kill() { if (msg.sender == owner) suicide(owner); }
}
contract greeter is mortal {
/* define variable greeting of the type string */
string greeting;
/* this runs when the contract is executed */
function greeter(string _greeting) public {
greeting = _greeting;
}
/* main function */
function greet() constant returns (string) {
return greeting;
}
}
Also while deploying the code :
>loadScript("firstContract.js")
INFO [06-27|19:48:01] Submitted contract creation
fullhash=0x1037088a27d9cacf9ced417381489ba58658c09e4377ec1f66a9bc24c1f29269
contract=0x2c7e7791dfe505c4f3d456d762990558d4cbe171
null [object Object]
true
Related
I am developing a dapp where users can upload photographs and mint them to NFTs. My application uses web3( Alchemy web3), Alchemy, Ropsten and Metamask. I also use Hardhat in order to deploy my contract with the command:
npx hardhat run --network ropsten scripts/deploy.js
First of all I have installed Metamask in my browser(Firefox) and I have created my wallet. I have also used a Ropsten Faucet in order to get some ether. In order to deploy my contract I use my account's private key in hardhat.config.js. The problem is that in this way only my account is able to use the contract. My application is supposed to accept multiple users, each with their own Metamask wallet or configuration, performing their own transactions.
Therefore, can I deploy or change my contract so that it can be used by any user and not just the one who deployed it?
Here is my contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract NFTminter is ERC721, Ownable {
using Counters for Counters.Counter;
mapping (uint256 => string) private _tokenURIs;
mapping(string => uint256) private hashes;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("MyToken", "PcI") {
}
function _baseURI() internal pure override returns (string memory) {
return "ipfs://";
}
function safeMint(address to, string memory metadataURI) public onlyOwner returns (uint256) {
require(hashes[metadataURI] != 1 , "This metadataURI already exists.");
hashes[metadataURI] = 1;
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, metadataURI);
return tokenId;
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
}
Here is my hardhat.config.js:
require("#nomiclabs/hardhat-waffle");
const { MNEMONIC, ALCHEMY_HTTP } = require("./alchemy_secrets.json");
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
module.exports = {
networks: {
ropsten: {
url: ALCHEMY_HTTP,
accounts: ['PRIVATEKEYGOESHERE']
},
},
solidity: "0.8.4",
};
And here is the code which calls the contract and sends the transaction:
import Web3 from "web3";
import CONTRACT_ABI from "../ethContractABI";
import { AbiItem } from "web3-utils";
import {
ROPSTEN_CONTRACT_ADDRESS,
NFT_STORAGE_KEY,
ALCHEMY_API_KEY,
} from "../constants";
import { NFTStorage } from "nft.storage";
import { Contract } from "web3-eth-Contract";
import { AlchemyWeb3, createAlchemyWeb3 } from "#alch/alchemy-web3";
declare global {
interface Window {
ethereum: any;
web3: Web3;
}
}
interface postcardReturn {
ipfsLink?: string | undefined;
tokenID?: number | undefined;
errorMessage?: string | undefined;
}
async function convertToNft(
imageToUpload: File,
etherAddress: string,
privateKey: string
): Promise<postcardReturn> {
try {
await CreateWeb3Object();
const web3 = createAlchemyWeb3(ALCHEMY_API_KEY);
const metadata = await GetNFTmetadata(imageToUpload);
const NFTminter = createNftContract(web3, etherAddress);
//CheckIfTokenExists(NFTminter, metadata, etherAddress);
const receipt = await mintToken(
NFTminter,
metadata,
etherAddress,
web3,
privateKey
);
return {
ipfsLink: metadata.data.image.href,
tokenID: receipt!.events!.Transfer.returnValues.tokenId,
};
} catch (error: any) {
return returnError(error);
}
}
async function GetNFTmetadata(imageToUpload: File) {
const client = new NFTStorage({ token: NFT_STORAGE_KEY });
const metadata = await client.store({
name: "From: User",
description: "IMage to be converted to nft",
image: imageToUpload,
});
return metadata;
}
async function CreateWeb3Object() {
if (window.ethereum) {
try {
const enable = window.ethereum.enable();
return;
} catch (error) {
console.log(error);
}
}
}
async function CheckIfTokenExists(
NFTminter: Contract,
metadata: any,
etherAddress: string
) {
const check = await NFTminter.methods
.safeMint(etherAddress, metadata.url)
.estimateGas((error: any, gasAmount: any) => {
if (error) {
console.error(error);
return "An error has occured";
}
});
}
function createNftContract(web3: any, etherAddress: string) {
const NFTminter = new web3.eth.Contract(
CONTRACT_ABI,
ROPSTEN_CONTRACT_ADDRESS
);
return NFTminter;
}
async function mintToken(
NFTminter: Contract,
metadata: any,
etherAddress: string,
web3: AlchemyWeb3,
privateKey: string
) {
const nonce = await web3.eth.getTransactionCount(etherAddress, "latest");
const tx = {
from: etherAddress,
to: ROPSTEN_CONTRACT_ADDRESS,
nonce: nonce,
gas: 2000000,
maxPriorityFeePerGas: 1999999987,
data: NFTminter.methods
.safeMint(etherAddress, metadata.data.image.href)
.encodeABI(),
};
const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
web3.eth.sendSignedTransaction(
signedTx.rawTransaction!
).then(console.log)
.catch(console.log);
const transactionReceipt = await web3.eth.sendSignedTransaction(
signedTx.rawTransaction!
);
console.log(transactionReceipt);
return transactionReceipt;
}
function returnError(error: any) {
if (error.message.includes("Internal JSON-RPC error."))
return {
errorMessage: "Internal JSON-RPC error.",
};
return {
errorMessage: error.message,
};
}
export default convertToNft;
The privateKey variable is given by the user before he clicks the upload button. If I change the account that I use, the exception is thrown in this line:
const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
The exception says that the Caller is not the contract owner. I think that what I described as the problem is the issue, because I redeployed my contract with the Metamask account that I use now and I can normally send and sign transactions. However, If I change the account I receive an error.
Your safeMint function has onlyOwner modifier. That's why only contract deployer can use it.
I would like to use delegatecall to deposit ETH into WETH and batch this process together with other actions (see code below). When running truffle tests, it seems like the events are triggered correctly but the state does not seem to be updated.
Same behavior on the Rinkeby network. The weird thing is that the transaction completes completely successfully. Here is an example of transaction: https://rinkeby.etherscan.io/tx/0x93c724174e2b70f2257544ebc0e0b9da6e31a7a752872da7683711bd4d4bd92b
Solidity code:
pragma solidity 0.4.24;
import "../interfaces/ERC20.sol";
import "./WETH9.sol";
contract SetupAccount {
address public exchangeAddress;
address public wethAddress;
constructor (
address _exchangeAddress,
address _wethAddress
) public {
exchangeAddress = _exchangeAddress;
wethAddress = _wethAddress;
}
function setup(
address[] _tokenAddresses,
uint256[] _values
) public payable {
for (uint i = 0; i < _tokenAddresses.length; i++) {
_tokenAddresses[i].delegatecall(abi.encodeWithSignature("approve(address,uint256)", exchangeAddress, _values[i]));
}
if (msg.value != 0) {
wethAddress.delegatecall(abi.encodeWithSignature("deposit()"));
}
}
Failing truffle test:
describe('setupAccount', async () => {
beforeEach(async () => {
weth = await WETH.new()
exchange = await Exchange.new(rewardAccount)
bnb = await BNB.new(user1, 1000)
dai = await DAI.new(user1, 1000)
omg = await OMG.new(user1, 1000)
setupAccount = await SetupAccount.new(exchange.address, weth.address)
})
it('setupAccount should deposit weth and approve tokens', async () => {
await setupAccount.setup(
[bnb.address, dai.address, omg.address],
[1000, 1000, 1000],
{ from: user1, value: 10 ** 18 }
)
let wethBalance = await weth.balanceOf(user1)
wethBalance.should.be.bignumber.equal(10 ** 18)
bnbAllowance.should.be.bignumber.equal(1000)
daiAllowance.should.be.bignumber.equal(1000)
omgAllowance.should.be.bignumber.equal(1000)
})
})
Events emitted during test:
Events emitted during test:
---------------------------
Deposit(dst: <indexed>, wad: 1000000000000000000)
---------------------------
Test result:
1) Contract: SetupAccount
setupAccount
setupAccount should deposit weth and approve tokens:
AssertionError: expected '0' to equal '1000000000000000000'
+ expected - actual
-0
+1000000000000000000
I'm confused as to why this doesn't work. Thank's in advance.
msg.value is preserved correctly through a delegatecall. The following code demonstrates this, as evidenced by the emitted event showing the correct value.
pragma solidity >0.4.99 <0.6;
contract Target {
event Received(uint256 amount);
function deposit() external payable {
emit Received(msg.value);
}
}
contract Delegater {
function deposit() external payable {
(bool success,) = address(new Target()).delegatecall(abi.encodeWithSignature("deposit()"));
require(success);
}
}
I have a stupid smart contract like this:
pragma solidity ^0.4.24;
contract ProdottoFactory {
function foo() view returns(string nome){
return "foo";
}
}
And I want to test it with chai
var Prodotto = artifacts.require("ProdottoFactory");
expect = require("chai").expect;
contract("descrizione primo test", function () {
describe("test 2", function () {
it("blablabla", function () {
return Prodotto.new().then(
istance => {
prodottoContract = istance;
}
)
})
})
})
contract("descrizione primo test2", function () {
describe("test 2 2", function () {
it("blablabla2",function () {
return prodottoContract.foo().then(function (res) {
expect(res.toString()).to.be.equal("foo")
})
})
})
})
When I run the command
truffle test
I have this error
Error: Attempting to run transaction which calls a contract function, but recipient address 0xe8f29e5c4ca41c5b40ed989439ddeae4d9384984 is not a contract address
truffle.js
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 7545, // Ganache GUI
network_id: "*" // Match any network id
}
}
};
contracts/ProdottoFactory.sol
pragma solidity ^0.4.24;
contract ProdottoFactory {
function foo() pure public returns(string nome){
return "foo";
}
}
test/ProdottoFactory.js
var pf = artifacts.require("ProdottoFactory");
contract('ProdottoFactory', function(accounts) {
var pfInstance;
before(function() {
return pf.new()
.then(function(instance) {
pfInstance = instance;
});
});
it("should return foo", function() {
return pfInstance.foo.call()
.then(function(str) {
assert.equal(str, "foo");
});
});
});
I made 2 small changes in your contract:
I added public keyword. It's good practice to always define the visibility of your function.
I replaced view to pure. When you are not reading from blockchain/state variable, use pure. More info can be found inside the docs here.
FYI, you don't have to require chai or mocha library. It's already there when you init a Truffle project using truffle init command. The before keyword is part of Mocha library. You can read more about it here.
Lastly, if you want to know the differences between new and deployed keyword in Truffle, read my thread here.
I'm trying to get the balance of an address on my smart contract using web3, but the balance is always 0. Using metamask on Rinkeby since my contract is deployed on rinkeby. https://rinkeby.etherscan.io/address/0x8e3a88be716ce7c8119c36558ec97bc634592255
You can verify the wallet has a balance by putting it in the balanceOf function on etherScan. Use the address 0x8b54A82a12bD5A7bA33B4842cA677E55f78a8612
let provider = web3.currentProvider;
web3 = new Web3(provider);
let abi = 'too long of a string to post here';
let MyContract = web3.eth.contract(JSON.parse(abi));
let myContractInstance = MyContract.at('0x8e3a88be716ce7c8119c36558ec97bc634592255');
let address = '0x8b54A82a12bD5A7bA33B4842cA677E55f78a8612';
function balanceOf(address) {
if (!address) {
return;
}
this.myContractInstance.balanceOf.call(address, function(error, balance) {
if (error) {
return;
}
alert(balance.c[0] + ' RHC');
});
}
balanceOf(address);
Here is the getBalance function on my contract
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
Website implemented on http://robinhoodcoin.net/metamask.html
Code https://github.com/robinhoodcoin/robinhoodcoin.github.io/blob/master/metamask.html
EDIT
when I change the provider to be the following:
var web3 = new Web3(new Web3.providers.HttpProvider('https://rinkeby.infura.io/'));
I am able to get the balance. SO there is something up with using metamask as the provider.
The line at https://github.com/robinhoodcoin/robinhoodcoin.github.io/blob/master/metamask.html#L118 has a typo. It reads:
self.myContractInstance = self.MyContract.at(self.address);
but the address is stored at self.contractAddress, so it should read:
self.myContractInstance = self.MyContract.at(self.contractAddress);
After making that fix, the page works fine for me with MetaMask.
I am trying to deploy a smart contract to a private Blockchain which uses oraclizeAPI.sol library code.
Basically the smart contract is a small implementation of oraclize.
The import does not work, either with the github link or with local import, solc compilation fails because of import.
Both of the below does not work, the contract is not getting properly compiled by solc
1.import "oraclizeAPI.sol";
2.import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
So, next approch i took was to copy the code of oraclizeAPI.sol, directly into the contract code file.
Now the contract gets compiled properly but the i am falling shot on gas every time, while deploying.
Error:
The contract couldn't be stored, please check your gas amount.
Now here are the details of the Blockchain.
genesis.json
{
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x4000",
"alloc": {
"84840c340067c75806273d2524dfbae646a7c68f":
{ "balance": "1606938044258990275541962092341162602522202993782792835301376" }
},
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase": "0x84840c340067c75806273d2524dfbae646a7c68f",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x8000000000000000"
}
I am currently trying to deply the contract using the coinbase id.
web3.eth.getBlock("latest").gasLimit
132661998547049420
web3.eth.getBalance('0x84840c340067c75806273d2524dfbae646a7c68f').e
60
contract code:
contract oraclizeExample is usingOraclize {
string public data;
event newOraclizeQuery(string description);
event newData(string data);
event eventC(string data);
function oraclizeExample() payable {
update();
}
function __callback(bytes32 myid, string result) {
if (msg.sender != oraclize_cbAddress()) throw;
data = result;
newData(result);
//return result;
}
function eventCheck(string dataFClient) returns (string) {
eventC(dataFClient);
return dataFClient;
}
function update() payable returns (string) {
newOraclizeQuery("Oraclize query was sent, standing by for the answer..");
oraclize_query("URL", "json(https://jewel-api.herokuapp.com/jewel/58d89d264d59a000110829bb).invoice_num");
return "update function was called!";
}
}
The code of contract creation.
var ContractABI = web3.eth.contract(JSON.parse(interface));
var SaveContract = ContractABI.new(
{
from: account,
data: bytecode,
gas: '93048696279858031'
}, function (e, contract) {
if(e){
console.log(e, contract);
return;
}
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
fs.writeFileSync('./contracts_data/'+ contract_name + '_final', 'Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash)
return;
}
});
If you want to check the complete contract code with the and the way i am doing this please got to this link.
https://github.com/utkarsh17ife/oraclizeExample/tree/master/contracts_data
Or the complete implementation with node as well:
https://github.com/utkarsh17ife/oraclizeExample
And yes i am able to mine other contract using this setup.
Comment if you need further info on this.
If you are using a private chain you must run the ethereum-bridge, you are getting a throw because your smart contract invokes the oraclize_query function on deployment (constructor function) but no Oraclize contracts were found on your chain.