Ethereum coinflip dapp discussion

Hi everybody,

since I cannot get ETH on rinkeby I use ropsten which works well.
My problem is when I try to deploy the contract I get this error:


I don’t understand why because Metamask works well

Yeah it’s an update to solidity that changes the way we access the conract. Write your getBalance function like this and retry.

function getBalance() constant public returns (uint){
    return address(this).balance;
}

It’s weird, I won new ETH

But even though I updated my code like you told me I get the same error message

Sorry, I misread your previous compilation warning as an error. Sorry about that. I can see the real error now. Have you selected the external account in superblocks and have unlocked metamask?

Thanks Filip,

I don’t remember what was the problem but now it works!


1 Like

Please check that in metamask setting the privacy mode is “turned off” , it may also cause problem for external website to access metamask accounts.

When its turn off, it will work :slight_smile:

1 Like

Hello Fellow Toshi Timers,
Can someone tell me what’s wrong with my code please? Thanks in advance.
This is what it’s supposed to look like…

Here’s what mine look like…

And here’s the code…
(function (Contract) {
var web3;
var instance;

function init(cb) {
    web3 = new Web3(
        (window.web3 && window.web3.currentProvider) ||
        new Web3.providers.HttpProvider(Contract.endpoint));

    var contract_interface = web3.eth.contract(Contract.abi);
    instance = contract_interface.at(Contract.address);
    cb();
}

function getBalance() {
    instance.getBalance(function (error, result) {
        if(error){
            alert(error);
        }
        else{
            $("#balance").html(result.toString());
        }
    });
}

function waitForReceipt(txHash, cb){
    web3.eth.getTransactionReceipt(txHash, function(error, receipt){
        if(error){
            alert(error);
        }
        else if(receipt !==null){
            cb(receipt);
        }
        else{
            window.setTimeout(function(){
                waitForReceipt(txHash, cb);
            }, 5000);
        }
    });
}

function flip() {
    let val = parseint($("#bet").val());
    instance.flip.sendTransaction({from: "0x95c2332b26bb22153a689ae619d81a6c59e0a804", gas: 100000, value: val}, function(error, result){
        if(error){
            alert(error);
        }
        else{
             waitForReceipt(txHash, function(receipt){
                 if(receipt.status === "0x1"){
                     alert(JSON.stringify(receipt));
                 }
                 else{
                     alert("Receipt status fail")
                 }
             });
        }
    })
}

$(document).ready(function () {
    init(function () {
        getBalance(); 
    });
    $("#submit").click(function(){
        flip();
    });
});

})(Contracts[‘Coinflip’]);

Well I thought I solved my last problem, but as it turns out I didn’t. Can someone take a look at what I’m did please?
Thanks in advance
Sgt. Crypto

Here’s what it looks like.

Here’s the result

So when I am in the view tab of the DApp, enter a number and hit the submit button, nothing happens. I can make deposits on the DApp, however I’m not able to interact with it otherwise.

I would check your chrome console for errors. Let me know what you find.

Another idea would be to try to debug to see where your issue is appearing. See if you even get into the click handler by setting an alert there. Test the same thing at the top of the flip function.

Send your HTML here as well, so we can see if there is any error there.

1 Like

@filip While calling the .click() attribute we have to a function as an argument. Why are we always giving an anonymous function as the argument, why not directly call the function that is required.
eg ("#submitButton").click(flip(); )

You can do that. It’s mostly a personal preference.

1 Like

@filip I have some confusion regarding web3 object. Till this video we were creating an object like var web3=new Web3(…). From what I understood, Web3 is a class and we created an object web3. Then we created an instance of this web3 object by giving the address and ABI.Now we can interact with instance like instance.update.sendtransaction().
Now that we dont have web3 as we renamed it to web3_interface how can we us web3.eth.accounts. Shouldnt we create web3=new Web3(…) and then use web3.eth.accounts? Please clarify.

I understand the confusion. It’s even more confusing since Javascript at it’s core doesn’t have classes or objects, but you can simulate it. And for me referring to things as classes and objects makes it easier to grasp the concepts.

Let me try to clarify. Web3 is the class, correct. We can instantiate that class by creating an object, that would be web3. The web3 object has a property called instance, which refers to the contract instance. The instance is a JS representation of our deployed contract, and through the instance variable we can interact with the contract.

When you say web3_interface, I assume you mean web3_instance. The reason we did this was due to a current bug with web3 and superblocks where the web3 variable would be overwritten. web3_instance is just another name for the web3 object. Which we then use to get the instance and accounts and so on.

I hope that become clearer. Let me now if you have further questions :slight_smile:

BTW, solidity update coming on October 1st. Completely new Dapp course and much more.

1 Like

@filip Thanks for the reply. My confusion is not completely clear. I have an analogy. please tell me if it is wrong. web3 is an already defined instance of Web3. If we want to access anything on the ethereum blockchain i.e. not particulary linked to a smart contract we use web3 without actually instantiating it. e.g.- web3.eth.accounts. This is basically in the browser and does not concern whether there is a smart contract at the backend or not. Now if we want to access a smart contract and its functions we create an instance web3_instance only to access the things related to smart contracts.
In all the previous examples if instead of creating var web3, we created a var with another name (e.g. var connection=Web3(…)), we could use connection.function.sendTransaction() to access the contract and still use web3.eth.accounts because this is already defined in any object of Web3.
Hope i have clearly explained what i think.
Thats a lot to understand. :sweat_smile:

@filip Can anyone please send me some ether on rinkeby test network on this address.
0x457cE8fFB22bcF098637AD20f9848186b3677F30
I am unable to get it from the faucet. Apparently i am a greedy user for that website.:rofl: :rofl: :rofl:

Almost, you are right that we use web3 generally for accessing everything on the blockchain and not necessarily tied to a specific contract.

But I think you are confused with term instantiated. There is a different between when we talk about instantiation in Javascript and a contract instance in Web3. Also, web3 and web3_instance is exactly the same thing, just different names.

The web3 and web3_instance variables are instantiations of the Web3 class, this is pure programming talk.

When we want to interact with the contract we need to get a contract instance, which we do using the ABI and the address like this: instance = contract_interface.at(Contract.address);

instance is not the same as web3_instance.

As you said that web3 and web3_instance are both the same. Will accounts=web3_instance.eth.accounts work?

@filip forgot to mention you

In general yes, I don’t think it will work in Superblocks because of their bug. This will not be case after the course is updated.

Hi Filip (and everybdy),

I changed the getLastFlip as followes:

function getLastFlip (address owner/*player*/) constant public returns (bool) {
        return lastFlip [owner/*player*/];
    }

I also used “owner” instead of “msg.sender” in the flip function.
It works (give results). However is there any problem that i am not aware to doing so?

  1. I used function random (involving the msg.value in determining the calculations ,instead of just the block.timestamp) as follows:
    it works, is it acceptable solution?
function random () private view returns (uint8) {
       return uint8(uint256(keccak256(msg.value,block.timestamp)));
   }


    function flip () payable public{
     
        uint time= random();//block.timestamp;
        uint bet= msg.value;
    
        if(time % 2== 0){
        msg.sender.transfer(bet*2);
        lastFlip [owner/*msg.sender*/]= true;
        } 
        else{
            lastFlip [owner/*msg.sender*/]= false;
        }
}

Thanks

Thanks

Guy