I’ve checked it twice, and the address is the same. I feel like it has something to do with the metamask version i am using… don’t know if that’s the case. Could it be??
Not sure if this might be the problem, but you can try to reset the cache of metamask.
Carlos Z
Hi man,
Tried it on Brave and Chrome, but still the same.
I just uploaded the whole project on Github.
Can you check out what I did wrong?
I honestly don’t know what’s going on.
Kinda stuck rn
Your repo might be private, I’m getting a “page not found” error, which might be because the repo is private.
Try to change it to public please
It will be easier for me to download the repo and replicate the issue.
Carlos Z
Thanks Carlos, It’s now public
So, i have downloaded your repo, create a node project (npm init
), then install truffle (npm install truffle -g
).
The error from the image is “trying to call a function from a non-contract address”.
I’m not sure if you forgot to initialize your local blockchain using truffle, just need to type in the console truffle develop
, you will initialize a local blockchain server that will give you some private keys that you can later use to import in metamask (at least the first private key which will be the deployer of the contract).
You can now do some of the truffle commands inside the truffle console.
Then, after i have added the truffle local blockchain and the private key of the deployer, I just have to deploy the contract in truffle using deploy
, that way i deployed your contracts in the truffle local blockchain and it will return me the data about the deployment of each contract.
After changing just the address of the contract deployed on truffle in your index.js
file, I refreshed your dapp, randomize a cat and click on “create me”, I was able to successfully trigger the function without the error on metamask.
Carlos Z
Ohh damn, it works with you…
I’ve tried using Ganache, think that that’s where the problem was.
Did I miss something if I wanted to use Ganache?
When I used develop
on Ganache, the terminal said that It was a successful deployment.
I even looked on which account it was, and it was the same as the first address on Ganache.
You could use truffle
instead of ganache, i switched to truffle because it gave me less issues than ganache.
Try to follow my steps for truffle, let me know if you need any assistance on process.
Carlos Z
After some time it finally worked.
Thanks!!
Hi. After implemnting the event and playing around a bit I noticed two things. First, the obvious, my Event doesn´t get displayed at all. Second, for some reason I can mint on and on without getting warning, that I hit my limit of 10 gen0 bears.
If someone finds the errors in my code I would be very happy. As for now i have to keep looking for what went wrong.
https://github.com/paulsimroth/nft_marketplace
Hey @PaulS96, hope you are ok.
It’s an issue on the contract or in the dapp? just to know what im exactly looking for, i can locally deploy your contract and try the dapp my self to help you solve that issue.
Carlos Z
Hey @thecil
While testing the Bearcontract in the console I had the desired effect. I could create BEars and after the limit was reached I got the error message. So my guess is, that I have an error somewhere in index.js as my frontend acts a bit weird. I had troubles getting Metamask to respond and also the birth event behaves incorrect.
Thanks in advance for the help
I’m not sure if its only you, there is nothing wrong with your code, it should be working, after i have made some research, i believe it is related to a latest update on metamask, the window.ethereum.enable()
method has been deprecated apparently (check the warnings from the console).
What you could do is to learn https://docs.ethers.io/v5/
Its a web3 library just like web3js, but more commonly used these days.
I tried to run my old repo too, compare yours with mine carefully to find the error, and its also failing like yours, and off course, i have not change it for a long time, it was working before.
I’m going to be offline for some days sadly, but I could drop an update for this when im back on how to migrate the project to ethersjs, is not that hard to be honest, try it by your self and let me know about your progress
Carlos Z
Thanks @thecil for the help.
I kind of guessed that this could be the issue. I will look into it and post an update here.
Hi thecil, how are you doing with this project “Cat Factory-Ethereum Dapp”? Some video instructions are missing to complete the project, could you get them? Let me know if you are interested in trying to solve it together.
Thank you!
VdSR
Hi @thecil
I am currently in the process of implementing your recommended library but I have still some trouble figuring out the correct implementation. I will definetely keep on trying. If you could take a look at my current code and give some feedback I would be grateful.
Thanks in advance.
Hey @PaulS96, hope you are great.
Sorry for the delay on my reply, im not at home this days, so i login to our forum whenever I can.
I have made some progress for the migration to ethersjs.
Initialize Truffle local blockchain node
I’m not using ganache, instead im using truffle to initialize a local blockchain, this is my truffle-config.js
file (which is just an standard config with the development blockchain configured).
Just copy/paste into your file.
truffle-config.js
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation, and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* https://trufflesuite.com/docs/truffle/reference/configuration
*
* Hands-off deployment with Infura
* --------------------------------
*
* Do you have a complex application that requires lots of transactions to deploy?
* Use this approach to make deployment a breeze 🏖️:
*
* Infura deployment needs a wallet provider (like @truffle/hdwallet-provider)
* to sign transactions before they're sent to a remote public node.
* Infura accounts are available for free at 🔍: https://infura.io/register
*
* You'll need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. You can store your secrets 🤐 in a .env file.
* In your project root, run `$ npm install dotenv`.
* Create .env (which should be .gitignored) and declare your MNEMONIC
* and Infura PROJECT_ID variables inside.
* For example, your .env file will have the following structure:
*
* MNEMONIC = <Your 12 phrase mnemonic>
* PROJECT_ID = <Your Infura project id>
*
* Deployment with Truffle Dashboard (Recommended for best security practice)
* --------------------------------------------------------------------------
*
* Are you concerned about security and minimizing rekt status 🤔?
* Use this method for best security:
*
* Truffle Dashboard lets you review transactions in detail, and leverages
* MetaMask for signing, so there's no need to copy-paste your mnemonic.
* More details can be found at 🔎:
*
* https://trufflesuite.com/docs/truffle/getting-started/using-the-truffle-dashboard/
*/
// require('dotenv').config();
// const { MNEMONIC, PROJECT_ID } = process.env;
// const HDWalletProvider = require('@truffle/hdwallet-provider');
module.exports = {
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a managed Ganache instance for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache, geth, or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 9545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
//
// An additional network, but with some advanced options…
// advanced: {
// port: 8777, // Custom port
// network_id: 1342, // Custom network
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
// from: <address>, // Account to send transactions from (default: accounts[0])
// websocket: true // Enable EventEmitter interface for web3 (default: false)
// },
//
// Useful for deploying to a public network.
// Note: It's important to wrap the provider as a function to ensure truffle uses a new provider every time.
// goerli: {
// provider: () => new HDWalletProvider(MNEMONIC, `https://goerli.infura.io/v3/${PROJECT_ID}`),
// network_id: 5, // Goerli's id
// confirmations: 2, // # of confirmations to wait between deployments. (default: 0)
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
// },
//
// Useful for private networks
// private: {
// provider: () => new HDWalletProvider(MNEMONIC, `https://network.io`),
// network_id: 2111, // This network is yours, in the cloud.
// production: true // Treats this network as if it was a public net. (default: false)
// }
},
// Set default mocha options here, use special reporters, etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.5.12", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
settings: { // See the solidity docs for advice about optimization and evmVersion
optimizer: {
enabled: false,
runs: 200
},
// evmVersion: "byzantium"
}
}
},
// Truffle DB is currently disabled by default; to enable it, change enabled:
// false to enabled: true. The default storage location can also be
// overridden by specifying the adapter settings, as shown in the commented code below.
//
// NOTE: It is not possible to migrate your contracts to truffle DB and you should
// make a backup of your artifacts to a safe location before enabling this feature.
//
// After you backed up your artifacts you can utilize db by running migrate as follows:
// $ truffle migrate --reset --compile-all
//
// db: {
// enabled: false,
// host: "127.0.0.1",
// adapter: {
// name: "sqlite",
// settings: {
// directory: ".db"
// }
// }
// }
};
Then I just initialize my local blockchain with truffle develop
, this one will generate some random addresses with their respective private keys that you can import to your metamask to interact with the contract as owner of it.
Then just deploy the contracts with migrate
command inside the develop.
1st step: remove web3js, change to ethersjs CDN
We need to change all .html
files that includes:
<script type="text/javascript" src="./web3.min.js"></script>
to ethersjs CDN
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>
2nd step: initialize ethersjs. Re-structure of the index.js
file.
In our index.js
file, lets start it with this syntax. (We are declaring all the variables that we are going to use, once the document is loaded, we initialize all ethersjs config)
var provider, signer, instance, user, address;
var dnaStr = "457896541299";
var contractAddress = "0xF1aE611fc478659D36188acEa42925426278a1Fd";
$(document).ready(async function () {
// we need to verify if the browser have a wallet extension installed, Example: metamask
if (window.ethereum) {
// ethers provider
provider = new ethers.providers.Web3Provider(window.ethereum);
// MetaMask requires requesting permission to connect users accounts
await provider.send("eth_requestAccounts", []);
// The MetaMask plugin also allows signing transactions to
// send ether and pay to change state within the blockchain.
// For this, you need the account signer...
user = provider.getSigner();
addrees = await user.getAddress();
// ethers
// A contract instance, It allows for easy interaction with the smart contract.
instance = new ethers.Contract(contractAddress, abi, provider);
// You need to connect to a Signer, so that you can pay to send state-changing transactions.
signer = instance.connect(user);
const testCall = await signer.owner();
console.log('Ethereum Browser: Contract Owner', testCall);
} else {
console.log('NON-ETHEREUM BROWSER');
}
});
3rd step: create new gen0 kitty
This is the new basic structure to trigger writing functions on the contract:
async function createKitty() {
var dnaStr = getDna();
try {
const tx = await signer.createKittyGen0(dnaStr);
// wait for the transaction to be mined
const receipt = await tx.wait();
console.log('createKitty receipt', receipt)
} catch (err) {
console.log(err);
}
}
In the next week I will be working to update the course to use ethersjs instead web3js.
Hope this give you a hint
Carlos Z
HI @thecil
Thanks for the help. I wasn´t that far off. I switched to the imported version you now suggested. Still I have the same problems as before. I managed to connect Metamask but I still get different errors regarding the createBear function.
https://github.com/paulsimroth/nft_marketplace
Good morning all,
I’ve added the mint kitty functionality to the page.
I tested it with Metamask and Firefox, connecting to a local chain running within truffle develop.
Code:
index.js
var web3 = new Web3(Web3.givenProvider);
var instance;
var user;
var contractAddress = "0x1753C9f8bFd56c0A21D9a6552bDC7A5cbE0a3E5b";
function notify(message)
{
$('#notifications').html(message);
}
$(document).ready(() => {
console.log('Calling provider.request()...');
window.ethereum.request({ method: 'eth_requestAccounts' }).
then((accounts) => {
user = accounts[0];
notify("Welcome, you are logged in as " + user);
instance = new web3.eth.Contract(abi, contractAddress, { from: user });
// Register with the event
console.log('Registering with Birth event...');
instance.events.Birth({}, (error, event) => {
if (error) {
console.log(error);
}
else {
console.log('Birth event emitted ' + event);
var dna = event.returnValues.genes;
notify("New kitty with dna " + dna + " was added to your wallet");
}
})
});
})
$("#createkitty").click(async () => {
var currentDna = getDna();
notify("Creating a new kitty...");
instance.methods.createKittyGen0(currentDna).send({}, (error, txhash) => {
if (error) {
console.log('Error: ' + error);
}
else {
console.log('createKittyGen0 called');
}
});
})
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Academy kitties </title>
<script type="text/javascript" src="assets/js/jquery-3.4.1.js"></script>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<script src="assets/bootstrap/js/popper.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/web3.min.js"></script>
<script src="./abi.js"></script>
<link rel="stylesheet" href="assets/css/animations.css">
<link rel="stylesheet" href="assets/css/mystyle.css">
<link rel="stylesheet" href="assets/css/cats.css">
<link rel="stylesheet" href="assets/css/scared_cat.css">
<link rel="stylesheet" href="assets/css/colors.css">
<link rel="stylesheet" href="assets/css/factory.css">
<link rel="stylesheet" href="assets/css/frontend.css">
</head>
<body>
<div class="container p-5" style="margin-top: 12vh;margin-bottom: 10vh;">
<div align="center">
<h1 class="c-white">Kitty Freakout</h1>
<p class="c-white">This kitty accidently broke an OFAC sanction</p>
</div>
<div class="row">
<div class="col-lg-6 catBox m-2 light-b-shadow">
<div class="cat">
<div class="ears">
<div class="ear left-ear"></div>
<div class="ear right-ear"></div>
</div>
<div id="head">
<div class="eyes">
<div class="eye">
<div class="pupils"></div>
</div>
<div class="eye">
<div class="pupils"></div>
</div>
</div>
<div class="mouth">
</div>
</div>
<div class="catbody">
<div class="legs">
<div class="legs" id="leg1"></div>
<div class="legs" id="leg2"></div>
</div>
</div>
</div>
<br>
<div class="dnaDiv" id="catDNA">
<b>
DNA:
<!-- Colors -->
<span id="dnabody"></span>
<span id="dnahead"></span>
<span id="dnaears"></span>
<span id="dnalegs"></span>
<!-- Cattributes -->
<span id="dnashape"></span>
<span id="dnaactivity"></span>
<span id="dnaprivacy"></span>
<span id="dnamouth"></span>
<span id="dnaanimation"></span>
<span id="dnaspecial"></span>
</b>
</div>
</div>
<div class="col-lg-5 cattributes m-2 light-b-shadow">
<p>
<div class="tab-menu">
<div class="tab-buttons">
<label><input type="radio" name="tab-menu" value=1>Colors</label>
<label><input type="radio" name="tab-menu" value=2>Cattributes</label>
</div>
</div>
</p>
<div class="tabs">
<div id="tab-colors">
<div class="form-group">
<label for="formControlRange"><b>Body</b><span class="badge badge-dark ml-2"
id="bodycode"></span></label>
<input type="range" min="10" max="98" class="form-control-range" id="bodycolor">
<label for="formControlRange"><b>Head</b><span class="badge badge-dark ml-2"
id="headcode"></span></label>
<input type="range" min="10" max="98" class="form-control-range" id="headcolor">
<label for="formControlRange"><b>Ears</b><span class="badge badge-dark ml-2"
id="earscode"></span></label>
<input type="range" min="10" max="98" class="form-control-range" id="earscolor">
<label for="formControlRange"><b>Legs</b><span class="badge badge-dark ml-2"
id="legscode"></span></label>
<input type="range" min="10" max="98" class="form-control-range" id="legscolor">
</div>
</div>
<div id="tab-cattributes">
<div class="form-group">
<label for="formControlRange"><b>Eye Shape</b>
<span class="badge badge-dark ml-2" id="eyeshapecode"></span>
</label>
<input type="range" min="1" max="3" class="form-control-range" id="eyeshape">
</div>
<div class="form-group">
<label><b>Activity</b></label>
<label><input type="radio" name="decoration" value=1>Run</label>
<label><input type="radio" name="decoration" value=2>Rest</label>
</div>
<div class="form-group">
<label for="formControlRange"><b>Privacy</b>
<span class="badge badge-dark ml-2" id="incognitocode"></span>
</label>
<input type="range" min="0" max="10" class="form-control-range" id="incognito">
<label for="formControlRange"><b>Mouth color</b>
<span class="badge badge-dark ml-2" id="mouthcolorcode"></span>
</label>
<input type="range" min="1" max="90" class="form-control-range" id="mouthcolor">
<label for="formControlRange"><b>Animation</b>
<span class="badge badge-dark ml-2" id="animationcode"></span>
</label>
<input type="range" min="0" max="2" class="form-control-range" id="animation">
</div>
</div>
</div>
</div>
</div>
<p align="center">
<button id="randomkitty" class="white-btn">Get random kitty</button>
<button id="defaultkitty" class="white-btn">Reset to factory settings</button>
<button id="createkitty" class="red-btn">Mint new kitty</button>
<div id="notifications">...</div>
</p>
</div>
<footer align="left">
<p>Ivan on Tech Academy Bootcamp July 2020</p>
</footer>
</body>
<script src="./index.js"></script>
<script src="assets/js/colors.js"></script>
<script src="assets/js/catSettings.js"></script>
<script src="assets/js/catFactory.js"></script>
</html>
Screenshots:
Kitty creating confirmation message: