# How to create a Donation Contract | Solidity Tutorial #### Things you can create:

You can use the app from this link. Please install Metamask and choose Goerli Network before using it.

Unfortunately, the code above is a little bit confusing because I use many JavaScript to sort data on Front End.

To make this tutorial simple, we are going to create a very basic app like this: It looks like boring, but you can create a complicated one after studying the basic one. So let's begin.

• 1. Create a Donation Contract
• 1-1. Struct
• 1-2. Mapping
• 1-3. function public payable
• 2. Create a Front End with JS
• 2-1. Basic HTML
• 2-2. Enable web3.js
• 2-3. Load from Smart contract
• 2-4. Read from Smart contract
• 2-5. Write to Smart contract

## 1. Create a Donation Contract

All the code of donation contract is below:

There are three points you should learn.

• (1) Struct
• (2) Mapping
• (3) Payable

So let's dig in one by one.

### (1) Struct

You can define your type by creating a Struct.

For example, if you want to keep track of your books in a library, you might want to track the followings:

• Title
• Author
• Book ID

In this case, you can use `Struct` as follows:

```struct Book {
string title;
string author;
uint book_id;
}
```

It's easy, right? So this time, we want to create a Donation Contract, so we need to write a code like this:

```struct Person {
uint id; // Donor's ID
string name; // Donor's name
uint256 amount; // Donor's amount of a donation
}
```

After that, we set the default value as zero like so:

`uint256 id = 0;`

Okay. Let's move to the next step.

### (2) Mapping

`Mapping` is a reference type as arrays and structs. You can use it like this:

```mapping ( A => B ) public mappingName
```

For example, we can use it like so:

```contract MyContract {

// Define the data
constructor() {
names = "Jon";
names = "Sara";
names = "Paul";
}

// Mapping the data
mapping ( uint => string ) public names;
}
```

If we deploy the code above, we can get the function like so: You can see `names function` in the red box and call stored data. For example, if we put "101", then get the name "Jon."

This time, we will create a donation contract. So the `mapping` is like so:

`mapping ( uint => Person ) public people;`

Using the code above, we can get data like the below:

• 1. Jon
• 2. Bob
• 3. Alice

Needless to say, we don't have data right now. So, in order to get the data like above, we need to create a function named `addPerson`.

#### How to add data to the blockchain

We can add a new person to the blockchain using the code below.

```function addPerson(string name) public {
id += 1;
people[id] = Person(id, name, msg.value, msg.sender);
}
```

I will briefly explain the code above.

You can see the word `public`, which means everyone can use this function. There are four types of function types.

• `public` can be used when contract was deployed, can be used in inherited contract
• `external` can be used when contract was deployed , can NOT be used in inherited contract
• `internal` can NOT be used when contract was deployed , can be used in inherited contract
• `private` can NOT be used when contract was deployed, can NOT be used in inherited contract

You can choose it case by case. Proceeding further, you can see the followings:

• `msg.value` is the ammount of ether sent.
• `msg.sender` is the address that has called a function.

#### Meaning of Memory

Actually, there is a mistake in the code above. The correct one is below:

```function addPerson(string memory name) public payable {
id += 1;
people[id] = Person(id, name, msg.value, msg.sender);
}
```

You can see the word `memory`. So what's the heck of this? There are two types of keywords:

• string `memory` name
• string `storage` name

The difference is like so:

• `Memory` in Solidity is a temporary place to store data.
• `Storage` holds data between function calls.

This time, we use `memory` because we want to reset the `string name` whenever we use the `addPerson` function. Therefore, if we use a `storage`, the name stored in the blockchain will always be the same.

### (3) Payable

Lastly, please take a look at below:

