Hi @cherrybluemoon
Your artifact should be your contract name not your file name so use
const Flipcoin = artifacts.require("Coinflip");
instead of
const Flipcoin = artifacts.require("Flipcoin");
Hi @gabba,
Thanks for artifacts.
I am not sure why this is happening. I do not see anywhere a type:error
Compiling your contracts…
Error: TypeError: Cannot read property '2' of null
at /Users/cherrybluemoon/.nvm/versions/node/v12.14.1/lib/node_modules/truffle/build/webpack:/packages/truffle-compile/profiler.js:375:1
at /Users/cherrybluemoon/.nvm/versions/node/v12.14.1/lib/node_modules/truffle/build/webpack:/packages/truffle-compile/~/async/dist/async.js:969:1
at next (/Users/cherrybluemoon/.nvm/versions/node/v12.14.1/lib/node_modules/truffle/build/webpack:/packages/truffle-compile/~/async/dist/async.js:5222:1)
at /Users/cherrybluemoon/.nvm/versions/node/v12.14.1/lib/node_modules/truffle/build/webpack:/packages/truffle-compile/profiler.js:357:1
@cherrybluemoon can you double check there is not a “2” in your code somewhere?
Update your github repo and i ll have a look a it
@gabba,
ok, I’ve updated github, and the only place I have “2” is in contract Flipcoin.sol
modifier costs(uint cost){
uint jackpot = address(this).balance / 2;
require(msg.value <= jackpot, "Jackpot is the max bet you can make");
require(msg.value >= cost, "The minimum bet you can make is 0.01 Ether");
_;
}
When i try to deploy your contract i have the following issue :
You are calling a function which is not in your contract :
instance.fundContract({value: web3.utils.toWei("0.5","ether"), from: accounts[0]}).then(function(){
console.log("The contract successfully got funded with 0.5 ether by the contract owner " + accounts[0]);
console.log("The contract address is " + Flipcoin.address);
Ok, thanks you! I will dive into this and fix this.
Awesome project @Erno, your interface is cool and you are using reactJs
You did take care of every details
usage of private, internal, external, ownership
Provable api is well used and you are checking the api price
Great use of events in the frontend
Well done really great project
Just few details why is your withdraw function payable ?
The payout function is returning a value but you are not using it in your contract (internal funct).
you are not really respecting Check Effects Interactions pattern in your payout function because you are transfering eth before setting the balanceToBeCollected variable to zero. You will not have an issue with reentrancy attack because transfert is limited to 2300 gas so you are safe but it’s always better to use this coding pattern.
You could add the SafeMath library and a proxy in the future, anyway this is just details it’s a really good project overall so well done
@gabba
Project now running with success. https://github.com/rubyredmoon/flipForMoney
cherrybluemoon@Markandrews-MacBook-Pro flipper % truffle migrate --network ropsten
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'ropsten'
> Network id: 3
> Block gas limit: 8000029 (0x7a121d)
2_flipcoin_migration.js
=======================
Deploying 'Coinflip'
--------------------
> transaction hash: 0x0cdf8e6ecaed0407400cafb1aea515b80b008323d6c82535d8deef31ae3afdeb
> Blocks: 1 Seconds: 9
> contract address: 0x49f946fF1CbF970E0194d916153C0b6A636ABaDf
> block number: 8117588
> block timestamp: 1592453071
> account: 0x3F349ca62F3cCa64609702a4a8560D496Ac82A88
> balance: 4.960605497
> gas used: 276612 (0x43884)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00553224 ETH
Pausing for 2 confirmations...
------------------------------
> confirmation number: 2 (block: 8117590)
⠇ Saving migration to chain.The contract successfully got funded with 0.5 ether by the contract owner 0x3F349ca62F3cCa64609702a4a8560D496Ac82A88
The contract address is 0x49f946fF1CbF970E0194d916153C0b6A636ABaDf
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.00553224 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.00553224 ETH
Thanks Yeah I love React, I use it for almost everything and seems to be very suitable for building DApps.
The payable on withdraw function is an error on my part, that should not be there. I have no idea why i did that . The Check Effects Interactions pattern is a good one to use, I agree. I was not aware of this pattern but just finished the smart contract security course and realise the importance of this pattern.
Thanks for the feedback.
Hello everyone, I am a bit stuck, checking my contract on remix i see that now i cant anymore make a bet succesfully (error: transact to HodlSodl.makeBet errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.)
the thing is that my function is payable, i am attaching a value (more than 0.1 eth as required ) and that is for sure less than the contract balance…so i dont know why of this behaviour, maybe you guys have a suggestion for this?
import "./Ownable.sol";
import "./provableAPI.sol";
pragma solidity 0.5.12;
contract HodlSodl is Ownable, usingProvable{
constructor () public payable{ //not updated
balance = msg.value;
}
Bet private lastBet;
uint private balance;
modifier costs(uint cost){
require(msg.value >= cost);
_;
}
struct Player {
uint id;
string name;
uint age;
string email;
uint pin;
uint repeatPin;
}
struct Bet {
string name;
//defined betting hodl (1) or sodl (2)
uint optionChosen;
//defined running __callback_draw()function.
bool win;
//defined in makeBet from __callback_draw()function
uint betAmount;
//defined in makeBet msg.sender
address player;
//defined by wins or losses
uint playerBalance;
//given by __callback
bytes32 queryId;
// queryId would work as element
// in Bet struct, or must be outside
// as a state variable ???
}
mapping (bytes32 => Bet) private betsQueue;
mapping(address => bytes32) private alreadyInGame;
mapping (address => Player) private gamers;
function createPlayer(string memory name, uint age, string memory email, uint pin,uint repeatPin) public payable costs(1 ether){
require(age > 0, "Set age"); //not updated
require(age < 100, "Age needs to be below 100");
require(pin == repeatPin, "repeatPin not equal");
require(msg.value >= 1 ether);
balance += msg.value;
//This creates a player
Player memory newPlayer;
newPlayer.name = name;
newPlayer.age = age;
newPlayer.email = email;
insertPlayer(newPlayer);
assert(
keccak256(
abi.encodePacked(
gamers[msg.sender].name,
gamers[msg.sender].age,
gamers[msg.sender].email
)
)
==
keccak256(
abi.encodePacked(
newPlayer.name,
newPlayer.age,
newPlayer.email
)
)
);
emit playerCreated(newPlayer.name, newPlayer.email);
}
function insertPlayer(Player memory newPlayer) private {
address creator = msg.sender;
gamers[creator] = newPlayer;
}
function getPlayer() public view returns(string memory name, uint age, string memory email){
address creator = msg.sender;
return (gamers[creator].name, gamers[creator].age, gamers[creator].email);
}
function deletePlayer(address creator) public onlyOwner {
string memory name = gamers[creator].name;
string memory email = gamers[creator].email;
delete gamers[creator];
assert(gamers[creator].age == 0);
emit playerDeleted(name, email, msg.sender);
}
function withdrawAll() public onlyOwner returns(uint) {
uint toTransfer = balance;
balance = 0;
msg.sender.transfer(toTransfer);
return toTransfer;
}
function myLastBet() public view returns(string memory name, bool win, uint optionChosen, uint betAmount){
return (
betsQueue[queryId].name,
betsQueue[queryId].win,
betsQueue[queryId].optionChosen,
betsQueue[queryId].betAmount
);
}
function myBalance() public view returns(string memory name, uint playerBalance){
return (
betsQueue[queryId].name,
betsQueue[queryId].playerBalance
);
}
uint256 constant NUM_RANDOM_BYTES_REQUESTED = 1; //move outside the function ???
bytes32 queryId;
function makeBet(uint optionBid) payable public {
// check if contract has enough balance
require(msg.value <= balance);
// set minimum bettable amount
require(msg.value >= 0.1 ether);
//check if player has active games
require(alreadyInGame[msg.sender] == 0);
//This creates a lastBet based on Bet struct
lastBet.name = gamers[msg.sender].name;
lastBet.optionChosen = optionBid;
lastBet.betAmount = msg.value;
lastBet.player = msg.sender;
lastBet.playerBalance = betsQueue[queryId].playerBalance;
uint256 QUERY_EXECUTION_DELAY = 0;
uint256 GAS_FOR_CALLBACK = 200000;
lastBet.queryId = provable_newRandomDSQuery(QUERY_EXECUTION_DELAY, NUM_RANDOM_BYTES_REQUESTED, GAS_FOR_CALLBACK);//__callback_draw(optionBid);
emit logNewProvableQuery("request sent, waiting for result");
betsQueue[queryId] = lastBet;
alreadyInGame[msg.sender] = queryId;
}
function __callback(bytes32 _queryId, string memory _result, bytes memory _proof) public {
// Checks that the the callback function is called from the oracle-contract
require(msg.sender == provable_cbAddress());
require(provable_randomDS_proofVerify__returnCode(_queryId, _result, _proof) == 0);
// Generate result
uint256 randomResult = (uint256(keccak256(abi.encodePacked(_result))) % 2);
if(randomResult == lastBet.optionChosen){
lastBet.win = true;
balance = balance - (betsQueue[_queryId].betAmount);
lastBet.playerBalance += (lastBet.betAmount)*2;
}
else{
betsQueue[_queryId].win = false;
balance = balance + (betsQueue[_queryId].betAmount);
}
// emit result to frontend
emit resultReady(betsQueue[_queryId].name, betsQueue[_queryId].player,betsQueue[_queryId].betAmount , betsQueue[_queryId].win);
// clear player from mapping
delete alreadyInGame[betsQueue[_queryId].player];
delete betsQueue[_queryId];
}
function withdrawPlayer() public returns(uint) {
uint toTransfer = betsQueue[queryId].playerBalance;
betsQueue[queryId].playerBalance = 0;
msg.sender.transfer(toTransfer);
return toTransfer;
}
// eventi
event playerCreated(string name, string email);
event playerDeleted(string name, string email, address deletedBy);
event placedBet(string name,address player, uint betAmount, bool win);
event logNewProvableQuery(string waiting);
event resultReady(string name, address player, uint betAmount , bool win);
}
Thanks, this was just what I was looking for.
Hi guys,
I have a trouble after cmd>> truffle migrate --network ropsten
It says "… can not read property ‘number’ of null from ethUtil.toBuffer(jsonBlock.number)
I tried to search on google - but seems no one had the same issue…
Could some one please help?!
last update:
I followed instruction of @gabba to reinstall all things at:
https://forumtest.ivanontech.com/t/windows-installation-git-vscode-nvm-nodes-ganache-truffle/15582
Then, I when I tried: “truffle migrate --network ropsten --reset” --> there was error message that the solidity version should be 0.4.26
after revising vesion inside solidity files to 0.4.26, it seems to be able to Migrate…
In remix, I was able to connect to “injected web3” and deploy the contract.
Everything seems running exept that the value of “latestNumber” always show 0.
It seems __callback never returned from the Oracle?
Please help…
Hi @tungtien
If you are not working on the master branch, let us know on which one is your last commit ;).
It’s CoinFlip4_stage2_0 i guess ?
I m trying to look at your contract transaction but i can’t see any contract there
0xcf031ECc9792583F48430b42610664E313ccF403
This is the address in your main.js .
Can you send me a transaction hash or your contract address ?
Sometime the provable Api is down it happens many times.
Can you try to use the provable api this way
constructor () public payable{
provable_setProof(proofType_Ledger);
balance = msg.value;
}
event proofFailed(string description);
function __callback(bytes32 _queryId, string memory _result, bytes memory _proof) public {
require(msg.sender == provable_cbAddress());
if (
provable_randomDS_proofVerify__returnCode(
_queryId,
_result,
_proof
) != 0
) {
emit proofFailed("The proof verification failed in the callback");
} else {
// Generate result
}
}
Thx you
Thanks @gabba,
Yes, I am working on " CoinFlip4_stage2_0" branch.
The address inside main.js is the address I deployed on local Truffle console since the last phase. I havent changed main.js since I started phase 2. Now I just followed Filip’s lecture on adding Oracle functions and deploying to Ropten network. So far I am just testing on Remix.
After deploying to Ropsten on Power sheell, I have following result:
PS D:\@TUNG 2020\IVANONTECH\SOLIDITY 201\coinFlip4> truffle migrate --network ropsten --reset
Compiling .\contracts\CoinFlip100.sol...
Compiling .\contracts\Ownable.sol...
Compiling .\contracts\provableAPI_0.4.25.sol...
Writing artifacts to .\build\contracts
Using network 'ropsten'.
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0x935c14f925e07f081ed2323ced11e07f6c01d490b1bc7a8b3d8b43f8fbfaff24
Migrations: 0xc3c605b56c2261f9f9dc004602029188bccc09be
Saving artifacts...
Running migration: 2_CoinFlip100_migration.js
Replacing CoinFlip100...
... 0xb4a68003670fd37a0d5ca69dd8820dfc4d2e054629fb6256e6838b83dafee23f
CoinFlip100: 0xe1ded24e07bc83af82a2d06c021bfc27be3c81c9
Saving artifacts...
Remix shows CoinFlip100 is deployed at:
0x8D441eF1319FD13682213653F4510071F6f563f4
I will try with your suggested codes and reply later…
Updated:
WHen I came to the https://faucet.ropsten.be/ after cliking request for some ETH, I saw the notice that :" **you are greylisted - your greylist period is now extended on ip and address for spamming… **"
Is this greylist policy applying only on this Faucet Page or on entire Ropsten networks? Can this explain weird responses I had during the deployment process?
I also found a small error in the code: I used “bytes” type for _queryId , but it should be “bytes32”… I hope this fix will work. (updated in last commit)
UPdated:
I used matamask fauset io and got some more ETH; Hope that the above Greylist issue is only applying for that specific fauset page (?)
After adding some more line as @gabba sugested… From Power Shell, I tried to migrate to Ropsten again but got the error again:
on other hand, if I deploy the contract from inside Remix, I got the error:
Contract code size over limit
Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails.
Updated:: Hi @gabba I comment out proof code sugested by you and it seems solved the problem.
The migration problem seems caused by Over sized problem :
here is the result after migration on Truffle :
PS D:@TUNG 2020\IVANONTECH\SOLIDITY 201\coinFlip4> truffle migrate --network ropsten --reset
Compiling .\contracts\CoinFlip100.sol…
Compiling .\contracts\Ownable.sol…
Compiling .\contracts\provableAPI_0.4.25.sol…
Writing artifacts to .\build\contractsUsing network ‘ropsten’.
Running migration: 1_initial_migration.js
Deploying Migrations…
… 0x45adcd118dab889e7d15d7db29854d299f2a5ed887a12c1a77a59489e205af27
Migrations: 0x3ea6760f9cb647fc596602c6ef67a3202d2ca6fd
Saving artifacts…
Running migration: 2_CoinFlip100_migration.js
Replacing CoinFlip100…
… 0x4ee9f403075c9aa72a59a82b01abf8eabcf45aa4a251f9ac4af3749643fdf8e1
CoinFlip100: 0x067fe7ca944ad3bab992e00b6cecf3a40db2ef99
Saving artifacts…
On Remix, I could get an update for lastNumber other than Zero !
still: don’t know how to solve if the “over size” error if it will happens again…
hi guys,
my deploying cost for Ropsten network is arround 0,5 ETH one time, is it too much? or is it normal?
Hi,
You can set the gas price via Metamask, but it will take some time to be incorporated in a block.
Hi @tungtien
You are using the file provableAPI_0.4.25 did you code your smart contract in solidity 0.4 or 0.5 ?
You need to use the provableAPI_0.5.sol file
You get greylist when you are asking too much ETH , How many ETH did you ask for ?
This is the way to initialize it using the version 5 of the Api
0.5 ETH seems a bit expensive, but bigger is your contract , more expensive it is to deploy it.
Hi @gabba,
- As I ve asked you in few emails ago, after I implemented your instructions on installing allthings from begiining, such as python2, git, window build tools…etc… after that, truffle keeps require me to use solidity 0.4.26. Otherwise it dont compile. Therefore I had to downgrade all my .sol files to 0.4.26… this this really wierd…
- My code is now can be deployed normaly on Remix. The deploy cost is only arround 0.0005eth. But while deploying by Truffle, it takes something like 0,5eth. So o think some thing might wroong with that…
- Now I am still strungling on truffle deployment and truffle testing with this weird error…
Here is my code; I am working on branch …phase2_1
Hi @tungtien
Yes as i answered you did you try to change it in the truffle-config.js ?
line 89
version: "0.4.26", // Fetch exact version from solc-bin (default: truffle's version)
use the same version as in your .sol files instead
version: "0.5.12", // Fetch exact version from solc-bin (default: truffle's version)