Search code examples
blockchainsoliditysmartcontractsnft

How to track transaction history in solidity?


I'm trying to create a blockchain system that has the following features

  1. Get current owner
  2. Change owner
  3. Get product history (all users that have owned this product at some point of time)

Now I don't know how do I implement this product history requirement. Like we have to track all the transactions of the type change owner but don't know how to implement this.

We are using this smart contract https://github.com/niksvisuals/contracts/blob/master/ProductManager.sol

Note: in our smart contract the change owner is implemented as (ship product + receive product)


Solution

  • You have 2 main options:

    1. Track history on the smart contract (Not recommended since this would be really expensive).
    2. Emit events on the smart contract, listen to them, listen for events and index them.

    Example of number 2

    Smart contract:

    //Declare an Event
    event OwnerChange(address _from, address _to);
    
    //Emit an event when the transfer happens
    emit OwnerChange("0x213..", "0x13123...");
    

    On your backend code, example using web3js We will first get your contract instance: (https://web3js.readthedocs.io/en/v1.7.1/web3-eth-contract.html?highlight=events#new-contract) Then set up a listener to monitor those events (https://web3js.readthedocs.io/en/v1.7.1/web3-eth-contract.html?highlight=events#contract-events):

    var yourContractInstance= new web3.eth.Contract(yourContractABI,contractAddressYouWantToMonitor);
    
    yourContractInstance.events.OwnerChange({
        fromBlock: 0 //This should be when you deployed your contract, ideally keep track of this number as you read new blocks
    }, function(error, event){ console.log(event); })
    .on("connected", function(subscriptionId){
        console.log(subscriptionId);
    })
    .on('data', function(event){
        console.log(event); // same results as the optional callback above
    })
    .on('changed', function(event){
        // remove event from local database
    })
    .on('error', function(error, receipt) { // If the transaction was rejected by the network with a receipt, the second parameter will be the receipt.
        ...
    });
    
    // event output example
    > {
        returnValues: {
            _from: '0x123456789...',
            _to: '0x123456789...',
        },
        raw: {...}