so the biggest problem is that when you purchase an item, you need to wait till miners confirm your transaction, before you can use it. so sidechains or state channels like bitcoin Lightning should solve this problem.
Iâm stuck here⌠when using the button to trigger my buyTokens function MetaMask throws an error.
After spending a lot of time on debugging I still couldnt find the error but most likely it has to do with the buyTokens function of the marketplace contract.
Can you give it a look @filip ? It is really frustrating to be stuck so close to the end⌠Many thanks in advance!
pragma solidity ^0.5.0;
import "../lib/IERC1155.sol";
contract Marketplace {
IERC1155 private _token;
// mapping each ID to a specific price
mapping (uint256 => uint256) price;
constructor (IERC1155 token) public {
require(address(token) != address(0));
_token = token;
// prices are given in WEI
price[1] = 100000000000000;
price[2] = 200000000000000;
price[3] = 300000000000000;
}
// if someone sends ETH to the contract without using a specific function (like the buyTokens function)
// in this case we determined that the sender automatically buys an item, so the sender at least gets something in return
function () external payable {
buyTokens(1);
}
function buyTokens(uint256 tokenId) public payable{
uint256 weiAmount = msg.value;
require(weiAmount >= price[tokenId] && price[tokenId] != 0);
_token.safeTransferFrom(address(this), msg.sender, tokenId, 1, "");
}
//this function enables that the user can send tokens/items to the contract
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4){
return bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"));
// the specific return string signals the base contract that we actually can receive buyTokens
// this is a security measure, because if we wouldnt have a receive function, the base contract would make sure
// that the transfer will not be executed and protects the user from accidently losing his tokens
}
}
In case it matters, here is also the javascript file that calls the buyTokens function:
// the provider is changed to work with MetaMask. Metamask injects a provider into our browser which we can access
web3 = new Web3(web3.currentProvider);
ethereum.enable(); // causes a MetaMask popUp that the User has to accept that the webpage can interact with MetaMask
// application binary interface,
// provides the interface to communicate with the functions of our smart contract
// the abi is found in the solidity folder after compiling / migrating the contract:
// SimpleGame\Solidity\build\contracts\GameToken.json
var tokenAbi = [
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_id",
"type": "uint256"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x00fdd58e"
},
{
"constant": false,
"inputs": [
{
"name": "_initialSupply",
"type": "uint256"
},
{
"name": "_uri",
"type": "string"
}
],
"name": "create",
"outputs": [
{
"name": "_id",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x0118fa49"
},
{
"constant": true,
"inputs": [
{
"name": "_interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x01ffc9a7"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_ids",
"type": "uint256[]"
},
{
"name": "_values",
"type": "uint256[]"
},
{
"name": "_data",
"type": "bytes"
}
],
"name": "safeBatchTransferFrom",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x2eb2c2d6"
},
{
"constant": true,
"inputs": [
{
"name": "_owners",
"type": "address[]"
},
{
"name": "_ids",
"type": "uint256[]"
}
],
"name": "balanceOfBatch",
"outputs": [
{
"name": "",
"type": "uint256[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x4e1273f4"
},
{
"constant": false,
"inputs": [
{
"name": "_uri",
"type": "string"
},
{
"name": "_id",
"type": "uint256"
}
],
"name": "setURI",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x67db3b8f"
},
{
"constant": false,
"inputs": [
{
"name": "_operator",
"type": "address"
},
{
"name": "_approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xa22cb465"
},
{
"constant": true,
"inputs": [],
"name": "nonce",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xaffed0e0"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "creators",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xcd53d08e"
},
{
"constant": false,
"inputs": [
{
"name": "_id",
"type": "uint256"
},
{
"name": "_to",
"type": "address[]"
},
{
"name": "_quantities",
"type": "uint256[]"
}
],
"name": "mint",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xcfa84fc1"
},
{
"constant": true,
"inputs": [],
"name": "ERC1155_RECEIVED",
"outputs": [
{
"name": "",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xe0a5c949"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xe985e9c5"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_id",
"type": "uint256"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xf242432a"
},
{
"constant": true,
"inputs": [],
"name": "ERC1155_BATCH_RECEIVED",
"outputs": [
{
"name": "",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xfc67bf1c"
},
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor",
"signature": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_operator",
"type": "address"
},
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_id",
"type": "uint256"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "TransferSingle",
"type": "event",
"signature": "0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_operator",
"type": "address"
},
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_ids",
"type": "uint256[]"
},
{
"indexed": false,
"name": "_values",
"type": "uint256[]"
}
],
"name": "TransferBatch",
"type": "event",
"signature": "0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_operator",
"type": "address"
},
{
"indexed": false,
"name": "_approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event",
"signature": "0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_value",
"type": "string"
},
{
"indexed": true,
"name": "_id",
"type": "uint256"
}
],
"name": "URI",
"type": "event",
"signature": "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b"
}
];
// For the ERC1155 version, we also need an abi for the marketplace
var marketplaceAbi = [
{
"inputs": [
{
"name": "token",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor",
"signature": "constructor"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"constant": false,
"inputs": [
{
"name": "tokenId",
"type": "uint256"
}
],
"name": "buyTokens",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function",
"signature": "0x3610724e"
},
{
"constant": false,
"inputs": [
{
"name": "_operator",
"type": "address"
},
{
"name": "_from",
"type": "address"
},
{
"name": "_id",
"type": "uint256"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_data",
"type": "bytes"
}
],
"name": "onERC1155Received",
"outputs": [
{
"name": "",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xf23a6e61"
}
];
// the addresses used is generated by truffle after migrating the GameToken and Marketplace contracts on the Ropsten Testnetwork
var token = new web3.eth.Contract(tokenAbi, "0xD42b9f042546317EE05AfBE583EF196CF0B56976");
var marketplace = new web3.eth.Contract(marketplaceAbi, "0x47AB0211A6f590021147F18D8317327Ac9b75524");
function buy(id){
web3.eth.getAccounts().then(accountArray => {
var options = {
from: accountArray[0],
value: 0
};
if(id == 1)
options.value = 100000000000000;
else if(id == 2)
options.value = 200000000000000;
else if(id == 3)
options.value = 300000000000000;
marketplace.methods.buyTokens(id).send(options)
.on('receipt', receipt => {
alert("Transaction Complete");
})
});
}
Also I made sure that the marketplace contract is funded (generated the items), I checked it using truffle and the local Node
I would guess itâs something within safeTransferFrom that is throwing an error. Did you successfully mint tokens to the marketplace contract during your migration? You could use truffle to query for the marketplace balance like I did when we tested it locally. Or if you have it deployed on the testnet you could check a block explorer for that testnet.
I haved checked the token balance via truffle on the local node and the balance is there. On Etherescan I find the token and the marketplace contract but I fail to see a balance, maybe you do:
-
Token:
https://ropsten.etherscan.io/address/0xd325e10ff0c8cf44722f708e82d1f3acfc25386a -
Marketplace:
https://ropsten.etherscan.io/address/0x99b8638414fDB9a02A4989Ae60eF15cEC920d8E9
Any ideas? I would love to finish this project succesfullyâŚ
Edit: To avoid confusion, Iâve redeployed the contracts, thats why the address isnt the same anymore as in my .js file that I posted above.
Could you maybe try to use my both contract addresses in your .js file and check if you are able to do the purchases? This might narrow down the problem a bit.
Edit 2:
One important note: Besides changing the contract addresses in your .js file you would also need to adjust the method name:
marketplace.methods.buyTokens(id).send(options)
.on('receipt', receipt => {
alert("Transaction Complete");
})
});
}
As you see my marketplace method is called âbuyTokensâ while in your example you called it âbuyTokenâ
The ABIs are as posted previously.
Many thanks!
I checked your contracts on ropsten. There, the marketplace balance of token id 1 is 0. So that would be one reason for the error. I checked this using myetherwallet, where you can interact with contracts.
SkaĚrmavbild 2019-10-28 kl. 10.18.28One problem that I see, if you look at your token events in etherscan. You can see that value(quantity) is zero for your mint call. That means it minted 0 tokens to marketplace, which would explain the issue. I donât know why though. You should probably double check your deployment of these contracts, and how you call mint.
Below is a screenshot of the event, where the last value is the amount of tokens you minted.
SkaĚrmavbild 2019-10-28 kl. 10.20.14Hey Filip!
Thanks for checking into the contracts. I still havent solved the issue but I figured out something:
This what you see at Etherescan in your second image (the events) is actually the createToken1 function which creates a new token with id1 and creates an initial supply of 0 (as it was supposed to).
Those inital tokens are transferred to my MetaMask account as I am deploying the contracts on the testnet.
I double checked this by using the following code in the migration:
// get token contract
var Token = artifacts.require("./GameToken.sol");
var Marketplace = artifacts.require("./Marketplace.sol");
// initialize truffles deployer object that will at the end execute its deploy() function
module.exports = (deployer, network, [owner]) => deployer
.then(() => createToken1())
.then(() => createToken2())
.then(() => createToken3())
.then(() => mintTokens());
async function createToken1(){
// calls the create function of the ERC1155Mintable contract
// Token with ID1 created, initial supply = 0
(await Token.deployed()).create(81,"");
}
async function createToken2(){
// calls the create function of the ERC1155Mintable contract
// Token with ID2 created, initial supply = 0
(await Token.deployed()).create(82,"");
}
async function createToken3(){
// calls the create function of the ERC1155Mintable contract
// Token with ID3 created, initial supply = 0
(await Token.deployed()).create(83,"");
}
function mintTokens(){
Token.deployed().then(instance => {
//calls the mint function of the ERC1155Mintable contract
instance.mint(1, [Marketplace.address], [30]);
instance.mint(2, [Marketplace.address], [20]);
instance.mint(3, [Marketplace.address], [10]);
});
}
So as you see Iâm now creating an initial supply of 81 / 82 / 83. When checking the token contract on Etherescan you now see the following events:
Here all the addresses:
Token Contract: 0x9303C0194abd4a295cEfbc77f79A6E49f859e655
Marketplace Contract: 0xA7Bc05fa24c28F42eFFBc08f95981190732E2B23
My MetaMask Address: 0x49C41696d0083767Eb4ae8E141BF2ef7E719fcB1
So from what I see here at the event log, it really seems like only the very first createToken() function gets executed, since I do not see any events for the remaning tokens and also the Marketplace wonât be mint the tokens, so somehow the execution seems to stop after the first function.
Do you have any idea why this might be happening? Is it some sort of error during the migration / deployment?
When Iâm deploying the exact same contracts on the local node via truffle it seems to work because Iâm able to verify the marketplace balance via
(await GameToken.at("0x...")).balanceOf("0x...",1).then(bn => bn.toNumber())
I really hope to be able to finish this project and I would be very glad if you could take another look at it.
Thank you so much and best regards,
Lars
Hmm, could you try adding some logging to the truffle code to see which functions actually run?
I would also appreciate if you could share the ABI for the contract. I try to interact with the contract of MEW, but when I use the ABI I used last time it doesnât work.
Hi Filip!
Sure, here is the ABI, sorry for not adding it into my previous comment
var marketplaceAbi = [
{
"inputs": [
{
"name": "token",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor",
"signature": "constructor"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"constant": false,
"inputs": [
{
"name": "tokenId",
"type": "uint256"
}
],
"name": "buyTokens",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function",
"signature": "0x3610724e"
},
{
"constant": false,
"inputs": [
{
"name": "_operator",
"type": "address"
},
{
"name": "_from",
"type": "address"
},
{
"name": "_id",
"type": "uint256"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_data",
"type": "bytes"
}
],
"name": "onERC1155Received",
"outputs": [
{
"name": "",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xf23a6e61"
}
];
var tokenAbi = [
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_id",
"type": "uint256"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x00fdd58e"
},
{
"constant": false,
"inputs": [
{
"name": "_initialSupply",
"type": "uint256"
},
{
"name": "_uri",
"type": "string"
}
],
"name": "create",
"outputs": [
{
"name": "_id",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x0118fa49"
},
{
"constant": true,
"inputs": [
{
"name": "_interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x01ffc9a7"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_ids",
"type": "uint256[]"
},
{
"name": "_values",
"type": "uint256[]"
},
{
"name": "_data",
"type": "bytes"
}
],
"name": "safeBatchTransferFrom",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x2eb2c2d6"
},
{
"constant": true,
"inputs": [
{
"name": "_owners",
"type": "address[]"
},
{
"name": "_ids",
"type": "uint256[]"
}
],
"name": "balanceOfBatch",
"outputs": [
{
"name": "",
"type": "uint256[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x4e1273f4"
},
{
"constant": false,
"inputs": [
{
"name": "_uri",
"type": "string"
},
{
"name": "_id",
"type": "uint256"
}
],
"name": "setURI",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x67db3b8f"
},
{
"constant": false,
"inputs": [
{
"name": "_operator",
"type": "address"
},
{
"name": "_approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xa22cb465"
},
{
"constant": true,
"inputs": [],
"name": "nonce",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xaffed0e0"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "creators",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xcd53d08e"
},
{
"constant": false,
"inputs": [
{
"name": "_id",
"type": "uint256"
},
{
"name": "_to",
"type": "address[]"
},
{
"name": "_quantities",
"type": "uint256[]"
}
],
"name": "mint",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xcfa84fc1"
},
{
"constant": true,
"inputs": [],
"name": "ERC1155_RECEIVED",
"outputs": [
{
"name": "",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xe0a5c949"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xe985e9c5"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_id",
"type": "uint256"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xf242432a"
},
{
"constant": true,
"inputs": [],
"name": "ERC1155_BATCH_RECEIVED",
"outputs": [
{
"name": "",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xfc67bf1c"
},
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor",
"signature": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_operator",
"type": "address"
},
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_id",
"type": "uint256"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "TransferSingle",
"type": "event",
"signature": "0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_operator",
"type": "address"
},
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_ids",
"type": "uint256[]"
},
{
"indexed": false,
"name": "_values",
"type": "uint256[]"
}
],
"name": "TransferBatch",
"type": "event",
"signature": "0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_operator",
"type": "address"
},
{
"indexed": false,
"name": "_approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event",
"signature": "0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "_value",
"type": "string"
},
{
"indexed": true,
"name": "_id",
"type": "uint256"
}
],
"name": "URI",
"type": "event",
"signature": "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b"
}
];
In regards to the logging, where would you suggest to add the logging? in the migration files themselves? And what kind of debug output function would you suggest?
Thank you so much in advance and I wish you and your family already merry christmas!
Best, Lars
Thank you! And merry christmas and happy new year to you as well!
It indeed seems like only the first create function is running in your truffle code. I would suggest you simple add console.log(âhelloâ) at the top of createToken2. Then if you see that in your console you at least know that it did run.
Hey Filip! I hope you had great holidays and had a good start into the new year!
Regarding this fricking migration problem Iâm still stuck⌠A few new findings, hoping maybe you have some more idea what the problem could be:
So I added several console outputs:
// get token contract
var Token = artifacts.require("./GameToken.sol");
var Marketplace = artifacts.require("./Marketplace.sol");
// initialize truffles deployer object that will at the end execute its deploy() function
module.exports = (deployer, network, [owner]) => deployer
.then(() => createToken1())
.then(() => createToken2())
.then(() => createToken3())
.then(() => mintTokens());
async function createToken1(){
console.log('hello createToken1');
// calls the create function of the ERC1155Mintable contract
// Token with ID1 created, initial supply = 0
(await Token.deployed()).create(81,"");
(await Token.deployed()).create(84,"");
}
async function createToken2(){
console.log('hello createToken2');
// calls the create function of the ERC1155Mintable contract
// Token with ID2 created, initial supply = 0
(await Token.deployed()).create(82,"");
}
async function createToken3(){
console.log('hello createToken3');
// calls the create function of the ERC1155Mintable contract
// Token with ID3 created, initial supply = 0
(await Token.deployed()).create(83,"");
}
function mintTokens(){
console.log('hello mintTokens');
Token.deployed().then(instance => {
//calls the mint function of the ERC1155Mintable contract
instance.mint(1, [Marketplace.address], [30]);
instance.mint(2, [Marketplace.address], [20]);
instance.mint(3, [Marketplace.address], [10]);
});
}
When I deploy the contract on a local node or on the Ropsten Testnet, all those outputs will pop up, but still only the createToken1 function actually creates new Tokens .
As you also will notice, I played around a little and created a second set of tokens in the createToken1 function. By checking on etherscan (https://ropsten.etherscan.io/address/0xbb7fbe7b77cc33e8600b581e55354e7729176fe3#events) you now notice that both of those token creations will get executed, but anyways for some weird reason the token creations of the following functions are left ignored.
Also when I deploy the very same files on the local node via âtruffle developâ, the whole thing actually seems to work (marketplace holds 30 tokens of id1):
truffle(develop)> (await GameToken.at("0xDF31d391105269675bEe8b04c9C152537DfC76Ac")).balanceOf("0x8710A44348620042748558B37ce3Ce8c7bd8B48b",1).then(bn => bn.toNumber())
30
So it appears that somehow when deploying on the Ropsten Testnet, the migrations wonât interact with the contracts properly. Do you have any idea what the problem might be? Did you also test if your very own files still work? (maybe some parts are outdated due to some Ethereum hardfork?)
Looking forward to be hearing from you and I hope we can still get it to work ⌠=) Iâm already very close to giving up due to the amount of time spent on debuggingâŚ
Best, Lars
I understand the frustration. Iâm not sure what we are missing here.
Let me run it myself and check Iâll get back to you.
Of course when I run it it works for me. You can check it out on these addresses.
Token: https://ropsten.etherscan.io/address/0x316b644c0bdbeb8bf6070ac6a57bf3781c4f8f14
Marketplace: https://ropsten.etherscan.io/address/0x46d4adE748612eEcdaaD1798B625B1634d426530
And when I check the balances through the console it all looks good.
Have you tried cloning my entire project from github? https://github.com/filipmartinsson/Ethereum-Game-Programming-Course . To make sure you are running exactly the same versions and code. Just to see if we can get it to work, after that we can try to backtrack to find the issue.
Hey Filip!
I did another session of testing and debugging and FINALLY it works!
To do so, I took your marketplace project folder and replaced step by step all of your files with mine until I was able to recreate the same weird behavior.
The problem was rather embarrassing, and was found in the âinitial_migrationâ file. I simply had the import path wrong which needed to be pointed to the Migrations.sol file ⌠I have no idea how I missed it, some sort of code-blindnessâŚ
While testing I also found a minor issue in your project file, which is in your Token.sol file. There you declare the contract as âGameTokenâ which actually should be called âTokenâ. This little error left me quit a bit confused when I cleared your build folder since I wouldnât be able to compile anymore.
The funny thing is that in your original build folder, there was anyways some GameToken.json file already, which was then used by truffle during deployment and luckily you wouldnât receive any errors =)
So finally it is all set and ready and now I will quickly finish the project by integrating the smart contracts into the actual game, yey!
Thanks for your support and best regards, Lars
Amazing! Thanks for sharing your progress Lars And thanks for the head up about my code.
Good luck in the future!
wouldnât it be easier to start introducing async/await code rather than all the callback chaining⌠it would also be a lot easier for noobs to js maybe
For people like me who had the same code but neither of the options above were the problem after following through the course:
So it turns out that in my case that specific error had nothing to do with the code I had. The issue was with truffle. I npm uninstall -g [email protected]
(whatever different version of truffle you have that caused the error)
I tried truffle v 5.0.5 (npm install g [email protected]
)
This fixed the above issue with the ALERT: Transaction Error. Exception thrown in contract code.
If you have checked everything and you find that nothing is wrong with your code. Chances are that the truffle version is the issue.
The following versions of plugins that I have success with are as follows:
[email protected]
truffle/hdwallet-provider": â^1.2.2â
Also be aware that truffle-hdwallet-provider has been deprecated. So make sure you install truffle/hdwallet-provider instead and replace the require
statement inside truffle-config.js
to const HDWalletProvider = require('@truffle/hdwallet-provider');
Another thing, donât forget to place your Infura project key! @filip missed this out in one of his videos when he was setting up truffle-config.js file in his project.
Hope that helps fix any remaining issues people may have!
Hey guys so i have just finished the last sections in the course and with this ill share my final post to the changes that can be made to get the whole code working. For anyone that sees this post i have written similar walthrough style posts in the other sections where adjustments need to be made to the code to get things working properly. If you go back and follow my previous posts then you should be able to finish this course.
However this post actually summarises the last three sections. I thought id write it here instead of breaking it down in the last two sections since there isnt too much to do. So the first part of the last few sections of this course is deploying our contratcts to the ropsten test network. Since our ERC1155 contratc are in a new directory outside of the main code folder we must reinstall the truffle hd-wallet provider. in Filips video he uses the command
npm install truffle-hdwallet-provider
If you recall my previous post, this will most likley not work for you and we instead have to change the install to
npm install @truffle/hdwallet-provider.
The reason for this is because the original course is a few years old and web3 has evolved and some commands and functions have changed thus we need to use the latter verion of the hdwallet provider install. Remember that if you use this version you need to also change your declaration in your truffle-config.js.
For more details on this go back to the first ERC20 part of the course and in my post there i explain this in more detail. Once the hd-wallet providr is installed in our ERC1155 directory we can now deploy to ropsten as usual using
truffle migrate --network ropsten
Now when i had installed the hdwallet provider and run the ropsten migration i recieved this error
I believe this is to do with a version error when we ran the truffle hdwallet provider install. After some digging online it seems that things will work if you install a specific version of the hdwallet provider. So to do this we need to first uninstall our current version by running the command
npm uninstall @truffle/hdwallet-provider
and then reinstalling with
npm install @truffle/[email protected]
where we are specifically installing with version 1.2.3. Now that this version is installed you should be able to deploy successfully to ropsten. Note that the migration will take about 3-5 minutes so be paitent as your heart races in hope that no compilation errors arise lol!!!.
Once you successfully deply to ropsten you can follow Filips code perfectly right up untill he adds the functionality of purchasing the different items with the inclusion of buttons. Now when i got this far i was able to purchase item0 which is the pump talisman. However whenever i tried to purchase either the super botts or time warp cape metamask would throw this error
For awhile i had no clue at all why this error was being thrown. I couldnt figure out why it was allowing me to purchase the first item but not the latter two. If any of you get this same transaction error note that it is a contarct issue and not a front end issue in your eth.js file or index.html file. So be prepared to go back into your contarcts and start debugging. It is most likely going to be in your marketplace.sol file. For me the error liked in my marketplace.sol file here
There is two issues here firstly i have the a typo in the IERC1155 constructor where i define the price of the second and third item in our price array. This is why i could not buy the super boots and the cape. The second error is in the fallback function below the constructor where i define
buyToken(1)
This should be
buyToken(0)
However just making these changes is not enough. Since we have changed our smart contartcs we must redeploy to ropsten to overwrite the changes in our smart contratcs. Then when we have redeployed we must switch out our new GameToken and Marketplace contract addresses with those in our eth.js file, otherwise we will not be accessing our updates contracts.
This is very important because i did not do this at first and took me a few minutes to realise wh the new changes werent taking effect. I nearly just wrote it off as the change of index above not being the correct fix. With his final change i was able to purchase all items and notice their effect. I just was to emphasis the important point here. Most likely your contract error will not be the same as mine. So if yur getting the meta mask error shown in the screenshot above or a similar error note that the mistake is in one of your contracts. Just be patient and persistent and again line by line go through each file checking for typos and all sorts making sure your code is correct. If you have tunnel vision take a break and come back with fresh eyes.
And with that we have finished this course. Congratulations to everyone who has made it this far it was certainly a difficult journey (for me it was anyway). Stay safe and happy coding
Hello I get the following issue in their command window:
Macbooks-MBP:erc-1155 macbookpro$ npm install truffle-hdwallet-provider
npm WARN deprecated [email protected]: WARNING: This package has been renamed to @truffle/hdwallet-provider.
- [email protected]
updated 2 packages and audited 1971 packages in 16.049s
96 packages are looking for funding
run npm fund
for details
found 918 vulnerabilities (11 low, 335 moderate, 572 high)
run npm audit fix
to fix them, or npm audit
for details
Macbooks-MBP:erc-1155 macbookpro$
I was wondering if anybody has fix this issue.
Based on your console the truffle-hdwallet-provider was already installed (updated 2 packages).
the vulnerabilities error is a common warning message to audit the modules you have installed, but to be honest there is nothing to worry about. The hdwallet provider IS installed properly in you system.
Carlos Z
I get this error when I try to buy an item:
web3.min.js:1 Uncaught (in promise) Error: Transaction has been reverted by the EVM:
{
âblockHashâ: â0x78260a58f6b095f351d23ea7a0d76d99d578af4973ab5759a65bfcbc9a6ca456â,
âblockNumberâ: 11786815,
âcontractAddressâ: null,
âcumulativeGasUsedâ: 7629665,
âeffectiveGasPriceâ: â0x5906e3f9â,
âfromâ: â0xb2688e0166224f1c798c7249f1078cbb248b18dfâ,
âgasUsedâ: 7481741,
âlogsBloomâ: â0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000â,
âstatusâ: false,
âtoâ: â0xdc62011596c23e1284646bf8b6182fa3277d26c4â,
âtransactionHashâ: â0xafb53924f7e88117f7d583aea1b6c04ad29a7d96c8ad8d652d68bd0b86bed063â,
âtransactionIndexâ: 4,
âtypeâ: â0x2â,
âeventsâ: {}
}
at web3.min.js:1:357325
Would anyone be able to advice?
I have posted the files into github here:
Front End: https://github.com/nortay250/pump-your-bag
ERC1155 Implementation: [I tried to push the folder to github but I got this error: remote: Permission to filipmartinsson/erc-1155.git denied]