Solidity Basics

Hi @Kkrypto,

There are 4 function types (3 of which we define with specific keywords in the function header) as follows:

  1. pure (most restrictive)
    Cannot change or read the contract state.
  2. view
    Can read the contract state, but cannot change it.
  3. undefined (no type declared in the function header)
    Can read and change the contract state (but cannot receive ether)
  4. payable (least restrictive)
    Can read and change the contract state, and can also receive ether.
    (Note: a function doesn’t need to be payable to send ether — only to receive it)

It is good risk management to always restrict what a function is allowed to do, to only what it needs to do…

// LINE 7

function getNumber() public view returns(int) {
    return number;
}

This is a getter. It only needs to read data stored in the contract state (the integer stored in the state variable number ) and return it to the caller. It doesn’t need to modify the contract state. So, we should define it as a view function by adding view to the function header.

// LINE 10

function setNumber(int _number) public {
    number = _number;
}

In contrast, this is a setter. It needs to modify data stored in the contract state (assign the integer input into the function to the state variable number ). To ensure that it can modify the contract state, but cannot receive any ether, we leave its function type undefined i.e. we do not need to add anything extra to the function header.

Let me know if anything is still unclear, or if you have any further questions :slight_smile:

Hi @jon_m - appreciate the reply. So I understand that memory is temporary, however there are many lines of code that Filip has shown that does not use data locations. So in those cases, how is anything stored?

1 Like

Thanks again Jon - I should have been a bit clearer. I have notes on view and pure and I understand that view does not change statement. But I see “view” used on line 7, but why is it not used on line 10?

1 Like

Hi @Kkrypto

ALL values have a data location…

… but we only need to explicitly declare the data location in certain specific cases: when more than one data location is possible, or where the syntax requires it. In all other cases the data location is determined by default (i.e. without having to add a data location keyword). Until you have covered the material in the Data Location section, which covers all of these aspects, I would just accept that the syntax requires us to add the keyword memory when we define string parameters, local string variables, and returned strings values; but not when we define a string state variable. Then, after having worked through the videos and assignment for the Data Location section, if you still have questions, I would have a good read of the posts, replies, solutions, feedback and comments in the forum discussion threads for that section, where you will find a lot of useful information which should help to fill in any gaps, and to go a bit deeper than what is covered in the videos. And after that, if you still have questions about the topic, post them there :slight_smile:

No, you were perfectly clear :slight_smile: I set out all 4 function types, because you need to understand the 3 types that require a keyword (pure, view and payable) before you can understand why not adding a keyword for function type results in a default type:

I also explained how this undefined type is the resaon why no function type keyword is added to your “line 10” function header:

To summarise…

Function in line 7 needs to read the contract state but not modify it. Therefore the access this function has to the contract state should be restricted to view.

Function in line 10 does need to modify the contract state. This is the default type of access granted to the contract state i.e. when no function type keyword is added to the function header, and the function type is left undefined.

This makes sense, thank you.

1 Like

Thanks Jon! You’re right!!
Yes, everything is good now. I’m 40% through the course at this point.
Cheers!
Douglas

1 Like

Hi,

The quiz question ‘Is it possible to find all values entered into a mapping in solidity?’ why is the answer to this no? surely there is a way to read the keyset? Any ideas on this?
Thanks

1 Like

Hello Filip,
You are a great instructor!
Im trying to do the transfer bank exercise but it throws me an error when i add the address, it says is invalid, i tried with 3 different addresses from remix.

transact to bank.transfer errored: Error encoding arguments: Error: invalid address (argument=“address”, value=“0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2 50”, code=INVALID_ARGUMENT, version=address/5.1.0) (argument=null, value=“0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2 50”, code=INVALID_ARGUMENT, version=abi/5.1.2)

any idea of what could be possibly happening?

1 Like

i just changed it with and without the private function “_transfer” and still tells me the address is an invalid argument.

Hi, you’re missing the comma after the address! Put the comma in and then leave a space before 50. That should do it!

1 Like

Hi @Eduardo_Carrillo,

Have you managed to get this working now, by following @Random’s advice?

Hi @Random,

