i'm learning blockchain dev and now i'm trying to mint an NFT, the process is ok but the problem is that metadata are not showed in the wallet or opensea.
This is the contract
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;
import '#openzeppelin/contracts/token/ERC721/ERC721.sol';
import '#openzeppelin/contracts/access/Ownable.sol';
import "#openzeppelin/contracts/utils/Counters.sol";
contract NFT is ERC721, Ownable {
uint256 public mintPrice;
uint256 public maxPerWallet;
uint256 public totalSupply;
bool public isPublicMintEnabled;
string internal baseTokenUri;
address payable public withdrawWallet;
mapping (address => uint256) public walletMints;
mapping(uint256 => string) private _tokenURIs;
Counters.Counter private _tokenIds;
using Counters for Counters.Counter;
using Strings for uint256;
constructor() payable ERC721('NFT', 'NFT') {
mintPrice = 0.0004 ether;
maxPerWallet = 3;
// Set withdraw wallet address
}
function setIsPublicMintEnabled(bool isPublicMintEnabled_) external onlyOwner {
isPublicMintEnabled = isPublicMintEnabled_;
}
function setBaseTokenUri(string calldata baseTokenUri_) external onlyOwner {
baseTokenUri = baseTokenUri_;
}
function tokenURI(uint256 tokenId_) public view override returns (string memory) {
require(_exists(tokenId_), 'Token does not exist!');
return string(abi.encodePacked(baseTokenUri, Strings.toString(tokenId_), ".json"));
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual
{
_tokenURIs[tokenId] = _tokenURI;
}
function withDraw() external onlyOwner {
(bool success, ) = withdrawWallet.call{ value: address(this).balance } ('');
require(success, 'Withdraw failed');
}
function mint(string memory uri) public payable returns (uint256) {
require(isPublicMintEnabled, 'Mint is not enabled');
require(msg.value == mintPrice, 'Wrong mint value');
require(walletMints[msg.sender] + 1 <= maxPerWallet, 'Exceed max quantity per wallet');
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, uri);
return newItemId;
}
}
And this is the mint function on the mint website
const mintNFT = async (nft) => {
setMinting(true)
const mintAmount = 1
const isConnected = Boolean(accounts[0])
if (!isConnected) {
alert('Non sei connesso al tuo Wallet')
setMinting(false)
return
}
var nftParsed = JSON.parse(nft.metadata)
if (window.ethereum) {
// Connect to blockchain
const provider = new providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
const contract = new Contract(
address,
NFT.abi, // Implement
signer
)
const imageFile = await dataUrlToFile(nftParsed.image, "img.png")
const nftstorage = new NFTStorage({ token: NFT_STORAGE_KEY })
const storage = await nftstorage.store({
image: imageFile,
name: nftParsed.name,
description: 'prova'
})
if (storage) {
try {
const response = await contract.mint(storage.url, {
value: ethers.utils.parseEther((0.0004).toString())
})
console.log(response)
} catch (e) {
console.error(e)
alert("Sorry, error while minting your NFT")
setMinting(false)
}
} else {
alert("Mint problems")
setMinting(false)
}
setMinting(false)
}
}
This code convert dataurl (format for nft saved in db) to image
async function dataUrlToFile(dataUrl, fileName) {
const res = await fetch(dataUrl);
const blob = await res.blob();
return new File([blob], fileName, { type: 'image/png' });
}
In first try, i successfully created nft with metadata, but now using a min website seems to be impossible, the time that it worked the image was stored in a directory and not in a dataurl format.
Hope someone can help,
Thanks
Related
VS Code suggested i install Solidity extension which I did. immediately it installed it required that I update my solidity to 0.8.17; I did then I had to update some parts of the code. after I did, I tested on remix and it worked. Back on vs code now and I've been trying to compile but it is not compiling.It creates the 'build' folder but doesn't write any JSON files in it.
Campaign.sol file:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
contract CampaignFactory {
address[] public deployedCampaigns;
function createCampaign(uint minimum) public {
Campaign newCampaign = new Campaign(minimum, msg.sender);
deployedCampaigns.push(address(newCampaign));
}
function getDeployedCampaigns() public view returns (address[] memory) {
return deployedCampaigns;
}
}
contract Campaign {
struct Request {
string description;
uint value;
address payable recipient;
bool complete;
uint approvalCount;
mapping(address => bool) approvals;
}
Request[] public requests;
address public manager;
uint public minimumContribution;
mapping(address => bool) public approvers;
uint public approversCount;
modifier restricted() {
require(msg.sender == manager);
_;
}
constructor (uint minimum, address creator) {
manager = creator;
minimumContribution = minimum;
}
function contribute() public payable {
require(msg.value > minimumContribution);
approvers[msg.sender] = true;
approversCount++;
}
function createRequest(string memory description, uint value, address payable recipient) public restricted {
Request storage newRequest = requests.push();
newRequest.description = description;
newRequest.value = value;
newRequest.recipient = recipient;
newRequest.complete = false;
newRequest.approvalCount = 0;
}
function approveRequest(uint index) public {
Request storage request = requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender] = true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount > (approversCount / 2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete = true;
}
function getSummary() public view returns (
uint, uint, uint, uint, address
) {
return(
minimumContribution,
address(this).balance,
requests.length,
approversCount,
manager
);
}
function getRequestsCount() public view returns (uint) {
return requests.length;
}
}
compile.js file
const path = require("path");
const solc = require("solc");
const fs = require("fs-extra");
const buildPath = path.resolve(__dirname, "build");
fs.removeSync(buildPath);
const campaignPath = path.resolve(__dirname, "contracts", "Campaign.sol");
const source = fs.readFileSync(campaignPath, "utf8");
const output = solc.compile(source, 1).contracts;
fs.ensureDirSync(buildPath);
for (let contract in output) {
fs.outputJsonSync(
path.resolve(buildPath, contract.replace(":", "") + ".json"),
output[contract]
);
}
I have a problem calling a read only function from my frontend. When I try to call it metamask ask me to pay gas fee
and the output of this transaction doesn't have any sense.
The solidity smart contract: https://rinkeby.etherscan.io/address/0xcf781c136ce1534d00db67c4ec488a6c4e01bbef
This is the solidity function : viewregistro
function compile_registro (string memory new_reg) public returns (bool registration){
registro[ultima] = new_reg;
ultima = ultima +1;
registration = true;
return registration;
}
function viewregistro(uint where) public view returns (string memory here){
here = registro[where];
return here;
}
This is the javascript code:
const enable = async () =>{
await window.ethereum.enable();
provider = new ethers.providers.Web3Provider(window.ethereum);
signer = await provider.getSigner();
address = await signer.getAddress();
console.log(provider);
return provider, signer, address
}
const contractConnection2 = async () => {
rank = new ethers.Contract( address_, rankingabi_ ,signer);
console.log(rank);
return rank;
}
const addmember = async() => {
rank.compile_registro("pluto");
}
I am using web3 CDN and I have deployed contract with two variables. example:
pragma solidity ^0.5.0;
contract Sweet() {
address public owner;
uint256 sweets;
uint256 shops;
constructor(uint256 _sweets, uint256 _shops){
owner = msg.sender;
sweets = _sweet;
shops = _shops;
}
function setSweetAndShop(uint256 _sweets, uint256 _shops) public {
sweets = _sweets;
shops = _shops;
}
}
After deploying this example code everything works fine in the remix. After that, I have created an example DAPP.
async function change(){
var web3 = await new Web3(window.ethereum);
var account = await web3.eth.getAccounts();
var abi = [];
var contract = "0x000000000.........";
var token = new web3.eth.Contract(abi, contract);
try{
token.methods.setSweetAndShop(10, 20).call({
from: account[0],
gas: 800000
})
.then(function(error, result) {
if (!error){
console.log(result);
}else{
console.log(error); // This part is returning an error g{} , no data inside.
}
})
}catch(error){
console.log(error)
}
}
Hello I am new to Smart Contract development, for a few days I try to get this working, but no luck. I hope someone can help me. I try to communicate to a Smart Contract deployed to BSC https://testnet.bscscan.com/address/0x2ED1c3c1Fc6646F321cf546a892684E946435CE9 see the source code below.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
mapping(address => uint256) public addressToAmountFunded;
address[] public funders;
address public owner;
AggregatorV3Interface internal priceFeed;
uint balance;
// if you're following along with the freecodecamp video
// Please see https://github.com/PatrickAlphaC/fund_me
// to get the starting solidity contract code, it'll be slightly different than this!
constructor(address _priceFeed) {
priceFeed = AggregatorV3Interface(_priceFeed);
owner = msg.sender;
}
function fund() public payable {
uint256 mimimumUSD = 50 * 10**18;
require(
getConversionRate(msg.value) >= mimimumUSD,
"You need to spend more ETH!"
);
addressToAmountFunded[msg.sender] += msg.value;
balance += msg.value;
funders.push(msg.sender);
}
function getVersion() public view returns (uint256) {
return priceFeed.version();
}
function getPrice() public view returns (uint256) {
(, int price, , , ) = priceFeed.latestRoundData();
return uint256(price * 10000000000);
}
// 1000000000
function getConversionRate(uint256 ethAmount)
public
view
returns (uint256)
{
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
return ethAmountInUsd;
}
function getEntranceFee() public view returns (uint256) {
// mimimumUSD
uint256 mimimumUSD = 50 * 10**18;
uint256 price = getPrice();
uint256 precision = 1 * 10**18;
return (mimimumUSD * precision) / price;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function withdraw() public payable onlyOwner {
payable(msg.sender).transfer(balance);
for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
addressToAmountFunded[funder] = 0;
}
funders = new address[](0);
}
}
I deployed the smart contract with truffle, with the following migration script
const FundMe = artifacts.require("FundMe");
const BINANCE_BNB_USD_PRICE_FEED = '0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE';
module.exports = async (deployer, network, [defaultAccount]) => {
let priceFeedAddress = BINANCE_BNB_USD_PRICE_FEED
try {
await deployer.deploy(FundMe, BINANCE_BNB_USD_PRICE_FEED, { from: defaultAccount })
} catch (err) {
console.error(err)
}
}
I try to call getPrice() that communicates to chainlink to get the latest price of BNB/USDT.
Here is the Javascript
const getContract = () =>
new Promise(async (resolve, reject) => {
const contract = await fetch('./build/contracts/FundMe.json')
const Contract = await contract.json()
let provider = await detectEthereumProvider()
if (provider) {
await provider.request({ method: 'eth_requestAccounts' })
const networkId = await provider.request({ method: 'net_version' })
provider = new ethers.providers.Web3Provider(provider)
const signer = provider.getSigner()
showAddress(signer)
const contract = new ethers.Contract(
Contract.networks[networkId].address,
Contract.abi,
signer,
)
resolve(contract)
return
}
reject('Install Metamask')
})
const showAddress = async (signer) => {
address = await signer.getAddress()
const connectButton = document.getElementById('connect')
connectButton.innerText = address
}
const getPrice = async (contract) => {
console.log('contract', contract)
const price = await contract.getPrice()
console.log('price', price)
const priceContainer = document.getElementById('price')
priceContainer.innerText = price
}
const init = async () => {
const contract = await getContract()
getPrice(contract)
}
const fundButton = document.getElementById('fund')
fundButton.addEventListener('click', async () => {
const fundMe = await getContract()
})
init()
I get the following error in the browser console and have no idea whats the cause.
Your deploy script passing the 0x056... address as the priceFeed param of the constructor.
So the getPrice() contract function is then trying to call the latestRoundData() on the 0x056... address, expecting a response.
However, your contract is deployed on the testnet, and there's no contract on the 0x056... address on the testnet (link) to return a value, which causes the "main" call to revert.
I am a beginner in blockchain programming and I am not able to understand why I am getting an error while trying to solidity function using Web3 and Ganache.
const PetList = require('./build/contracts/PetList.json')
const fs = require('fs')
const Web3 = require('web3')
const abi = fs.readFileSync("build/contracts/PetList.json").toString().trim();
// Ganache Blockchain
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
web3.eth.net.isListening()
.then(() => console.log('Web3 is connected'))
.catch(e => console.log('Wow. Something went wrong'));
var setUpContract = async function( ){
await web3.eth.net.getId().then((networkId) => {
const networkData = PetList.networks[networkId]
console.log("Setting up contract...")
if(networkData){
return petList = new web3.eth.Contract(PetList.abi, networkData.address)
}
})
acc = await web3.eth.getAccounts()
currentAccount = acc[0]
console.log("Account: ", acc[0])
}
async function start(){
await setUpContract()
await addPet()
}
var addPet = async function(){
console.log(await getPetCount())
return results = await petList.methods.addPet('Zippo', 'Dog').send({from: currectAccount})
}
start()
pragma solidity ^0.5.0;
contract PetList{
uint public petCount = 0;
mapping (uint => Pet) public pets;
struct Pet{
uint id;
string name;
string tag;
}
event PetAdded(
uint id,
string name,
string tag
);
function addPet(string memory _name, string memory _tag) public {
require(bytes(_name).length > 0, "INVALID TAG");
require(bytes(_tag).length > 0, "INVALID NAME");
petCount++;
pets[petCount] = Pet(petCount, _name, _tag);
emit PetAdded(petCount, _name, _tag);
}
}
I also used .send() without any parameters and it gave me an error saying No "from" address specified in neither the given options, nor the default options.
To make a function receive ether you must have a fallback function or add payable modifier
So you can change your code to the following
function addPet(string memory _name, string memory _tag) public payable