0

I have one smart contract, in which I am doing mapping of machine id and user id mentioned as below:

mapping(bytes32 => uint256) public machineAllocs;
machineAllocs[machineId] = userId;

Now, I am assigning a user id to a machine id and also user id can be change for same machine id. So, if I want to know that on particular date what is last state(let's 11:59 pm) of particular machine id, means which last user id is mapped with that machine id.

So, how to fetch this details?

Fischa7
  • 108
  • 3
Riya Soni
  • 99
  • 10
  • Do you want a smart contract to fetch the details, or some application outside the blockchain, like web3? – Henk Apr 25 '18 at 11:46
  • yes, I want to fetch it from web3. And if there in any option in solidity then it is also ok for me. But is that possible with web3 bcoz I am already fetching past history from event object. But now I want more specific history as I have mentioned in my question. – Riya Soni Apr 25 '18 at 11:51
  • Do you know how to do it with web3 ? – Riya Soni Apr 25 '18 at 12:19

2 Answers2

0

To access these history details in Solidity, you would have to store every mutation, as smart contracts can only seen the current state of the blockchain.

To get the information from outside the blockchain with for example web3, you should have your smart contract log an event every time a mutation of machineAllocs happens.

Take a look at this example:

pragma solidity ^0.4.22;

contract MachineMapping {

    mapping(bytes32 => uint256) public machineAllocs;


    function setMachineUserId(bytes32 _machineId, uint256 _userId) {
        emit MachineUserIdSet(_machineId, machineAllocs[_machineId], _userId);
        machineAllocs[_machineId] = _userId;
    }

    event MachineUserIdSet(bytes32 indexed machineId, uint256 oldUserId, uint256 newUserId);
}

Now, when you want to look up every mutation for a certain machineId, you can use web3.eth.filter.get to get every MachineUserIdSet event logged concerning your contract and the machineId.

To see how, checkout this answer answer. Good luck!

Henk
  • 4,261
  • 1
  • 13
  • 27
  • As per your answer, I had already done this code. Created an event and calling that in my js mentioned as below :

    var machineHistoryEvent = contractInstance.Transferred({}, {fromBlock: 0, toBlock: 'latest'}).get((error, result) => { var blockNumber = JSON.stringify(result[i].blockNumber); }

    But now I have allocated many user ids to particular machine id, and want to get that last state of machine id. Means what was the last user id mapped with machine id, so how to do it ?

    – Riya Soni Apr 25 '18 at 13:53
0

When calling a view function from web3, you can specify the block number at which you want to evaluate the call.

So your task can be decomposed into two steps:

  1. Find the block number that corresponds to the timestamp you're interested in. (You could do a binary search with web3.eth.getBlock() until you find the right timestamp, although you could do better than that by making an intelligent initial guess based on roughly 10-15 seconds per block.)
  2. Call your function and specify that block number. E.g., in web3.js 0.2x.x: contract.machineAllocs(x, blockNumber).
user19510
  • 27,999
  • 2
  • 30
  • 48
  • But in this case, if we become more specific like, if I passing date as 24th April, it gives me the results of all the machine ids let's take time as 11:59 pm. So, how to do that, bcoz we have not entry of block number for 11:59 pm. – Riya Soni Apr 25 '18 at 14:10
  • That's what point #1 is about in my answer. Was there something there you didn't understand? – user19510 Apr 25 '18 at 14:12
  • But if I am entering any time-stamp that is not present in block then how to fetch the state.? – Riya Soni Apr 25 '18 at 14:13
  • If you're looking for the value at time X, then you're looking for the block with the highest timestamp less than or equal to X. – user19510 Apr 25 '18 at 14:15
  • ok, means is it possible to fetch the highest timestamp from the blocks right? – Riya Soni Apr 25 '18 at 14:17
  • I don't know what you mean. Every block has exactly one associated timestamp, and you can see what that timestamp is. – user19510 Apr 25 '18 at 14:21
  • Yes, that I know. And I m also getting timestamp in my code. But how to find highest timestamp for particular machine id from block, that I just got stuck. – Riya Soni Apr 25 '18 at 14:23
  • May be for that we need some logic like find maximum number from many number. That logic I need to put for finding highest timestamp for particular machine id for particular date. – Riya Soni Apr 25 '18 at 14:24
  • I have no idea what you're talking about. What I thought you're asking: "How can I find out the value of machineAllocs[xyz] at a given timestamp?" If you're asking something different, please explain. – user19510 Apr 25 '18 at 14:26
  • No, you got the right point.var blockNumber = JSON.stringify(result[i].blockNumber); var blockCreationTime = web3.eth.getBlock(blockNumber).timestamp;

    I have done this till now. But the question is : For particular machine id I need to find highest timestamp block on that given day, right?

    – Riya Soni Apr 25 '18 at 14:29
  • "For particular machine id"... No, right? If you want to know a value on April 24th at 11:59pm, you need to find the block with the highest timestamp less than April 24th at 11:59pm. Which block that is has nothing to do with which machine ID you're going to check. – user19510 Apr 25 '18 at 14:38
  • So again, you can just do a binary search through the blocks until you find the right one. I don't know how to answer more clearly; I think I'm just repeating the same thing over and over. – user19510 Apr 25 '18 at 14:39