• function addPerson(string memory name) public {
• function addPerson(string memory name) public `payable`

We can see the word `payable`. Functions declared `payable` can receive ether into the contract.

This time, we want to store donors' data and the amount paid, right? So we need to declare `payable` to receive ETH from donors.

Okay, that's it for the donation contract. Let's move to the Front End part. It's more fun.

## Create a Front End with JS

All of the Front End code is below:

It's basic HTML and JavaScript. Five things you have to learn:

• (1) Basic HTML
• (2) Enable web3.js
• (3) Load from Smart contract
• (4) Read from Smart contract
• (5) Write to Smart contract

### (1) Basic HTML The HTML is straightforward. Don't forget to read web3.js in the section.

`<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>`

The code below will show three donators.

```<h3>Donaters</h3>
```

If you want to show more, you can use a code like so:

```<?php for (\$i=1; \$i <= 10 ; \$i++) { ?>
<span id="people<?php echo \$i; ?>"></span>
<span id="price<?php echo \$i; ?>"></span>
<?php } ?>
```

### Enable web3.js

Using the code below, you can enable web3.js.

Using the code below, you can load the smart contract.

```// Load Contract
return await new window.web3.eth.Contract(
}
```

#### The meaning of ABI

ABI is Application Binary Interface, which interacts with contracts in the Ethereum ecosystem, both from outside the blockchain and contract-to-contract interaction.  Attention: Please choose `Injected Web3` when you deploy your contract so that we can interact with it using web3js. #### How to get your Contract Address You can get your contract address from Remix. ### Read from Smart contract Using the code below, you can read the data from the smart contract.
```// Read data from the contract
async function getFunction() {

// Read data of the first donor.
get1 = await window.contract.methods.people(1).call();
document.getElementById('people1').innerHTML = get;
document.getElementById('price1').innerHTML = get;
}
```

The important thing is here:

`window.contract.methods.people(1).call()`

`window.contract.methods.`methodName()`.call()`

When you look at your ABI, you can see the method below:

```{
"inputs": [{ ... }],
"name": "people",
"outputs": [{ ... }],
"stateMutability": "view",
"type": "function"
}
```

This time, the function's name is `people` so that we can use it like so:

`window.contract.methods.people().call()`

But we need an argument, so do it like this:

`window.contract.methods.people(1).call()`

If you want to read the data more, you can do it like so:

```// Read data from the contract
async function getFunction() {

// Read data of the first donor.
get1 = await window.contract.methods.people(1).call();
document.getElementById('people1').innerHTML = get;
document.getElementById('price1').innerHTML = get;

// Read data of the second donor.
get2 = await window.contract.methods.people(2).call();
document.getElementById('people2').innerHTML = get;
document.getElementById('price3').innerHTML = get;

// Read data of the third donor.
get3 = await window.contract.methods.people(3).call();
document.getElementById('people3').innerHTML = get;
document.getElementById('price3').innerHTML = get;
}
```

But obviously, the code is not clean. You can make it simple like so:

```// Read data from the contract
async function getFunction() {
for (let i = 1; i <= 100; i++) {
get = await window.contract.methods.people(i).call();
document.getElementById('people' +i).innerHTML = get;
document.getElementById('price' +i).innerHTML = get;
}
}
```

Looks much better, but we still have a problem because the code above will continue until `i` becomes 100, even though we only have a fewer donors.

To solve the problem, we can do like this:

```// Read data from the contract
async function getFunction() {
for (let i = 1; i <= 100; i++) {
get = await window.contract.methods.people(i).call();
if ( get != 0 ){ // Continue for a loop until the ID is not equal to 0.
document.getElementById('people' +i).innerHTML = get;
document.getElementById('price' +i).innerHTML = get;
} else break;
}
}
```

The code above will stop their loop if the donor's ID becomes 0, which means there are no donors more than that. If the code looks complicated, you can test it like so:

```// Read data from the contract
async function getFunction() {
for (let i = 1; i <= 100; i++) {
get = await window.contract.methods.people(i).call();
console.log(get);
if ( get != 0 ){ // Continue for a loop until the ID is not equal to 0.
document.getElementById('people' +i).innerHTML = get;
document.getElementById('price' +i).innerHTML = get;
} else break;
}
}
```

When you open the console of your browser, you can see as follows: `get/1000000000000000000; // Change wei to ETH`

We need it because the amount read from the contract is Wei, the smallest denomination of ether. So we can multiply it 1000000000000000000 times, which will become ETH.

### Write to Smart contract

All the code is below:

```// Donate function
async function donateFunction() {

// Get the name from input box
\$name = document.getElementById('your_name').value;

// Get the amount from input box
\$wei = document.getElementById('your_eth').value;

// Change wei to ETH
\$eth = \$wei * 1000000000000000000;

\$account = await getAccount();

// Write to Smart Contract
{
from: \$account,
value: \$eth
}
);
}
```

The important thing is below:

```await window.contract.methods.addPerson(\$name).send(
{
from: \$account,
value: \$eth
}
);
```

Let me explain them one by one.

#### How to use `.send()` method

When we want to read from the smart contract, we use the `.call()` method.

On the other hand, we use the `.send()` method to write some data to the blockchain. We use it like so:

```window.contract.methods.methodName(value).send(
{
from: account
}
);
```

This time, we want to input the data of name, address, and amount of ETH sent. Please take a look at ABI below:

```{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
}
],
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
```

We can see the word `inputs`, which says the name is "name." So the code should be like this:

```window.contract.methods.addPerson(\$name).send(
{
from: \$account,
value: \$eth
}
);
```

We input the argument of `\$name` and also \$account and \$eth. If you want to define gas data, you can do it like so:

```window.contract.methods.addPerson(\$name).send(
{
from: \$account,
value: \$eth.
gas: 1500000,
}
);
```

For more detail of how to use `.send()`, please visit web3.eth.Contract. Okay, that's all for the explanation. I hope this article helps many people.