# Migration from Truffle to Etherlime

## Migration from Truffle to Etherlime

### Install & Initialize Etherlime

```
npm i -g etherlime
```

Install the global etherlime to allow you to run `etherlime` commands.

```
etherlime init
```

The command will add to your project structure the following parts:

> * ./contracts/LimeFactory.sol
>   * ./deployment/deploy.js
>   * ./test/exampleTest.js

Note! These are added just to give you an example. You can remove them.

### Write new scripts for deployment using the template provided

* **require etherlime module**
* **require the compiled contract** from ./build folder not the

  contract itself

*with Truffle* :

```javascript
    const LimeFactory = artifacts.require("./LimeFactory.sol");
```

*with Etherlime* :

```javascript
    const etherlime = require('etherlime-lib')
    const LimeFactory = require('../build/LimeFactory.json');
```

* **set the deployer and then deploy the contract**

*Local deployment with Etherlime* :

```javascript
    const etherlime = require('etherlime-lib')
    const LimeFactory = require('../build/LimeFactory.json');
    const InterfaceFactory = require('../build/InterfaceFactory.json')

    const deployer = new etherlime.EtherlimeGanacheDeployer();
    const limeFactory = await deployer.deploy(LimeFactory);

    //example how to wrap deployed contract and to pass its address
    const contractInstance = await etherlime.ContractAt(InterfaceFactory,
        limeFactory.contractAddress)
```

Find more examples for deployment [here](https://etherlime.readthedocs.io/en/latest/api/deployers.html).

### Modify tests

In order to modify the tests from Truffle to Etherlime, slight changes are needed to be done:

*with Truffle* :

```javascript
    const LimeFactory = artifacts.require("./LimeFactory.sol");

    contract('LimeFactory tests', async (accounts) => {

        let owner = accounts[0];

        beforeEach(async function() {
            limeFactory = await LimeFactory.new();
        });

        it('should do something', () => {

        })
    }
```

*with Etherlime* :

```javascript
    // step1: require Etherlime module
    const etherlime = require('etherlime-lib')

    // step2: require compiled contract from ./build,
    // not the .sol file (as in deployment scripts)
    const LimeFactory = require('../build/LimeFactory.json')


    // step4: replace 'contract' descriptor to 'describe', 
    // then remove (accounts) param in async function 
    describe('LimeFactory tests', async () => {

        // step5: initialize account
        let owner = accounts[0];

        // step6: set the deployer in before/beforeEach
        // and fix the deployment scripts as we did before
        beforeEach(async function() {

            deployer = new etherlime.EtherlimeGanacheDeployer(owner.secretKey);
            limeFactory = await deployer.deploy(LimeFactory);

        });

        it('should do something', () => {

        })
    })
```

```
# Flexibility
```

* \*\*in case you want to use an address of an account, you must extend

  it to\*\* `let owner = accounts[0].signer.address`
* \*\*when a contract’s method is called, the default sender is set to

  accounts\[0]. If you want to execute it from another account,

  replace\*\* `{from: anotherAccount}` object with

  `.from(anotherAccount)`.

*with Truffle* :

```javascript
    await limeFactory.createLime(newLime' 0, 10, 12, {from: accounts[1]})
```

*with Etherlime* :

```javascript
    await limeFactory.from(2).createLime('newLime' 0, 10, 12);

    // as a param you may also use:
    await limeFactory.from(accounts[1]).createLime('newLime' 0, 10, 12);
    await limeFactory.from(accounts[1].signer).createLime('newLime' 0, 10, 12);
    await limeFactory.from(accounts[1].signer.address).createLime('newLime' 0, 10, 12);
    await limeFactory.from(customSigner).createLime('newLime' 0, 10, 12);
```

* \*\*when you need to execute payable function, pass the value as an

  object\*\* `contract.somePayableFunction(arg1, arg2, {value: 100})`
* **don't use “.call” when calling view functions.**
* **to timeTravel - replace web3 increaseTime with global options**

  `utils.timeTravel(provider, seconds)`

## Assertions and available utils

For more convenience Etherlime provides some additional assertions and global utils object:

**assert it is an address** :

```javascript
    it('should be valid address', async () => {
        assert.isAddress(limeFactory.contractAddress, "The contract was not deployed");
    })
```

**assert a function revert** :

```javascript
    it('should revert if try to create lime with 0 carbohydrates', async () => {
        let carbohydrates = 0;
        await assert.revert(limeFactoryInstance.createLime("newLime2", carbohydrates, 8, 2),
            "Carbohydrates are not set to 0");
    });
```

**test an event**

*with Truffle:*

```javascript
    let expectedEvent = 'FreshLime';
    let result = await limeFactory.createLime('newLime' 8, 10, 12);
    assert.lengthOf(result.logs, 1, "There should be 1 event emitted from new product!");
    assert.strictEqual(result.logs[0].event, expectedEvent,
         `The event emitted was ${result.logs[0].event} instead of ${expectedEvent}`);
```

*with Etherlime*

```javascript
    let expectedEvent = 'FreshLime'
    let transaction = await limeFactory.createLime('newLime' 8, 10, 12);
    const transactionReceipt = await limeFactory.verboseWaitForTransaction(transaction)

    // check the transaction has such an event
    let isEmitted = utils.hasEvent(transactionReceipt, LimeFactory, expectedEvent);
    assert(isEmitted, 'Event FreshLime was not emitted');

    // parse logs
    let logs = utils.parseLogs(transactionReceipt, LimeFactory, expectedEvent);
    assert.equal(logs[0].name, 'newLime, "LimeFactory" with name "newLime" was not created');
```

Find more test examples [here](https://etherlime.readthedocs.io/en/latest/cli/test.html#).

## Final steps:

* **delete** `./migrations` folder
* **delete** `truffle.js/truffle-config.js` file
* **delete** `truffle` from `package.json`
* **delete** `node_modules`
* **run** `npm install`
* **open a fresh terminal tab and enter** `etherlime ganache`
* **run** `etherlime test`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://etherlime.gitbook.io/etherlime/developer-documentation/migration-from-truffle-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
