Home > Mobile >  Test for smart contract (solidity/truffle)
Test for smart contract (solidity/truffle)

Time:03-29

I have these lines of code

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract wasteManagement2 {
    struct Route{
        string date; //struct date{ uint day; uint month; uint year;}
        // eg. monday
        string vehicle;
        string driver; //struct driver { string name, string lname, uint id}
        string location;
        string routebinId;
    }

    mapping (uint => Route) public routes;
    uint public routeCount;

    constructor()  {
        routeCount = 0;
    }

    function setRoute(string memory _date,string memory _vehicle, string memory _driver, string memory _location, string memory _routebinId) public{
        routes[routeCount] = Route (_date,_vehicle, _driver, _location, _routebinId);
        routeCount  ;
    }

    function getRoute(uint _routeCount) public view returns(Route memory){
        return routes[_routeCount];
    }
}

and I want to test the contract on how it's going to work if 6000 different registries happen how much is going to cost. Thanks in advance.

This is the test file for now:

const Routes = artifacts.require("Routes");

contract ("Routes", (accounts) => {
    before(async () =>  {
        instance = await Routes.deployed()
    })

    it ('ensures that the array is empty', async () => {
        let count =  await instance.setRoute()
        assert.equal(count, 0, 'The array should be empty')
    })
})

CodePudding user response:

There is an explanation of manually calculating gas cost at Stack Exchange:

I'm using the Yellow Paper, Appendix G, page 25 as reference.

The cost of gas to deploy your contract can be calculated like this:

21000 because all transactions pay this (Gtransaction) 32000 because is a contract creation (Gcreate) Your transaction will have input data, which will cost you in gas:

4 for each byte with value zero in your input data (Gtxdatazero) 68 for each non zero byte in your input data (Gtxdatanonzero) Initialising variables and running the constructor, costs you:

20000 for each SSTORE when the storage value is set to non-zero(Gsset) 5000 for each SSTORE when the storage value is set to zero (Gsreset) additional gas for each OPCODE your constructor is executing (see reference) Finally, you have to pay to store your code, and that will cost you:

200 for each byte of code you store on the state. When you compile your code, you get your bytecode, and that's where > you can find all the OPCODES your smart contract executes.

You will also get your running (or deployed) bytecode, which is the > code that will be stored on the state. It's equal to the bytecode minus the initialisation and constructor code (that are not stored in the state).

How to know the code size using a truffle javascript test file You can use the following code in a js file inside the test folder:

var YourContract = artifacts.require("YourContract");

contract('YourContract', function(accounts) {
  it("get the size of the contract", function() {
    return YourContract.deployed().then(function(instance) {
      var bytecode = instance.constructor._json.bytecode;
      var deployed = instance.constructor._json.deployedBytecode;
      var sizeOfB  = bytecode.length / 2;
      var sizeOfD  = deployed.length / 2;
      console.log("size of bytecode in bytes = ", sizeOfB);
      console.log("size of deployed in bytes = ", sizeOfD);
      console.log("initialisation and constructor code in bytes = ", sizeOfB - sizeOfD);
    });  
  });
});

Afterwards, run truffle test.

This article on Medium may also help if you want to automate the process:

Measuring Gas Cost In order to determine how much gas (many cycles) of the EVM (Ethereum virtual machine) each option takes, we need to measure them. There are many useful blockchain features such as a system function called gasleft() that reports how much gas is left for the running contract, and it is also possible to pass functions to other functions. We can use these features to provide a function that will measure the gas cost of a given function, fun:

function GasCost(string memory name, 
    function () internal returns (string memory) fun) 
    internal returns (string memory) 
{
    uint u0 = gasleft();
    string memory sm = fun();
    uint u1 = gasleft();
    uint diff = u0 - u1;
    return concat(name, " GasCost: ", stringOfUint(diff), 
                " returns(", sm, ")");
}

CodePudding user response:

I will show how to calculate the cost of calling a function and then you have to do for loop for 6000 registiries. Assuming that you initialize the contract correct:

const result = await instance.setRoute()

if you console.log(result you get this object

result {
  tx: '0x1550f6f4f3e7abe0e2d39a43127714e4422e548e6a45d54a3fe12c2ed8b1c180',
  receipt: {
    transactionHash: '0x1550f6f4f3e7abe0e2d39a43127714e4422e548e6a45d54a3fe12c2ed8b1c180',
    transactionIndex: 0,
    blockHash: '0x6d13903f40a7b3c989b79accf70d5bb1f7ef673ee59a0eb534b09d375db1bd7e',
    blockNumber: 1249,
    from: '0xd76536f6b5722f78d444ba0c3b8aae84b7a226ba',
    to: '0xde7b6dd9d647e4249f85ac15e5f7c88e7e424fa',
    gasUsed: 31167,
    cumulativeGasUsed: 31167,
    contractAddress: null,
    logs: [],
    status: true,
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    rawLogs: []
  },
  logs: []
}

To get the gas cost write a function:

const getGas = async (result) => {
  const tx = await web3.eth.getTransaction(result.tx);
  const gasUsed = toBN(result.receipt.gasUsed);
  const gasPrice = toBN(tx.gasPrice);
  const gas = gasUsed.mul(gasPrice);
  return gas;
};

toBN is a helper function:

const toBN = (value) => web3.utils.toBN(value);

finally get the gas cost:

const result = await instance.setRoute()
const gas = await getGas(result);
  • Related