Learning Truffle

If you run npm -l it will list a detail of all commands that can be use on npm.

what the i stand for ?

    install         npm install

                    Install a package

                    Usage:
                    npm install [<@scope>/]<pkg>
                    npm install [<@scope>/]<pkg>@<tag>
                    npm install [<@scope>/]<pkg>@<version>
                    npm install [<@scope>/]<pkg>@<version range>
                    npm install <alias>@npm:<name>
                    npm install <folder>
                    npm install <tarball file>
                    npm install <tarball url>
                    npm install <git:// url>
                    npm install <github username>/<github project>

                    Options:
                    [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer]
                    [-E|--save-exact]

                    aliases: i, in, ins, inst, insta, instal, isnt, isnta, isntal, add

-g stand for

    root            npm root

                    Display npm root

                    Usage:
                    npm root

                    Options:
                    [-g|--global]

                    Run "npm help root" for more info

Carlos Z

thanks for these indications Carlos ! Very helpful

1 Like

Hello,
This is regarding the truffle assignment using the multisig contract we developed in an earlier course.
I managed to start up my local node and deploy the contract. Also operating the ā€œcreateTransferā€- ā€œapproveā€ and ā€œgetTransferrequestā€ was straight forward. The part I got stuck is how do I switch to a different owner in Truffle so I can add more approvals and eventually get the transfer to get executed? - Do I need to make a call from outside the multisigcontract, or can this be done from within?
In Remix itā€™s as easy as changing the address in the drop down menu, but searching the internet and Truffle documentation I havenā€™t found any leads how I can switch between accounts using the MultisigWallet in Truffle.
Iā€™d appreciate any hints from your end.
Thank you.
yestome

Another track I tried to take was connecting my metamask to Truffle and load the three owner accounts into metamask so I can operate from there, but I failed to setup the local custom PRC network on metamask as I think apart from the name and local network address (http://127.0.0.1:9545/) the ID is also required (save button inactive) but I didnā€™t know where to find that information in truffle.

Hey @dan-i
Iā€™ve few queries to ask -

  1. How can I see the logs of an event.
    Letā€™s say in the below function I want to see the value of txnId, how can I trace it?
function createTransfer(address payable _recipient, uint _amount) public onlyOwners{
        require(msg.sender != _recipient,"You can't transfer funds to yourself");
        require(balance[msg.sender] >= _amount,"Transfer amount is more than deposit");
        Transfer memory txn = Transfer(msg.sender,_recipient,_amount,0,transferRequests.length);
        transferLog[txn.txnId] = txn;
        transferRequests.push(txn);
        emit ViewTransfer(txn.transmitter,txn.receiver,txn.amount,txn.approvalsCount,txn.txnId,limit);
       
    }
  1. The output of walletBalance() is quite confusing. How can I see my balance just like in remix? Also, can you elaborate on this output?
    walletBalance

  2. In the wallet.js, I wanted to utilize accounts array rather than hardcoding the addresses. I did try something but it doesnā€™t seem to work.
    export

Thanks,
Tanu

Hey @tanu_g

Logs

Consider this contract:

pragma solidity 0.8.0;

contract A {

  event testEvent (uint);

  function go () public {
    emit testEvent(10);
  }
}

Its migration:

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

module.exports = async function (deployer) {
  await deployer.deploy(A);
  const a = await A.deployed();
  const r = await a.go()
  console.log(r.logs[0].args)
};

r is the receipt, if you console.log it you will see it has a property called ā€œlogsā€, diving deep into that property leads you to the logs r.logs[0].args

Screenshot 2021-07-02 at 09.22.19

The output of walletBalance()

The result you see is a BigNumber: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

You can parseInt() your result or convert it to string to have a human readable number.

In the wallet.js, I wanted to utilize accounts array rather than hardcoding the addresses. I did try something but it doesnā€™t seem to work.

What is the error message you get?

Cheers,
Dani

Thanks, @dan-i for resolving my queries.

As you said, I did the following and it worked :smiley:
truffle(develop)> instance.walletBalance().then(balance => balance.toString())

Here:

Error:  *** Deployment Failed ***

"MultiSigWallet" -- invalid address (argument="address", value="d", code=INVALID_ARGUMENT, version=address/5.0.5) (argument=null, value="d", code=INVALID_ARGUMENT, version=abi/5.0.7).

    at C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\deployer\src\deployment.js:365:1
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at Migration._deploy (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:75:1)
    at Migration._load (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:61:1)
    at Migration.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:218:1)
    at Object.runMigrations (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:150:1)
    at Object.runFrom (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:110:1)
    at Object.runAll (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:114:1)
    at Object.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:79:1)
    at runMigrations (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:258:1)     
    at Object.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:223:1)        
    at Command.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\command.js:167:1)
