Programming Project - Phase 2

Hi @tungtien
I m not using directly the .on(‘data’)
Can you try with “once”
https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html#once

Or you can try this way

    await contractInstance.getPastEvents(['YOUREVENT NAME'], {fromBlock: 'latest', toBlock: 'latest'},
      async (err, events) => {
      console.log("result of win event was" +events[events.length-1].returnValues.win);
    });
1 Like

Thanks @gabba,
In case I use .once method, should I recall .once after every time I interact with contract?
For example, after receiving .receipt from blockchain?

@tungtien yes but use once only when an event is supposed to be sent and add a filter .
It’s free because you are just reading in the receipt log if there is an event, so use it as much as you can :slight_smile:

After trying to install the truffle hdwallet I get this error every time I try to run any truffle command

Error: Cannot find module '@truffle/hdwallet-provider'

@JeffE

npm install @truffle/hdwallet-provider

did you run this command??

Just figured it out. I uninstalled it but then reinstalled it. I was thinking there was a problem when I had first installed it, but I think it ended up not being a problem. I tried to run truffle console and when it was not running I thought it was a problem.
Thanks!

1 Like

I placed .once call in my js code as follow:

function initEventListeners() {

  //event notice(address indexed sender, string noticeString, uint noticeValue);
  CONTRACT_INSTANCE.once('notice', {  filter: { sender: ACTIVE_ADDRESS},
                                        fromBlock:'latest', toBlock:'pending'} // The same if using toBlock:'latest'
      , function(error, event){
              if (_lock_notice != event.transactionHash) {
                  _lock_notice = event.transactionHash;
                  alert(event.returnValues[1]+event.returnValues[2].toString());
                  console.log("Event fired: Notice",event)
                  log_notice.push({ notice: event.returnValues[1], value: event.returnValues[2]})
              }
          });

But it seems without the if-then checking for transaction hash, that .once event still alert for the same event multiple times !
Does anyone has the same issue?

I tried your way:

await CONTRACT_INSTANCE.getPastEvents(['notice'], {fromBlock: 'latest', toBlock: 'latest'},
        async (err, events) => {
        console.log("NOTICE event:" + events[events.length-1].returnValues);
        alert("NOTICE event txHash:"+ events[events.length-1].transactionHash)
      });

But here is the error on Console:

1 Like

read property of undefined means your events does not exist i.e. its null (does not have a value).
check err by console.log(err)

1 Like

hi @gabba,
I think I can finish Phase2 here…
Please help me to review my code and give me some recomendation for further optimizations.
I am still not confident in the proper use of events, how to save gas, security measures…

thank you
please see the Master

HI everybody,

I have a question regarding Oracles. How is the off chain server chosen ?
What if a hacker can determine the chosen off chain server and return a fixed number instead of a random number. Are these types of man in the middle attacks possible ?

Thank you very much for your help :slight_smile:

@filip and @gabba and classmates, I am happy to report that I have finally finished the project.

The contract is deployed on Ropsten. I am temporarily hosting the UI on AWS here. Please try it out, win and lose some Ropsten test ETH and let me know what you think.

The GIT project is here.

Some notes:
I started in April but due to recent events in the news had to take it slow. I hit some snags along the way (esp. handling the async responses) and set the project aside in early May. In June I started the project over from scratch, got it running in Truffle. I made necessary changes and deployed to Ropsten only to find that the callback was not firing (or so I thought). One evening in late June I hit the toss button and went to bed. In the morning I saw that it had returned, I just had not realized how long after the transaction completed that the Oracle would call the callback (turns out this is usually between 1 .5 to 2.5 minutes).

Any feed back is welcome. If anyone has any questions please ask.

4 Likes

I am trying to see if a certain line of code is running by running an event to make sure it is even getting to that spot. Where do I check to make sure this event worked? On etherscan

Hi @Angelo_Canesso

The off chain server is chosen by the company who have develop the oracle.

If an hacker want to do that, he will have to hack the company who provide the data to the oracle company.

Let’s take an example (a fake example), let’s say your Dapp is using Chainlink oracle to get the bitcoin price.

Chainlink will update the bitcoin price in his oracle smart contract, they are usually building an index based on multiples source.

ex: Coinmarketcap / CoinGecko/ Coinparprika

Only the owner of the contract is able to update the oracle contract (Chainlink) and as they have probably some mechanism in place to avoid slippage (if the price is ~5% the same or less i don’t know :slight_smile: )
It will be really complicated for an Hacker to achieve it because he will have to hack multiples company who are providing the price in the same time and avoid Chainlink protection mecanism. (For random number this is the same thing they are using multiples sources)

An other miss conception you can have regarding the oracle is that everybody is able to send a random number to your callback . This is not the case as at the beginning of your callback you are usually checking the oracle address :

require(msg.sender == provable_cbAddress(), "msg.sender is not a Provable_cbAddress");

It has been done in the past during a flashloan attack, an hacker was able to use a flashloan to sell a lot of crypto on an exchange use as index price to exploit an other exchange.
The error here cas to use only one external company as data provider.

2 Likes

Hi @JeffE
yes you can check on etherscan.

Every contract have an event category.

You can also simply look at your transaction receipt as an event is stored in your receipt log

3 Likes

So I am a little confused. I understand that this code:

uint256 QUERY_EXECUTION_DELAY = 0;
        uint256 GAS_FOR_CALLBACK = 200000;
        bytes32 queryId = provable_newRandomDSQuery(
            QUERY_EXECUTION_DELAY,
            NUM_RANDOM_BYTES_REQUESTED,
            GAS_FOR_CALLBACK
        );

triggers the callback, but why does it trigger the callback?
Or is it not this code that triggers the callback but the event?

I can get it to work but just want to understand why it works.

Thanks

For our commits. Should we include every file? the node_modules files is huge. Is that always needed to be commited? Or is that something we can have in .gitignore? Also, in build/contracts are the .json files related to the provable api needed?
Thanks

For our commits. Should we include every file? the node_modules files is huge. Is that always needed to be commited? Or is that something we can have in .gitignore? Also, in build/contracts are the .json files related to the provable api needed?
Thanks

No, as you mention you can use a gitignore file or more simply when you git add, do not add the node_modules.

People who clone your project usually will expect to run npm install. Same with build files, the consumer of the project would expect to build on their own as well.

2 Likes

@xactant
Great to see you finish your project in such a nice fashion :slight_smile:

I was able to review your flipit.sol and Storage.sol

  1. Amazingly written smart contract with no warnings too :star_struck:
  2. Great use of inheritance with Storage.sol and the mapping and struct in it makes the code very efficient and reusable
  3. Solidity assembly was also spot on
  4. Each function has been very comprehensively written

If you could upload ProvableAPI.sol file (its missing in the GitHub), can will be able to review ‘flipit_V1.sol’ and whole dApp including front-end :slight_smile:

Thank you!

2 Likes

@Taha,

Thank you for your very positive feedback. I have uploaded provableAPI.sol as requested.

I noticed that the UI is not filtering events by player address as expected. I adjusted the filter and still see everyone’s results (tested using 2 different browsers opened to the app at the same time with different accounts) - obviously not optimal. The filter is set in index.html on line 238. Again any feedback is appreciated.

Thank you!