I think you will find this post helpful.

Hi i’m trying to return an retire people array instead of individual with the index please let me know where i went wrong with the code and even if it’s possible?

pragma solidity 0.7.5;
contract classes{
struct Person{
uint age;
string name;
}
Person[]people;
function addPerson(uint _age, string memory _name) public{

 Person  memory newPerson= Person(_age, _name);
  people.push(newPerson);
  
 }
  function getPerson() public view returns (uint [] memory, string [] memory){

     
     return people;
  }

}

1 Like

Hi @jahh,

people  is an array of People struct instances, and so if you return the entire people array you need to define its data type in the function header as follows:

Person[] memory

You are not returning two separate arrays (one of integers and another of strings). The integers and strings are property values within each instance stored in a single array. We could visually represent this as follows:

// Data stored in the people array for 3 people:
[{age: 25, name: "Bob"}, {age: 43, name: "Alice"}, {age: 67, "Carol"}]

To be able to return arrays of strings or struct instances using Solidity v0.7, we need to override this version’s standard ABI coder by activating ABI coder v2. We do this by adding the following line of code at the top of our file:

pragma abicoder v2;

However, ABI coder v2 is activated by default from Solidity v.0.8, so if you change…

to

pragma solidity 0.8.4;

… you can return the array of struct instances without having to add the extra line of code to activate ABI coder v2.

Let me know if you have any further questions :slight_smile:

Thanks Jon , i’m gonna give this a go again

1 Like

Can someone tell me what is SPDX-License-Identifier and when should I use it?
In OpenZeppelin libraries they have SPDX-License-Identifier: MIT, do I have to put it on my contract too?

1 Like

Hi @taodai,

Since Solidity v0.6.8 the compiler issues a warning when you don’t include a comment at the top of each file stating what software license you are making your code available under. This is a warning and not an error, and so does not prevent the code from actually compiling.

Here is a link to the documentation with more details, and where you will find further links if you want to know more about what the actual SPDX identifier is and how it relates to the license type. From what I can gather it’s a format used to standardise how the file’s license type is compiled into the bytecode metadata.

https://docs.soliditylang.org/en/v0.7.5/layout-of-source-files.html#layout-of-a-solidity-source-file

If you aren’t publishing your code (e.g. your code for this course), then I think it’s fairly safe to assume that it’s not necessary to include. However, it is annoying! All of the other warnings are useful, because they give you important information about how your code should be modified before deployment. So what I do is just put…

// SPDX-License-Identifier: UNLICENSED

… at the top of each of my files, just to get rid of the annoying warning. That way, I know that if I do get a warning, it’s actually for something that I want to check.

OpenZeppelin have published their smart contract libraries (or at least some of them) under the open-source MIT license. This is a very common one used for open-source software, so you could use that identifier if you want. The “UNLICENSED” identifier means that it isn’t open source. I’m no expert on software licenses, but I’m pretty sure it doesn’t really matter which identifier you put if you’re not going to publish or make your code available.

Just let me know if you have any further questions :slight_smile:

1 Like

Ok, so if I want to use OpenZeppelin contracts for my ERC20 token and I want to deploy it, do i have to use the MIT license and specify the creator of the contracts?

1 Like

Hi @taodai

** DISCLAIMER - the following information is for educational purposes, and is not legal advice **

The OpenZeppelin Contracts library already comes with the MIT SPDX License Identifier at the top of each of their files. If you read their MIT license in their GitHub repository (link below — it’s only a very short license) you will see that the requirements for including their contracts in your own project are to include a copy of their MIT license and their copyright notice. The MIT license doesn’t require you to make your own code available under the same MIT license. Your license can be different, although the MIT license is a common one used for open-source software.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/LICENSE

With the MIT license you can usually just include a link to their license (which also includes the creator’s specific copyright notice), for example, a link to their license in their GitHub repository. Some licenses are also included in the actual file, or the link to the license provided there. This all really depends on the requirements of each type of license. The license page in a GitHub repository also has a link to more information about repository licenses.

If you install the OpenZeppelin Contracts library using npm (following the instructions in their README) it will include their README file which should include a link to their license.