Solidity Basics for JavaScript Devs Part 2
Tags: solidity, javascript, web3
Published: 2021-11-01 14:20:11

---
title: Solidity Basics for JavaScript Devs Part 2
published: true
series: Solidity for JavaScript Devs
tags: solidity, javascript, web3
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oehay5ebwz270ixsz036.jpg
--- 

After [my first article about Solidity basics for JavaScript devs](https://dev.to/fllstck/solidity-basics-for-javascript-devs-57c) got so much attention, I'm writing a second one!

I'm currently working through [a beginner smart contract development book](https://www.amazon.com/Hands-Contract-Development-Solidity-Ethereum/dp/1492045268), and now I'm doing the main project, a DApp fundraiser.

The book is written for Truffle, web3.js, and JavaScript, and I replaced the tools with [Hardhat](https://hardhat.org/), [Ethers.js](https://docs.ethers.io/v5/), and TypeScript to spice things up a bit.

Here are my last findings that threw me off a bit, so I think they might be interesting for newcomers!

## Solidity Events are for the Frontend

Solidity has an event construct/type. It allows you to define specific events for your smart contract that can emit when things you deem interesting.

```solidity
event MyEvent( uint256 value1, uint256 value2);

function f() public {
  emit MyEvent(123, 456);
}
```

Interesting for whom? For your frontend code!

If I understood it correctly, event data would be stored in the blockchain, but it isn't accessible within smart contracts.

Event data is for listeners from outside the blockchain. 

Your frontend can add event listeners for these events, and then, when it starts a transaction, these events will be emitted, and you can do things in the frontend. 

```javascript
smartContract.on("MyEvent", (valueA, valueB) => {
  console.log(valueA, valueB);
})

await smartContract.f();
```

## Ethers.js Uses `BigNumber` Instead of `BigInt`

Solidity usually has to handle huge integers, too big for the `Number` type of JavaScript. That's why Ethers.js created their type, called `BigNumber`, to get around this problem.

Today, modern JavaScript engines all have a `BigInt` type that can handle such values no problem, but this wasn't always the case, and Ethers.js wanted to be backward compatible.

I don't know why they didn't use a `BigInt` polyfill instead, but at least they offer a method `toBigInt()`. But you have to use `BigNumber` methods for calculations!

```javascript
const value1 = ethers.utils.parseEther("1")
const value2 = ethers.utils.parseEther("2")

const result = value1.add(value2)

console.log(result.toBigInt())
```

Anyway, don't mistake `BigNumber` for `BigInt` or you'll have a bad time!

## Setting the `msg` Object from Ether.js

There are some global variables inside your Solidity smart contract generated automatically before your function is called. 

One of them is called `msg`, and it contains data that isn't explicitly passed via function arguments, like `msg.sender` for the address that called the function or `msg.value` for the amount of Ether that was sent with the function call.

```solidity
function f(uint256 arg1, uint256 arg2) public payable {
  // These are obviously arguments
  uint256 a = arg1 + arg2;

  // But where do these come from?
  address x = msg.sender; 
  uint256 y = msg.value;
}
```

As this data isn't a function argument, how do you pass it to the smart contract from the Ethers.js side?

An overrides object is passed as the last argument to such a (payable) function, after all the regular arguments. Other values, like `msg.sender` are implicitly set on the smart contract side of things.

```javascript
const overrides = {value: 123}
await smartContract.payableFunction(arg1, arg2, overrides)
```
## Multiple returns will become an Array in Ethers.js

Solidity allows returning multiple values from one function.

```solidity
function f() public returns(uint256 a, uint256 b) {
  return (123, 456);
}
```

I saw some examples, seemingly for web3.js, that would use an object as a return value on the JavaScript side.

```javascript
const {a, b} = await smartContract.f();
```

This didn't work for me; I used an array to extract the return values depending on their position.

```javascript
const [a, b] = await smartContract.f();
```

## Using Waffle with Chai for Tests

The book I'm reading used low-level assertions with some try-catch constructs to test smart contract-specific behavior. I guess Waffle wasn't a thing back then.

To test events, you can use an asynchronous call to `expect`.

```javascript
it("emits", async () => {
  await expect(smartContract.f()).to.emit("EventType")
})
```

You can use an asynchronous call to `expect` with `reverted` to test that your contract reverts correctly.

```javascript
it("emits", async () => {
  await expect(smartContract.f()).to.be.revertedWith("Error Message")
})
```

## Summary

Web3 is an interesting topic, and Solidity is certainly a different language than I expected. It's simple in the sense that JavaScript is simple, but the devil lies in the detail. 

I hope I could clear some things up for you.