UnhandledRejections detected
Promise {
  <rejected> Error: invalid address (argument="address", value="d", code=INVALID_ARGUMENT, version=address/5.0.5) (argument=null, value="d", code=INVALID_ARGUMENT, version=abi/5.0.7)
      at C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\deployer\src\deployment.js:335:1
      at processTicksAndRejections (internal/process/task_queues.js:93:5)
      at Migration._deploy (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:75:1)        
      at Migration._load (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:61:1)
      at Migration.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:218:1)
      at Object.runMigrations (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:150:1)        
      at Object.runFrom (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:110:1)
      at Object.runAll (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:114:1)
      at Object.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:79:1)
      at runMigrations (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:258:1)   
      at Object.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:223:1)      
      at Command.run (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\command.js:167:1) {
    reason: 'invalid address (argument="address", value="d", code=INVALID_ARGUMENT, version=address/5.0.5)',
    code: 'INVALID_ARGUMENT',
    argument: null,
    value: 'd',
    hijackedStack: 'Error: invalid address (argument="address", value="d", code=INVALID_ARGUMENT, version=address/5.0.5) (argument=null, value="d", code=INVALID_ARGUMENT, version=abi/5.0.7)\n' + 

Thanks

Hey guys, on the first migration video during my first ā€œmigrateā€ call I keep getting this

"ReferenceError: helloWorld is not defined"

ā€¦ while helloWorld is clearly the contract name of my .sol file ā€¦ can someone help? perhaps someone came across the same issue as well

  • also, i expected that weā€™d learn about ganache as well as truffleā€¦ is this still to come or not in smart contracts 201 course? :slight_smile:
2 Likes

Hey @KennethJP

Please share your contract and migration file.

Cheers,
Dani

truffle assignment question -

pragma solidity 0.8.6;
pragma abicoder v2;

// "SPDX-License-Identifier: <SPDX-License>"  "SPDX-License-Identifier: UNLICENSED" 
contract multiSigAssignment {
    address[] public owners;
    uint limit;
    
    struct Transfer{
        uint amount;
        address payable receiver;
        uint approvals;
        bool hasBeenSent;
        uint id;
    }
    
    event TransferRequestCreated(uint _id, uint _amount, address _initiator, address _receiver);
    event ApprovalReceived(uint _id, uint _approvals, address _approver);
    event TransferApproved(uint _id);

    Transfer[] transferRequests;
    
    mapping(address => mapping(uint => bool)) approvals;
    
    //Should only allow people in the owners list to continue the execution.
    modifier onlyOwners(){
        bool owner = false;
        for(uint i=0; i<owners.length;i++){
            if(owners[i] == msg.sender){
                owner = true;
            }
        }
        require(owner == true);
        _;
    }
    //Should initialize the owners list and the limit 
    constructor(address[] memory _owners, uint _limit) {
        owners = _owners;
        limit = _limit;
    }
    
    //Empty function
    function deposit() public payable {}
    
    //Create an instance of the Transfer struct and add it to the transferRequests array
    function createTransfer(uint _amount, address payable _receiver) public onlyOwners {
        emit TransferRequestCreated(transferRequests.length, _amount, msg.sender, _receiver);
        transferRequests.push(
            Transfer(_amount, _receiver, 0, false, transferRequests.length)
        );
        
    }
    
    //Set your approval for one of the transfer requests.
    //Need to update the Transfer object.
    //Need to update the mapping to record the approval for the msg.sender.
    //When the amount of approvals for a transfer has reached the limit, this function should send the transfer to the recipient.
    //An owner should not be able to vote twice.
    //An owner should not be able to vote on a tranfer request that has already been sent.
    function approve(uint _id) public onlyOwners {
        require(approvals[msg.sender][_id] == false);
        require(transferRequests[_id].hasBeenSent == false);
        
        approvals[msg.sender][_id] = true;
        transferRequests[_id].approvals++;
        
        emit ApprovalReceived(_id, transferRequests[_id].approvals, msg.sender);
        
        if(transferRequests[_id].approvals >= limit){
            transferRequests[_id].hasBeenSent = true;
            transferRequests[_id].receiver.transfer(transferRequests[_id].amount);
            emit TransferApproved(_id);
        }
    }
    
    //Should return all transfer requests
    function getTransferRequests() public view returns (Transfer[] memory){
        return transferRequests;
    }
    
    
}

Hi guys, regarding the truffle assignment - when i used the instance.deposit({value:1000)} - everything went smoothly, however I wanted to see what would happen if i created a transfer, so i did instance.createTransfer({value:500}, 0xe784A0aBE1DFAf65116b0eFA83dB4E59108E7524)

However this returned the following errorā€¦ What seems to be the issue?

Uncaught:
Error: invalid BigNumber value (argument="value", value={"value":500}, code=INVALID_ARGUMENT, version=bignumber/5.0.8)
    at evalmachine.<anonymous>:0:10
    at sigintHandlersWrap (vm.js:274:12)
    at Script.runInContext (vm.js:142:14)
    at runScript (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:270:1)
    at Console.interpret (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:285:1)
    at bound (domain.js:416:15)
    at REPLServer.runBound [as eval] (domain.js:427:12)
    at REPLServer.onLine (repl.js:819:10)
    at REPLServer.emit (events.js:375:28)
    at REPLServer.emit (domain.js:470:12)
    at REPLServer.Interface._onLine (readline.js:364:10)
    at REPLServer.Interface._line (readline.js:700:8)
    at REPLServer.Interface._ttyWrite (readline.js:1045:14)
    at REPLServer.self._ttyWrite (repl.js:912:9) {
  reason: 'invalid BigNumber value',
  code: 'INVALID_ARGUMENT',
  argument: 'value',
  value: { value: 500 },
  hijackedStack: 'Error: invalid BigNumber value (argument="value", value={"value":500}, code=INVALID_ARGUMENT, version=bignumber/5.0.8)\n' +
    '    at lib_esm_Logger.makeError (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/logger/lib.esm/index.js:166:1)\n' +
    '    at lib_esm_Logger.throwError (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/logger/lib.esm/index.js:175:1)\n' +
    '    at lib_esm_Logger.throwArgumentError (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/logger/lib.esm/index.js:178:1)\n' +
    '    at Function.from (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/bignumber/lib.esm/bignumber.js:211:22)\n' +
    '    at NumberCoder.encode (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib.esm/coders/number.js:13:17)\n' +
    '    at /usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib.esm/coders/array.js:57:1\n' +
    '    at Array.forEach (<anonymous>)\n' +
    '    at pack (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib.esm/coders/array.js:43:1)\n' +
    '    at TupleCoder.encode (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib.esm/coders/tuple.js:19:16)\n' +
    '    at AbiCoder.encode (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib.esm/abi-coder.js:82:1)\n' +
    '    at ABICoder.encodeParameters (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/lib/index.js:121:1)\n' +
    '    at /usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth/node_modules/web3-eth-contract/lib/index.js:439:1\n' +
    '    at Array.map (<anonymous>)\n' +
    '    at Object._encodeMethodABI (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth/node_modules/web3-eth-contract/lib/index.js:438:6)\n' +
    '    at /usr/local/lib/node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:182:1\n' +
    '    at runMicrotasks (<anonymous>)'

The createTransfer does not contain any payable keyword, hence, you cant use {value:500}, in any case try with the same command but instance.createTransfer(500, 0xe784A0aBE1DFAf65116b0eFA83dB4E59108E7524).

Let us know how it goes :slight_smile:

Carlos Z

1 Like

Hey @filip!

Just a heads up - in the Assignment - Truffle section, thereā€™s a broken link for the ā€˜video where we built the multisig walletā€™.
The broken link was: https://academy.ivanontech.com/products/ethereum-smart-contract-programming-101-2/categories/4224524

Updated link is: https://academy.ivanontech.com/topic/full-project-code

Cheers! :upside_down_face:

1 Like

Hey @jak, hope you are well.

Nice catch on the broken link, thanks to you for notifiy it! :nerd_face:

Please verify that the new link is working perfectly, thanks man.
https://academy.ivanontech.com/lessons/assignment-truffle

Carlos Z

1 Like

Yep that seems to be working!

Good one mate :innocent:

1 Like

hi,
i am using atom text editor and the cmd terminal.
when i run truffle in the cmd terminal and i get to truffle develop i cant do anything else, its like it gets blocked or glitchedā€¦image

@dan-i Iā€™m stuck. I copied the code from the assignment and created a new project with truffle init.
Link to code: https://github.com/filipmartinsson/solidity-0.7.5/blob/main/project-final-code.sol
Then I run:

truffle develop
truffle migrate
let i  = await Wallet.deployed()
i.createTransfer(1000, '0x775dC1F43e9fe77cd0591d2f6705b05084a1881F') // This is the last address from the accounts array
i.getTransferRequests() // I checked that the transfer was created
i.approve(0) // Here everything crashes

The error I get:

Uncaught Error: Returned error: VM Exception while processing transaction: revert
    at evalmachine.<anonymous>:0:3
    at sigintHandlersWrap (vm.js:273:12)
    at Script.runInContext (vm.js:140:14)
    at runScript (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:270:1)
    at Console.interpret (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:285:1)
    at bound (domain.js:416:15)
    at REPLServer.runBound [as eval] (domain.js:427:12)
    at REPLServer.onLine (repl.js:819:10)
    at REPLServer.emit (events.js:376:20)
    at REPLServer.emit (domain.js:470:12)
    at REPLServer.Interface._onLine (readline.js:342:10)
    at REPLServer.Interface._line (readline.js:671:8)
    at REPLServer.Interface._ttyWrite (readline.js:1015:14)
    at REPLServer.self._ttyWrite (repl.js:909:9) {
  data: {
    '0x46d8955d2d23330d73934fa36b6cafddd0990348914bfea87fa71ffa94e71290': { error: 'revert', program_counter: 2063, return: '0x' },
    stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
      '    at Function.RuntimeError.fromResults (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/ganache-core/lib/utils/runtimeerror.js:94:1)\n' +
      '    at BlockchainDouble.processBlock (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/ganache-core/lib/blockchain_double.js:627:1)\n' +
      '    at processTicksAndRejections (internal/process/task_queues.js:95:5)',
    name: 'RuntimeError'
  },
  hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
    '    at Object.ErrorResponse (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/lib/errors.js:28:1)\n' +
    '    at /usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-core-requestmanager/lib/index.js:303:1\n' +
    '    at /usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:107:1\n' +
    '    at XMLHttpRequest.request.onreadystatechange (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-providers-http/lib/index.js:98:1)\n' +
    '    at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)\n' +
    '    at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._setReadyState (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)\n' +
    '    at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._onHttpResponseEnd (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)\n' +
    '    at IncomingMessage.<anonymous> (/usr/local/Cellar/truffle/5.3.9/libexec/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)\n' +
    '    at IncomingMessage.emit (events.js:388:22)\n' +
    '    at IncomingMessage.emit (domain.js:532:15)\n' +
    '    at endReadableNT (internal/streams/readable.js:1336:12)\n' +
    '    at processTicksAndRejections (internal/process/task_queues.js:82:21)'
}

Wallet.sol

pragma solidity 0.7.5;
pragma abicoder v2;

contract Wallet {
    address[] public owners;
    uint limit;
    
    struct Transfer{
        uint amount;
        address payable receiver;
        uint approvals;
        bool hasBeenSent;
        uint id;
    }
    
    event TransferRequestCreated(uint _id, uint _amount, address _initiator, address _receiver);
    event ApprovalReceived(uint _id, uint _approvals, address _approver);
    event TransferApproved(uint _id);

    Transfer[] transferRequests;
    
    mapping(address => mapping(uint => bool)) approvals;

    modifier onlyOwners(){
        bool owner = false;
        for(uint i=0; i<owners.length;i++){
            if(owners[i] == msg.sender){
                owner = true;
            }
        }
        require(owner == true);
        _;
    }

    constructor(address[] memory _owners, uint _limit) {
        owners = _owners;
        limit = _limit;
    }
    
    function deposit() public payable {}
    
    function createTransfer(uint _amount, address payable _receiver) public onlyOwners {
        emit TransferRequestCreated(transferRequests.length, _amount, msg.sender, _receiver);
        transferRequests.push(
            Transfer(_amount, _receiver, 0, false, transferRequests.length)
        );
        
    }
    
    function approve(uint _id) public onlyOwners {
        require(approvals[msg.sender][_id] == false);
        require(transferRequests[_id].hasBeenSent == false);
        
        approvals[msg.sender][_id] = true;
        transferRequests[_id].approvals++;
        
        emit ApprovalReceived(_id, transferRequests[_id].approvals, msg.sender);
        
        if(transferRequests[_id].approvals >= limit){
            transferRequests[_id].hasBeenSent = true;
            transferRequests[_id].receiver.transfer(transferRequests[_id].amount); // Code fails here
            emit TransferApproved(_id);
        }
    }
    
    //Should return all transfer requests
    function getTransferRequests() public view returns (Transfer[] memory){
        return transferRequests;
    }
}

1_wallet.js

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

module.exports = function (deployer, network, accounts) {
  deployer.deploy(Wallet, accounts, 1);
};

try using truffle --reset

Hi - I am able to compile the helloworld contract with truffle in visual studio, but it still shows an error under the problems tab saying there is an issue with the compiler version. Been trying to fix this on my own for a while now, but need some help. Thanks! @dan-i

Capture

Capture1

i cant, it is stuck like if its loading. i left it overnight and it is still the same.
the only way to use the terminal again its by closing it and reopeningā€¦
i do everything again but when I put ā€œtruffle developā€ it gets stuck againā€¦
i even tryed using the terminal on atom but that does the same.
i am going to try and install windows studio text editor and do it that way like in the video, lets see.
image

Hey @Zaqoy

You can check this faq to change the compiler version: FAQ - How do change truffle version

Cheers,
Dani