Here is a video of the project working!
Coin flip betting dapp
And here is the code!
aglawson/CoinFlipDapp_Phase1 at master (github.com)
Hi @a.lwsn, great work!
Just looked at your codebase and I have a doubt.
Isnât it a bad practice to define your variables when declaring them?
Shouldnât it be done in the constructor? Maybe Iâm just a bit confused with other programming languages
Hello everyone. I am almost done with the first phase but am having trouble with my withdraw function. The deposit and gamble functions both work as intended however when i click the withdraw function the metamask display comes up, I hit confirm but no value is being transferred. I can see in ganache there is value in the contract. Below is the code for .js interaction and the contract. Am I misdeclaring the function by not listing it as payable?
The contract Code
function withdrawAll() public onlyOwner returns(uint){
msg.sender.transfer(balance[msg.sender]);
return balance[msg.sender];
}
The .js code to call the function
function withdrawAll() {
console.log("called"); //written to check if code was being called
contractInstance.methods.withdrawAll().send()
.on("receipt", function(receipt){
contractInstance.methods.checkBalance().call().then(function(res){
$("#ETH_output").text(web3.utils.fromWei(res,"ether"));
console.log("completed");//written to check if function was completed
});
});
}
Thanks
As @filip said not a sexy dapp
https://drive.google.com/file/d/1iskKN0_jGZkX77lsBoJI23OvuftDiq4t/view?usp=sharing
Wow
pragma solidity 0.5.12;
//pragma abicoder v2;
contract BetContract{
address public owner;
event BetLog(uint amount, address indexed DepositedTo,bool status);
mapping(address => mapping(uint => bool)) approvals;
struct BetLogS{
uint amount;
address receiver;
bool Status;
uint id;
}
BetLogS[] BetLogAr;
bytes32 name;
constructor() payable public{
require(msg.value > 0);
owner = msg.sender;
}
function random() private view returns(uint){
return block.timestamp % 2;
//return now % 2;
}
function Bet() public payable{
require(msg.value > 0);
BetLogS memory newBet;
newBet.amount = msg.value;
newBet.receiver = msg.sender;
uint amt = random();
if(amt == 0){
emit BetLog(msg.value, msg.sender,false);
newBet.Status = false;
}else{
uint BtAmt = msg.value;
msg.sender.transfer(BtAmt * 2);
emit BetLog(msg.value, msg.sender, false);
newBet.Status = false;
}
newBet.id = BetLogAr.length;
BetLogAr.push(newBet);
}
modifier OnlyOwner{
require(owner == msg.sender ,"You can't view this function");
_;
}
/*function getTransactionPool() public OnlyOwner view returns(BetLogS[] memory){
return (BetLogAr);
}*/
}
Am done with the app
Hey @cge5009
Because the function is not âviewâ you have to use send()
instead of call()
.
contractInstance.methods.withdrawAll().send({from: accounts[0]})
Cheers,
Dani
Ready for phase two
dan-i,
Thanks for your help and I made the change from call to send and it still wonât work. See my updated code below. Metamask is still throwing an error saying âALERT: Transaction Error. Exception thrown in contract code.â Im at a bit of a loss here as this seems as though it should be straightforward.
Sol code
mapping (address => uint256) public balance;
function withdrawAll() public payable returns(uint){
msg.sender.transfer(balance[msg.sender]);
balance[msg.sender] == 0;
return balance[msg.sender];
}
JS code
function withdrawAll() {
contractInstance.methods.withdrawAll().send({from: accounts[0]})
.on("receipt", function(receipt){
contractInstance.methods.checkBalance().call().then(function(res){
$("#ETH_output").text(web3.utils.fromWei(res,"ether"));
console.log("completed");//written to check if function was completed
});
});
}
Hey @cge5009 Does that code compile?
mapping (address => uint256) public balance;
function withdrawAll() public payable returns(uint){
msg.sender.transfer(balance[msg.sender]);
balance[msg.sender] == 0; <<<---- this is an error
return balance[msg.sender];
}
In order to bind a value to a variable you have to use only one =
Also the function does not have to be payable as you are not sending ether to it.
Change these two things and retry, if it does not work please push your code on GitHub and give me the link, I will take a look.
Happy coding,
Dani
Thank you! @NamaWho
I think youâre right actually! Iâll have to keep that in mind for the future, thank you for the advice
@dan-i that code did compile but did not work. I updated it but am still having issues with that function. I posted my GitHub link below. I believe it is the mapping that is causing me problems. I tried adding in the provable function since everything else worked, but when I added mapping for that I am also having trouble getting that settled.
I know, i know, not so pretty, maybe in the future I will make it more fashion, now Iâm too curious of the next step
Hey @cge5009
I tried to withdraw from your contract and I was able to do it (I did not have any ether to withdraw but the function worked correctly)
TX: https://ropsten.etherscan.io/tx/0xbefc07d7698073df0e4e56a4fb67c9ac4b2ead2963fc2251c6940b50f79f09f1
I was also able to deposit 1 ether: https://ropsten.etherscan.io/tx/0xd1ec91f5b2777ee5fb6eb2b63a636610e7124f04bfe7c485d0676fe353edc6c6
And to play (and win ): https://ropsten.etherscan.io/tx/0x06059f255e470aa99387468d32bb178e071d1d91dba9e6d5e0ae5511a585c140
I was also able to withdraw the ether I deposited: https://ropsten.etherscan.io/tx/0xd421d2ab43831b95fb98c96df55841939138c819bf46ea85e9ee3c73a2d448ea
I deposited 1 ether, I player once and I won, and I was able to withdraw 1 ether, there is a logic issue here
Because I played once and I won, I should be able to withdraw more than I deposited.
Are you sure about this line in your function update()
?
betsPlaced[_queryID].amountGambled = amountGambled;
Think about it, fix it and deploy a new contract, I will be happy to check again.
Also add a button or just some text in your html page so that the user knows how much ether owns (this will update every time the user play and win or lose).
Cheers,
Dani
See you in the next phase!
Hey Danielle, I have a question. I am designing the smart contract for the coin flip but I have some troubles.
I have defined the following objects:
struct Bet {
address payable userAddress;
uint size;
uint side;
bool win;
bool finished;
}
uint contractBalance;
mapping(address => Bet) userBetting;
mapping(address => uint) userBalances;
I then define some functions - fundContract, fundUserBalance, withdrawFromContract, withdrawUserBalance and others. When I fund contract or fundUserBalance I just change âthe number in a mappingâ where it says balance, but I donât / canât do the actual transfer to the contract (by using address(this).transfer(_deposit)
like I wanted to).
When I withdraw on the other hand I do use .transfer like written below.
function fundContract(uint _deposit) public payable onlyOwner {
contractBalance += _deposit;
}
function fundUserBalance(uint _addCash) public payable {
require(msg.sender.balance >= _addCash);
userBalances[msg.sender] += _addCash;
function withdrawFromContract() public onlyOwner {
require(contractBalance > 0, "No funds to wtihdraw");
uint toWithdraw = contractBalance;
msg.sender.transfer(toWithdraw);
}
function withdrawUserBalance(uint _toWithdraw) public {
require(userBalances[msg.sender] > _toWithdraw, "Not enough funds");
userBalances[msg.sender] -= _toWithdraw;
msg.sender.transfer(_toWithdraw);
}
My questions now are:
-
is this correct and if so, why? Is it because I will send ether to the contract via Web3 in main.js file? And does that mean .transfer is used only for transfering funds that are on the contract?
-
if it is not correct I would believe I have to use .transfer when funding the contract at least. But
address(this).transfer(_deposit)
does not work, it says I canât deposit to address(this).
Thanks.
@dan-i found some trouble about main.js file after I start python server my main.js doesnât update.
https://drive.google.com/file/d/1TizgHm98bxLDC-YMTwZyu14_aEdPqv5h/view?usp=sharing
This is my phase1
https://drive.google.com/file/d/1FKiN8GAJE99TEPIDieeVr83A1lY6AZe9/view?usp=sharing
Hi,
I have a question. When I set up a python website (localhost: 8000) for the PeopleProject, everything works fine. I type into Powershell the following: python -m http.server. Then, when I type in âlocalhost:8000â into my browser, the webpage gets pulled up.
However, when I do the same for my project that I am working on, I get the four choices below (see screenshot). If I click on âwebSite.htmlâ, then my website comes up. Why is my website not coming up automatically (like with the PeopleProject website)? I canât figure it out, and is it a problem?
Hi @ZigaP
- is this correct and if so, why? Is it because I will send ether to the contract via Web3 in main.js file? And does that mean .transfer is used only for transfering funds that are on the contract ?
That is correct.
.transfer
is a solidity method that allows your contract to send ether to an address.
In order to send funds to a contract you need:
- A function in your contract that accepts ether, therefore it will be declared as
payable
; - A front end that allows a user to send funds (this is not strictly necessary but it is how you allow non-developers to interact with your contract).
Here an example of Solidity and backend that will hopefully clarify your ideas.
Solidity code of a deposit
function:
function deposit () public payable {
}
A deposit function does not need anything more than what I wrote before, of course inside you can add as much code as you want (depending on what you want to do) but you will be able to deposit Ether in your contract only by writing that statement above.
Now you need to code a js function that allows a user to deposit.
Whenever you want to send ether to a function (using web3) you have to use the method .send()
function deposit() {
contract.methods.deposit().send({ from: *here the sender address*, value: 10 ** 18 });
}
In the function above I am calling the method deposit()
and I am sending 1 ether (10 ** 18).
Make sure to always specify a sender address otherwise the function will not work.
Here a simple contract I wrote, check it out if you want https://github.com/dani69654/CoinFlip
Let me know if you have questions.
Cheers,
Dani