<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Catch The Block]]></title><description><![CDATA[Blockchain, Tech, and IoT]]></description><link>https://catchtheblock.com/</link><image><url>https://catchtheblock.com/favicon.png</url><title>Catch The Block</title><link>https://catchtheblock.com/</link></image><generator>Ghost 5.3</generator><lastBuildDate>Sat, 03 Jan 2026 17:00:16 GMT</lastBuildDate><atom:link href="https://catchtheblock.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[🔐 How to reset a forgotten password on Kali Linux?]]></title><description><![CDATA[In 3 easy steps, you will reset your Kali Linux root password.]]></description><link>https://catchtheblock.com/how-to-reset-forgotten-password-on-kali-linux/</link><guid isPermaLink="false">6433c8b6af8f4f00015866e7</guid><category><![CDATA[kali]]></category><category><![CDATA[linux]]></category><category><![CDATA[password]]></category><category><![CDATA[root]]></category><category><![CDATA[forgot]]></category><category><![CDATA[reset]]></category><category><![CDATA[tech]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Mon, 10 Apr 2023 08:54:09 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2023/04/kali-bright.webp" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2023/04/kali-bright.webp" alt="&#x1F510; How to reset a forgotten password on Kali Linux?"><p><strong>You forgot your Kali Linux password, and you cannot log in anymore? No worries, in this blog post, we&apos;ll walk you through a step-by-step guide on how to reset your forgotten password on Kali Linux, so you can regain access to your system in no time. So, grab a cup of coffee and let&apos;s get started!</strong></p><p><strong>3 steps</strong></p><ul><li><strong>Step 1 - Reboot into GRUB boot menu</strong></li><li><strong>Step 2 - Edit the booting instructions</strong></li><li><strong>Step 3 - Change password</strong></li></ul><h2 id="step-1%F0%9F%8E%AC-reboot-into-grub-boot-menu">Step 1 - &#x1F3AC; Reboot into GRUB boot menu</h2><p>When the below screen is displayed, press &quot;e&quot; key to edit this boot menu.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.32.56.png" class="kg-image" alt="&#x1F510; How to reset a forgotten password on Kali Linux?" loading="lazy" width="1392" height="889" srcset="https://catchtheblock.com/content/images/size/w600/2023/04/Capture-d-e-cran-2023-04-10-a--10.32.56.png 600w, https://catchtheblock.com/content/images/size/w1000/2023/04/Capture-d-e-cran-2023-04-10-a--10.32.56.png 1000w, https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.32.56.png 1392w" sizes="(min-width: 720px) 720px"><figcaption>Kali Linux GRUB Boot menu (I&apos;m using a Proxmox VM in this case)</figcaption></figure><h2 id="step-2%E2%9C%8F%EF%B8%8F-edit-the-booting-instructions">Step 2 - &#x270F;&#xFE0F; Edit the booting instructions</h2><p>Now that we can edit the boot menu, let&apos;s make some changes. In a few words, this menu tells the machine what to boot and how to boot it. We will make some modifications to boot with bash command.</p><p>Find the line starting with &quot;linux&quot;, and:</p><ol><li>Replace &quot;<em>ro</em>&quot; by &quot;<em>rw</em>&quot; (i.e. read-only mode is replaced by read-write mode)</li><li>Add the end of the line, add: &quot;<em>init=/bin/bash</em>&quot;</li></ol><p>So, you should start with:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.33.29-1.png" class="kg-image" alt="&#x1F510; How to reset a forgotten password on Kali Linux?" loading="lazy" width="1392" height="889" srcset="https://catchtheblock.com/content/images/size/w600/2023/04/Capture-d-e-cran-2023-04-10-a--10.33.29-1.png 600w, https://catchtheblock.com/content/images/size/w1000/2023/04/Capture-d-e-cran-2023-04-10-a--10.33.29-1.png 1000w, https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.33.29-1.png 1392w" sizes="(min-width: 720px) 720px"><figcaption>INITIAL - GRUB Boot instructions</figcaption></figure><p>And end with:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.41.36.png" class="kg-image" alt="&#x1F510; How to reset a forgotten password on Kali Linux?" loading="lazy" width="1392" height="889" srcset="https://catchtheblock.com/content/images/size/w600/2023/04/Capture-d-e-cran-2023-04-10-a--10.41.36.png 600w, https://catchtheblock.com/content/images/size/w1000/2023/04/Capture-d-e-cran-2023-04-10-a--10.41.36.png 1000w, https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.41.36.png 1392w" sizes="(min-width: 720px) 720px"><figcaption>NEW - GRUB Boot instructions</figcaption></figure><p>Once changes done, press: &quot;CTRL+X&quot;</p><p>It should reboot with bash command.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.43.png" class="kg-image" alt="&#x1F510; How to reset a forgotten password on Kali Linux?" loading="lazy" width="1392" height="889" srcset="https://catchtheblock.com/content/images/size/w600/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.43.png 600w, https://catchtheblock.com/content/images/size/w1000/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.43.png 1000w, https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.43.png 1392w" sizes="(min-width: 720px) 720px"></figure><h2 id="step-3%F0%9F%94%90-change-password">Step 3 - &#x1F510; Change password</h2><p>You should see the following screen after booting:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.53.png" class="kg-image" alt="&#x1F510; How to reset a forgotten password on Kali Linux?" loading="lazy" width="1392" height="969" srcset="https://catchtheblock.com/content/images/size/w600/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.53.png 600w, https://catchtheblock.com/content/images/size/w1000/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.53.png 1000w, https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.43.53.png 1392w" sizes="(min-width: 720px) 720px"><figcaption>Kali Linux Booting in Bash Mode</figcaption></figure><p>Now, type: &quot;passwd&quot;</p><p>(If you need to change password for a specific user, you can add the username after passwd, like: &quot;passwd username&quot;).</p><p>The prompt will ask you to define the new password, and to confirm it.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.45.34.png" class="kg-image" alt="&#x1F510; How to reset a forgotten password on Kali Linux?" loading="lazy" width="1392" height="969" srcset="https://catchtheblock.com/content/images/size/w600/2023/04/Capture-d-e-cran-2023-04-10-a--10.45.34.png 600w, https://catchtheblock.com/content/images/size/w1000/2023/04/Capture-d-e-cran-2023-04-10-a--10.45.34.png 1000w, https://catchtheblock.com/content/images/2023/04/Capture-d-e-cran-2023-04-10-a--10.45.34.png 1392w" sizes="(min-width: 720px) 720px"></figure><p>Once done, you can reboot, and you are all set. </p><p>Congrats &#x1F973; .</p>]]></content:encoded></item><item><title><![CDATA[💾 How to add an external USB drive to Proxmox?]]></title><description><![CDATA[<h2 id="introduction">Introduction</h2><p>In this short tutorial, we will see how to add an external USB drive to Proxmox Virtual Environment 7.3-3 .</p><p>We will assume the Proxmox environment is installed and well configured.</p><p>Here are the steps we will go through:</p><ol><li>&#x1F50C; Plug the USB disk in the machine</li><li>&#x1F5FB; Create</li></ol>]]></description><link>https://catchtheblock.com/how-to-add-an-usb-disk-to-proxmox-host/</link><guid isPermaLink="false">63aa8bef948edf0001a0d79a</guid><category><![CDATA[proxmox]]></category><category><![CDATA[usb]]></category><category><![CDATA[drive]]></category><category><![CDATA[hard disk]]></category><category><![CDATA[fstab]]></category><category><![CDATA[backup]]></category><category><![CDATA[mount]]></category><category><![CDATA[debian]]></category><category><![CDATA[lsblk]]></category><category><![CDATA[blkid]]></category><category><![CDATA[proxmox 7.3-3]]></category><category><![CDATA[pve7.3-3]]></category><category><![CDATA[tech]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Fri, 30 Dec 2022 15:18:04 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2022/12/addusbdisktoproxmox-1.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><img src="https://catchtheblock.com/content/images/2022/12/addusbdisktoproxmox-1.png" alt="&#x1F4BE; How to add an external USB drive to Proxmox?"><p>In this short tutorial, we will see how to add an external USB drive to Proxmox Virtual Environment 7.3-3 .</p><p>We will assume the Proxmox environment is installed and well configured.</p><p>Here are the steps we will go through:</p><ol><li>&#x1F50C; Plug the USB disk in the machine</li><li>&#x1F5FB; Create a mount point</li><li>&#x1F9FD; Format the USB disk</li><li>&#x1F6E0;&#xFE0F; Configure fstab</li><li>&#x2728; Reboot</li></ol><p>You will see how easy it is, let&apos;s go!</p><h2 id="%F0%9F%94%8C-step-1plug-the-usb-disk-in-the-machine">&#x1F50C; Step 1 - Plug the USB disk in the machine</h2><p>I think we can skip this one :-).</p><h2 id="%F0%9F%97%BB-step-2create-a-mount-point">&#x1F5FB; Step 2 - Create a mount point</h2><p>Now that our USB disk has been plugged, we need to create a mount point in our Proxmox VE, using the Shell.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/12/image.png" class="kg-image" alt="&#x1F4BE; How to add an external USB drive to Proxmox?" loading="lazy" width="1441" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2022/12/image.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/12/image.png 1000w, https://catchtheblock.com/content/images/2022/12/image.png 1441w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox VE 7.3-3 - Shell</figcaption></figure><p>Let&apos;s create the following directory in the /media directory:</p><pre><code>cd /media
mkdir -p henri/EXT_DISK_2T</code></pre><p>In my case, I&apos;m using a 2To USB disk, but you are free to use the one you want.</p><ul><li>&quot;<strong><em>mkdir -p</em></strong>&quot; is used to create multiple subdirectories using &quot;<strong><em>mkdir</em></strong>&quot;. It makes sure that &quot;<strong><em>mkdir</em></strong>&quot; adds any missing parent directories in the process.</li><li>Replace the name of the directory as you want, of course &#x1F603;.</li></ul><h2 id="%F0%9F%A7%BD-step-3format-the-usb-disk">&#x1F9FD; Step 3 - Format the USB disk</h2><p>Now that we created a mounting point, we need to format our disk properly. In this case, we will use the &quot;<strong><em>exfat</em></strong>&quot; type. You are free to use the type you want.</p><p>Before formatting, make sure you identified the right disk (!). To check this, let&apos;s run the command: </p><p></p><figure class="kg-card kg-code-card"><pre><code class="language-shell">fdisk -l</code></pre><figcaption>fdisk -l command is used to list all the disks</figcaption></figure><p>You should see something similar to:</p><pre><code class="language-shell">root@pve:/media/henri# fdisk -l
Disk /dev/sda: 465.76 GiB, 500107862016 bytes, 976773168 sectors
Disk model: Samsung SSD 870 
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 598755F6-ED7D-429A-9E22-7585CD559E5F

Device       Start       End   Sectors   Size Type
/dev/sda1       34      2047      2014  1007K BIOS boot
/dev/sda2     2048   1050623   1048576   512M EFI System
/dev/sda3  1050624 976773134 975722511 465.3G Linux LVM


Disk /dev/mapper/pve-swap: 7.67 GiB, 8237613056 bytes, 16089088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/mapper/pve-root: 96 GiB, 103079215104 bytes, 201326592 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/mapper/pve-vm--101--disk--0: 32 GiB, 34359738368 bytes, 67108864 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 65536 bytes / 65536 bytes
Disklabel type: dos
Disk identifier: 0xdc483fa1

Device                                 Boot    Start      End  Sectors  Size Id Type
/dev/mapper/pve-vm--101--disk--0-part1 *        2048 65107967 65105920   31G 83 Linux
/dev/mapper/pve-vm--101--disk--0-part2      65110014 67106815  1996802  975M  5 Extended
/dev/mapper/pve-vm--101--disk--0-part5      65110016 67106815  1996800  975M 82 Linux swap / Solar

Partition 2 does not start on physical sector boundary.


Disk /dev/mapper/pve-vm--100--disk--0: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 65536 bytes / 65536 bytes
Disklabel type: gpt
Disk identifier: 0ED5CE97-B11F-464C-A0E0-D44BA3FA3D5A

Device                                   Start       End   Sectors Size Type
/dev/mapper/pve-vm--100--disk--0-part1    2048      4095      2048   1M BIOS boot
/dev/mapper/pve-vm--100--disk--0-part2    4096   4198399   4194304   2G Linux filesystem
/dev/mapper/pve-vm--100--disk--0-part3 4198400 209713151 205514752  98G Linux filesystem


Disk /dev/sdb: 1.82 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: 2235            
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes</code></pre><p>As we can see here, we already have a disk <strong><em>sda</em></strong> with 3 partiti<strong><em>ons sda1, sda2, </em></strong>and<strong><em> sda3</em></strong>. Be careful not formatting this one, which is the root disk hosting Proxmox... </p><p>In our case, the plugged USB disk is called <strong><em>sdb</em></strong> (1.82 TiB).</p><p>To format <strong><em>sdb</em></strong> we will use the following command:</p><pre><code class="language-shell">mkfs.exfat -n EXT_DISK_2T /dev/sdb</code></pre><ul><li>exfat is the format we chose in this case.</li><li>-n: the LABEL we give to our disk <em>EXT_DISK_2T</em></li><li>/dev/sdb: the device</li></ul><p>To check if the disk was properly formatted, we can run</p><pre><code class="language-shell">fsck.exfat /dev/sdb</code></pre><p>We can see that everything was properly processed:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">exfatfsck 1.3.0
Checking file system on /dev/sdb.
File system version           1.0
Sector size                 512 bytes
Cluster size                128 KB
Volume size                1863 GB
Used space                   61 MB
Available space            1863 GB
Totally 0 directories and 0 files.
File system checking finished. No errors found.

</code></pre><figcaption>fsck check results: no errors found :-)</figcaption></figure><h2 id="%F0%9F%9B%A0%EF%B8%8F-step-4configure-fstab">&#x1F6E0;&#xFE0F; Step 4 - Configure fstab</h2><p>Now that we successfully formatted our disk, everything is ready. We need to add the information about our new disk in the <strong><em>fstab</em></strong>.</p><p>Doing this will ensure the &quot;automount&quot; of the disk when our drive reboot.</p><p>Check information using the following command</p><pre><code class="language-shell">blkid</code></pre><pre><code class="language-shell">root@pve:~# blkid
/dev/sda2: UUID=&quot;C6B3-A88F&quot; BLOCK_SIZE=&quot;512&quot; TYPE=&quot;vfat&quot; PARTUUID=&quot;fad7d0a1-ed35-412c-a2de-d9d8184141c1&quot;
/dev/sda3: UUID=&quot;8kaOpu-dyIf-v6u2-t5tr-n55e-MO6Q-2BmQli&quot; TYPE=&quot;LVM2_member&quot; PARTUUID=&quot;9c8fe9ca-923b-4c11-ac5d-4f0e148c45a0&quot;
/dev/mapper/pve-swap: UUID=&quot;6fd0c30d-94c2-4c04-ad3e-1ffe7ebf73c5&quot; TYPE=&quot;swap&quot;
/dev/mapper/pve-root: UUID=&quot;add66af1-bf90-4923-85ba-f11e95d53214&quot; BLOCK_SIZE=&quot;4096&quot; TYPE=&quot;ext4&quot;
/dev/sda1: PARTUUID=&quot;0149cd14-1960-4a00-a08d-20accc1fff33&quot;
/dev/mapper/pve-vm--101--disk--0: PTUUID=&quot;dc483fa1&quot; PTTYPE=&quot;dos&quot;
/dev/mapper/pve-vm--100--disk--0: PTUUID=&quot;0ed5ce97-b11f-464c-a0e0-d44ba3fa3d5a&quot; PTTYPE=&quot;gpt&quot;
/dev/sdb: LABEL=&quot;EXT_DISK_2T&quot; UUID=&quot;CA16-A25B&quot; BLOCK_SIZE=&quot;512&quot; TYPE=&quot;exfat&quot; PTTYPE=&quot;dos&quot;

</code></pre><p>The last line displays our newly added disk information. Let&apos;s update the <em><strong>fstab</strong></em> file using this information.</p><pre><code class="language-shell">nano /etc/fstab</code></pre><p>You should see something close to this</p><pre><code class="language-fstab">/dev/pve/root / ext4 errors=remount-ro 0 1
UUID=C6B3-A88F /boot/efi vfat defaults 0 1
/dev/pve/swap none swap sw 0 0
proc /proc proc defaults 0 0</code></pre><p>Let&apos;s add our new disk by editing the fstab file as following</p><pre><code class="language-fstab">/dev/pve/root / ext4 errors=remount-ro 0 1
UUID=C6B3-A88F /boot/efi vfat defaults 0 1
/dev/pve/swap none swap sw 0 0
proc /proc proc defaults 0 0
LABEL=EXT_DISK_2T /media/henri/EXT_DISK_2To exfat errors=remount-ro,defaults,users,noatime,nodiratime,umask=0 0 2</code></pre><ul><li>LABEL=EXT_DISK_2T : our external disk label</li><li>/media/henri/EXT_DISK_2To : the mount point</li><li>exfat : filesystem type</li><li>errors=remount-ro : mount the drive in &apos;read-only&apos; if error occurs</li><li>defaults : use default settings</li><li>users : allows any user to mount/unmount the drive</li><li>noatime : disables writing file access times to the drive every time you read a file</li><li>nodiratime : disables the writing of file access times only for directories while other files still get access times written</li><li>umask=0 : enables read/write access to all users</li><li>1 : used by the dump utility to decide when to make a backup</li><li>2 : sets the order for file system checks at boot time. The root device is set to 1, and other partitions are set to 2</li></ul><p>To save and close the file, press CTRL+X and ENTER.</p><h2 id="%E2%9C%A8-step-5reboot">&#x2728; Step 5 - Reboot</h2><p>Now that everything has been properly set up, let&apos;s reboot the <strong>Proxmox</strong> host by typing</p><pre><code class="language-shell">reboot</code></pre><p>If everything was properly done, the machine should reboot properly.</p><p>To check if everything was properly done, we can run the following command</p><pre><code class="language-shell">lsblk</code></pre><p>We should see our disk displayed, as well as the mountpoint</p><figure class="kg-card kg-code-card"><pre><code>NAME                         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                            8:0    0 465.8G  0 disk 
&#x251C;&#x2500;sda1                         8:1    0  1007K  0 part 
&#x251C;&#x2500;sda2                         8:2    0   512M  0 part /boot/efi
&#x2514;&#x2500;sda3                         8:3    0 465.3G  0 part 
  &#x251C;&#x2500;pve-swap                 253:0    0   7.7G  0 lvm  [SWAP]
  &#x251C;&#x2500;pve-root                 253:1    0    96G  0 lvm  /
  &#x251C;&#x2500;pve-data_tmeta           253:2    0   3.5G  0 lvm  
  &#x2502; &#x2514;&#x2500;pve-data-tpool         253:4    0 338.7G  0 lvm  
  &#x2502;   &#x251C;&#x2500;pve-data             253:5    0 338.7G  1 lvm  
  &#x2502;   &#x251C;&#x2500;pve-vm--101--disk--0 253:6    0    32G  0 lvm  
  &#x2502;   &#x2514;&#x2500;pve-vm--100--disk--0 253:7    0   100G  0 lvm  
  &#x2514;&#x2500;pve-data_tdata           253:3    0 338.7G  0 lvm  
    &#x2514;&#x2500;pve-data-tpool         253:4    0 338.7G  0 lvm  
      &#x251C;&#x2500;pve-data             253:5    0 338.7G  1 lvm  
      &#x251C;&#x2500;pve-vm--101--disk--0 253:6    0    32G  0 lvm  
      &#x2514;&#x2500;pve-vm--100--disk--0 253:7    0   100G  0 lvm  
sdb                            8:16   0   1.8T  0 disk /media/henri/EXT_DISK_2To

</code></pre><figcaption>lsblk results</figcaption></figure><p>Congrats! You successfully mounted an external USB disk to your Proxmox host!</p><!--kg-card-begin: html--><div style="width:100%;height:0;padding-bottom:49%;position:relative;"><iframe src="https://giphy.com/embed/3o6fJ1BM7R2EBRDnxK" width="100%" height="100%" style="position:absolute" frameborder="0" class="giphy-embed" allowfullscreen></iframe></div><p><a href="https://giphy.com/gifs/congratulations-congrats-3o6fJ1BM7R2EBRDnxK"></a></p><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🔥 How to Upload ISO images to Proxmox]]></title><description><![CDATA[<ol><li>Go to your Proxmox main dashboard</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-8.png" class="kg-image" alt="Proxmox - Step 1: main dashboard" loading="lazy" width="1484" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-8.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-8.png 1000w, https://catchtheblock.com/content/images/2022/05/Group-8.png 1484w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox - Step 1: main dashboard</figcaption></figure><p>2. Search for the local storage displaying ISO images in its submenu, and select the ISO images menu. This list beside will display all the ISO images you already uploaded to the server.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-9.png" class="kg-image" alt="Proxmox - Step 2: ISO Images" loading="lazy" width="1484" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-9.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-9.png 1000w, https://catchtheblock.com/content/images/2022/05/Group-9.png 1484w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox - Step 2: ISO</figcaption></figure>]]></description><link>https://catchtheblock.com/how-to-import-iso-to-proxmox-6-3-virtual-environment-pve/</link><guid isPermaLink="false">627fb3104ce77d00015cdd9b</guid><category><![CDATA[tech]]></category><category><![CDATA[proxmox]]></category><category><![CDATA[iso]]></category><category><![CDATA[virtual machine]]></category><category><![CDATA[virtual environment]]></category><category><![CDATA[proxmox 6.3 VE]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 25 May 2022 05:45:00 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2022/05/Frame-3.png" medium="image"/><content:encoded><![CDATA[<ol><li>Go to your Proxmox main dashboard</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-8.png" class="kg-image" alt="&#x1F525; How to Upload ISO images to Proxmox" loading="lazy" width="1484" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-8.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-8.png 1000w, https://catchtheblock.com/content/images/2022/05/Group-8.png 1484w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox - Step 1: main dashboard</figcaption></figure><img src="https://catchtheblock.com/content/images/2022/05/Frame-3.png" alt="&#x1F525; How to Upload ISO images to Proxmox"><p>2. Search for the local storage displaying ISO images in its submenu, and select the ISO images menu. This list beside will display all the ISO images you already uploaded to the server.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-9.png" class="kg-image" alt="&#x1F525; How to Upload ISO images to Proxmox" loading="lazy" width="1484" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-9.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-9.png 1000w, https://catchtheblock.com/content/images/2022/05/Group-9.png 1484w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox - Step 2: ISO Images</figcaption></figure><p>3. Click the Upload button</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-10.png" class="kg-image" alt="&#x1F525; How to Upload ISO images to Proxmox" loading="lazy" width="1484" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-10.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-10.png 1000w, https://catchtheblock.com/content/images/2022/05/Group-10.png 1484w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox - Step 3: Upload</figcaption></figure><p>4. Select the ISO image you would like to upload.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-11.png" class="kg-image" alt="&#x1F525; How to Upload ISO images to Proxmox" loading="lazy" width="1484" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-11.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-11.png 1000w, https://catchtheblock.com/content/images/2022/05/Group-11.png 1484w" sizes="(min-width: 720px) 720px"><figcaption>Proxmox - Step 4: Select ISO image to upload to the server</figcaption></figure><p>You are done :-).</p><p>Cheers!</p><!--kg-card-begin: html--><div style="width:100%;height:0;padding-bottom:55%;position:relative;"><iframe src="https://giphy.com/embed/3KC2jD2QcBOSc" width="100%" height="100%" style="position:absolute" frameborder="0" class="giphy-embed" allowfullscreen></iframe></div>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🗄️ Store Sensor's Data to the Blockchain]]></title><description><![CDATA[In this tutorial, we will learn how to store data from a sensor to the Ethereum Blockchain. ]]></description><link>https://catchtheblock.com/store-tasmota-sensor-data-to-the-blockchain-ethereum/</link><guid isPermaLink="false">612254c1754bc60001014db4</guid><category><![CDATA[blockchain]]></category><category><![CDATA[tasmota]]></category><category><![CDATA[iot]]></category><category><![CDATA[boot]]></category><category><![CDATA[tasmotafirmware]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[sensor's]]></category><category><![CDATA[sensor]]></category><category><![CDATA[data]]></category><category><![CDATA[storage]]></category><category><![CDATA[decentralization]]></category><category><![CDATA[truffle]]></category><category><![CDATA[ganache]]></category><category><![CDATA[web3]]></category><category><![CDATA[HDWallerProvider]]></category><category><![CDATA[axios]]></category><category><![CDATA[DHT11]]></category><category><![CDATA[esp8266]]></category><category><![CDATA[smart contract]]></category><category><![CDATA[infura]]></category><category><![CDATA[metamask]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Mon, 23 May 2022 05:45:00 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/store-sensor-data-blockchain-tasmsota-ethereum.png" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2021/09/store-sensor-data-blockchain-tasmsota-ethereum.png" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain"><p>In this tutorial, we will learn how to store data from a sensor to the Ethereum Blockchain. At the end, we will be able to see the data stored in Ethereum, via Etherscan, as <a href="https://ropsten.etherscan.io/tx/0x1748dd75146a6c22d4de9fd375cc88e3fd05a39273180c952d8e6eb0ffe4535e">follow</a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/tuto-results.gif" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1920" height="1080"><figcaption>Ropsten Etherscan Input Data Example</figcaption></figure><p><strong>Tutorial&apos; Steps</strong></p><ol><li>Setup</li><li>Fetch Data from Sensor</li><li>Create &amp; Migrate Smart Contract</li></ol><p>Let&apos;s go!</p><h2 id="step-1%EF%B8%8F%E2%9A%99%EF%B8%8F-setup">Step 1 - &#xFE0F;&#x2699;&#xFE0F; Setup</h2><h3 id="nodejs">NodeJS</h3><p>Install the latest version of NodeJS &amp; NPM (package manager). In this tutorial, I&apos;m using the v14.16.0. You can download the LTS version <a href="https://nodejs.org/en/">here</a>.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/08/image.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1386" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image.png 1000w, https://catchtheblock.com/content/images/2021/08/image.png 1386w" sizes="(min-width: 720px) 720px"></figure><h3 id="truffle">Truffle</h3><blockquote>&quot;Truffle is the most popular development framework for Ethereum with a mission to make your life a whole lot easier&quot;.</blockquote><p>Truffle can be installed via npm, by typing the following command in your terminal. More info <a href="https://www.trufflesuite.com/truffle">here</a>.</p><pre><code>npm install truffle -g</code></pre><h3 id="ganache">Ganache</h3><blockquote>&quot;Quickly fire up a personal Ethereum blockchain which you can use to run tests, execute commands, and inspect state while controlling how the chain operates.&quot;</blockquote><p>Ganache helps us launching a local blockchain in order to test, and develop. When you downloaded it, run it. You should have a window displaying 10 accounts with 100 $ETH each (hum, fake ETH sorry... &#x1F609;).</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/08/image-4.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1304" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-4.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-4.png 1000w, https://catchtheblock.com/content/images/2021/08/image-4.png 1304w" sizes="(min-width: 720px) 720px"></figure><h3 id="web3">Web3</h3><blockquote>&quot;web3.js is a collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC or WebSocket.&quot; </blockquote><p>More info <a href="https://www.npmjs.com/package/web3">here</a>.</p><pre><code>npm install web3</code></pre><h3 id="hdwalletprovider">HDWalletProvider</h3><p>This library will help us signing transaction for addresses derived from a 12 or 24 word mnemonic. </p><p>More info <a href="https://www.npmjs.com/package/@truffle/hdwallet-provider">here</a>.</p><pre><code>npm install @truffle/hdwallet-provider</code></pre><h3 id="axios">Axios</h3><blockquote>&quot;Promise based HTTP client for the browser and node.js&quot;. </blockquote><p>More info <a href="https://www.npmjs.com/package/axios">here</a>. In short, Axios is a NodeJs library allowing us to fetch the data from our sensor.</p><pre><code>npm install axios</code></pre><p>Now, we are all set, let&apos;s start &#x1F600; .</p><h2 id="step-2%F0%9F%AA%9D-fetch-data-from-sensor">Step 2 - &#x1FA9D; Fetch Data From Sensor</h2><p>In this tutorial, we will use 2 components a DHT11 sensor, and an ESP8266 module. We will assume you already flashed the ESP8266, with Tasmota. If you don&apos;t know how to proceed, please have a look to one of my tutorial about that part.</p><h3 id="dht11">DHT11</h3><ul><li><a href="https://amzn.to/3Lzvk3n">Amazon</a></li></ul><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B089W8DB5P&amp;asins=B089W8DB5P&amp;linkId=fab04337efbc789268a00248c2d53021&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><h3 id="esp8266">ESP8266</h3><ul><li><a href="https://amzn.to/3Ny4HNR">Amazon</a></li></ul><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B074Q2WM1Y&amp;asins=B074Q2WM1Y&amp;linkId=1604b32dd3c23bc51d7816f64a8d87e7&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><p>Data are accessible via an HTTP request, as explained in the Tasmota <a href="https://tasmota.github.io/docs/Commands/">documentation</a> (here, see &apos;with Web Requests&apos; section).</p><p>In this case, we will use the following URL:</p><pre><code>http://192.168.1.62/cm?cmnd=Status%2010</code></pre><ul><li>192...: my sensor&apos;s ip address</li><li>cm?...: the command getting the status data</li></ul><p>If you follow that link in a web browser, you should see an object displaying your sensor&apos;s data:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-3.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1192" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-3.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-3.png 1000w, https://catchtheblock.com/content/images/2021/08/image-3.png 1192w" sizes="(min-width: 720px) 720px"><figcaption>DHT11 data Illustration</figcaption></figure><p>Ok, now we need to fetch these data. That&apos;s why we previously installed the Axios library.</p><p>In our main directory, let&apos;s run the following command in our terminal, to initiate our project:</p><pre><code class="language-shell">npm init</code></pre><p>A package.json file should have appeared in our directory.</p><p>Now, let&apos;s create our script file, index.js and open it. In your terminal, run the following command</p><pre><code class="language-shell">touch index.js</code></pre><p>In this new file, type the code below:</p><pre><code class="language-javascript">const axios = require(&apos;axios&apos;);

const url = &apos;http://192.168.1.62/cm?cmnd=Status%2010&apos;;

const getData = async() =&gt; {
    const response = await axios.get(url);
    let result;
    if(response.status == 200){
        const data = {
            server: response.headers.server,
            timestamp: response.data.StatusSNS.Time,
            temperature: parseInt(response.data.StatusSNS.DHT11.Temperature),
            humidity: parseInt(response.data.StatusSNS.DHT11.Humidity),
            dewpoint: parseInt(response.data.StatusSNS.DHT11.DewPoint),
        };
        result = JSON.stringify(data);
    }
    console.log(result);
    return result;
}

getData();</code></pre><h3 id="comments">Comments</h3><ul><li>Import axios library in our file</li><li>Store the URL including the Tasmota command in a variable called URL. This address should be different on your side. When you flash Tasmota on the ESP8266 module, it assign a random IP address to the compoment.</li><li>Define a function getData to fetch the data with Axios.</li><li>In summary: if we have an answer from the module, then we collect and allocate the different data in an object called data (server, timestamp, humidity, etc.). Finally, we convert this object into a string (easier for the Smart Contract in Solidity part), and return the data.</li></ul><p>Now, we have our data. Let&apos;s move on the Blockchain part.</p><h2 id="step-3%F0%9F%94%A5-smart-contract">Step 3 - &#x1F525; Smart Contract</h2><p>In the step 1, we installed the Truffle framework. This will help us structure our Smart Contract part.</p><p>In your terminal, run the following command</p><pre><code class="language-shell">truffle init</code></pre><p>Now, you should have the following structure in your main directory:</p><figure class="kg-card kg-code-card"><pre><code>&#x251C;&#x2500;&#x2500; contracts
&#x2502;   &#x2514;&#x2500;&#x2500; Migrations.sol
&#x251C;&#x2500;&#x2500; index.js
&#x251C;&#x2500;&#x2500; migrations
&#x2502;   &#x2514;&#x2500;&#x2500; 1_initial_migration.js
&#x251C;&#x2500;&#x2500; node_modules
   &#x2514;&#x2500;&#x2500; ...
&#x2502;&#x2500;&#x2500; package-lock.json
&#x251C;&#x2500;&#x2500; package.json
&#x251C;&#x2500;&#x2500; test
&#x2514;&#x2500;&#x2500; truffle-config.js</code></pre><figcaption>Initial Directory Tree</figcaption></figure><p>In the contracts folder, create a new folder called MyContract.sol . This file will hold our Smart Contract in Solidity.</p><pre><code>touch contracts/MyContract.sol</code></pre><p>Here is our Smart Contract code. This tutorial is not about how to write Smart Contract in Solidity. So, we won&apos;t go in details of this contract.</p><figure class="kg-card kg-code-card"><pre><code class="language-solidity">pragma solidity &gt;=0.4.16 &lt;0.9.0;

contract MyContract {
    string data;

    event MyData (
        address indexed from,
        string data
    );

    function set(string memory x) public {
        data = x;
        emit MyData(msg.sender, data);
    }

    function get() public view returns(string memory) {
        return data;
    }
}</code></pre><figcaption>MyContract.sol</figcaption></figure><p>In a few words:</p><ul><li>We define 2 functions: set and get.</li><li>As you probably guessed already, the set function will &apos;store&apos; the data we send to the Smart Contract, while the get function will return the value we stored.</li><li>As you can see, we also add an event emitted in the set function.</li></ul><p>Now, we need to compile and migrate that MyContract.sol . </p><p>In the Migrate directory, create a new file called 2_contract_deploy.js, and write the following code inside:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const MyContract = artifacts.require(&apos;MyContract&apos;);

module.exports = function(deployer){
    deployer.deploy(MyContract);
}</code></pre><figcaption>2_contract_deploy.js</figcaption></figure><p>In our terminal, run the following command</p><pre><code>truffle migrate --reset</code></pre><p>You should see the following answer in your Terminal</p><pre><code>Compiling your contracts...
===========================
&gt; Compiling ./contracts/MyContract.sol
&gt; Artifacts written to /Users/henririon/Documents/Tutorials/From Sensor To Blockchain/build/contracts
&gt; Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang



Starting migrations...
======================
&gt; Network name:    &apos;ganache&apos;
&gt; Network id:      5777
&gt; Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Replacing &apos;Migrations&apos;
   ----------------------
   &gt; transaction hash:    0x984378f75dc8f252a4d51d1ad85ee72433aadb0a50be092130c0e2b516d315ed
   &gt; Blocks: 0            Seconds: 0
   &gt; contract address:    0xF07f86C3b0445DA2f0157C60B617F394b08ddc77
   &gt; block number:        23
   &gt; block timestamp:     1629645715
   &gt; account:             0x95Cba0aAA08704fDFc52312C2F130dd6312F6766
   &gt; balance:             99.94825178
   &gt; gas used:            191943 (0x2edc7)
   &gt; gas price:           20 gwei
   &gt; value sent:          0 ETH
   &gt; total cost:          0.00383886 ETH


   &gt; Saving migration to chain.
   &gt; Saving artifacts
   -------------------------------------
   &gt; Total cost:          0.00383886 ETH


2_contract_deploy.js
====================

   Deploying &apos;MyContract&apos;
   ----------------------
   &gt; transaction hash:    0x8fb6a0a2f9187d5928b7e00290c04444e4400b5f5c0cf99182b0ed3708948596
   &gt; Blocks: 0            Seconds: 0
   &gt; contract address:    0x4Ad94cE4c77c7Efeb2B6742125E6300E41c09Db4
   &gt; block number:        25
   &gt; block timestamp:     1629645715
   &gt; account:             0x95Cba0aAA08704fDFc52312C2F130dd6312F6766
   &gt; balance:             99.94205754
   &gt; gas used:            267374 (0x4146e)
   &gt; gas price:           20 gwei
   &gt; value sent:          0 ETH
   &gt; total cost:          0.00534748 ETH


   &gt; Saving migration to chain.
   &gt; Saving artifacts
   -------------------------------------
   &gt; Total cost:          0.00534748 ETH


Summary
=======
&gt; Total deployments:   2
&gt; Final cost:          0.00918634 ETH</code></pre><p>This answer shows our deployed contract to our local blockchain. If we had deployed that contract in the Mainnet, it would have cost some Gas for real. Here, these are fake Ether.</p><p>In your Ganache window, you should see the first account with a balance close to 99 ETH since we &apos;pay&apos; a GasPrice to deploy.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-5.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1304" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-5.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-5.png 1000w, https://catchtheblock.com/content/images/2021/08/image-5.png 1304w" sizes="(min-width: 720px) 720px"><figcaption>Ganache Accounts after deployment</figcaption></figure><p>So far, we collected our data, and we now deployed our Smart Contract in our local Blockchain.</p><p>Let&apos;s return now in our index.js file.</p><h2 id="step-4%F0%9F%A4%99%F0%9F%8F%BB-interact-with-our-smart-contract">Step 4 - &#x1F919;&#x1F3FB; Interact with our Smart Contract</h2><p>In our index.js , we will write the script&apos;s part allowing us to interact with our Smart Contract. In other words, we will send some data to the contract, and then we will check the data.</p><p>Here is the code:</p><pre><code>const HDWalletProvider = require(&apos;@truffle/hdwallet-provider&apos;);
const axios = require(&apos;axios&apos;);
const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const ganache = &apos;http://127.0.0.1:7545&apos;;

const address = &apos;0x904202186FF74eF4E78D12bf161796F18BAE3081&apos;;
const privateKey = &apos;633962326604757f2676241bf34b55eababe2c6314a7f456fd911f3fb1abd94e&apos;;

const url = &apos;http://192.168.1.62/cm?cmnd=Status%2010&apos;;

const getData = async() =&gt; {
    const response = await axios.get(url);
    let result;
    if(response.status == 200){
        const data = {
            server: response.headers.server,
            timestamp: response.data.StatusSNS.Time,
            temperature: parseInt(response.data.StatusSNS.DHT11.Temperature),
            humidity: parseInt(response.data.StatusSNS.DHT11.Humidity),
            dewpoint: parseInt(response.data.StatusSNS.DHT11.DewPoint),
        };
        result = JSON.stringify(data);
    }
    console.log(result);
    return result;
}

const main = async() =&gt; {
    const provider = new HDWalletProvider(
        privateKey,
        ganache
    );

    const web3 = new Web3(provider);
    
    const id = await web3.eth.net.getId();
    const deployedNetwork = MyContract.networks[id];

    let contract = new web3.eth.Contract(
        MyContract.abi,
        deployedNetwork.address
    );

    const accounts = await web3.eth.getAccounts();

    let result = await getData();
    console.log(result);

    try {
        const receipt = await contract.methods.set(result).send({
            from: address,
            gas: 3000000,
        });
    
        console.log(receipt);
    
        const x = await contract.methods.get().call({
            from: address, 
            gas: 3000000,
        });
        console.log(x);


    } catch (error) {

        console.log(error)
    
    }
}

main();</code></pre><p>Comments:</p><ol><li>We import the required libraries: @truffle/hdwallet-provider (library to sign transaction), web3 (library to interact with Smart Contracts), our MyContract (our Smart Contract).</li><li>We store the Ganache host in a variable. You can see this address in your Ganache window. In my case, I have http://127.0.0.1:7545 . </li><li>We store an Ethereum address to a const address (I toke the first address displayed in Ganache)</li><li>We store the Private Key (available in Ganache by clicking the key on the right of the required account)</li><li>We declare our custom provider using the HDWallerProvider library, including the privateKey constant, and the Ganache host address as parameters</li><li>We instantiate Web3 using our custom provider,</li><li>We instantiate our Contract using the web3 library.</li><li>In a the try/catch section, we send a Transaction to the method &apos;set&apos; including our data stored in the const result as parameter. To use the send method, we also need to include 2 parameters &apos;from&apos; (the source address), and the gas limit. More info <a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html?highlight=methods.MyMethod.send#methods-mymethod-send">here</a>.</li><li>Then we call the get method in order to see the data we stored.</li></ol><p>As a result, in the Terminal, you should see:</p><p>The receipt of the Send Transaction part</p><figure class="kg-card kg-code-card"><pre><code>{
  transactionHash: &apos;0x787708a586df25dc1e6c39305995db56be1d0c13fa14ac8cd4de3393b9984051&apos;,
  transactionIndex: 0,
  blockHash: &apos;0x0f1e2333a29692deea4824f0a5ea6e7c4c6d83fc7a3ab5bcff19b8e700110b5c&apos;,
  blockNumber: 7,
  from: &apos;0x904202186ff74ef4e78d12bf161796f18bae3081&apos;,
  to: &apos;0xca9c9833e58275dd66b47dfc8a560700d9abd474&apos;,
  gasUsed: 45668,
  cumulativeGasUsed: 45668,
  contractAddress: null,
  status: true,
  logsBloom: &apos;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000004000000000000000000002000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000&apos;,
  events: {
    MyData: {
      logIndex: 0,
      transactionIndex: 0,
      transactionHash: &apos;0x787708a586df25dc1e6c39305995db56be1d0c13fa14ac8cd4de3393b9984051&apos;,
      blockHash: &apos;0x0f1e2333a29692deea4824f0a5ea6e7c4c6d83fc7a3ab5bcff19b8e700110b5c&apos;,
      blockNumber: 7,
      address: &apos;0xca9c9833e58275Dd66b47Dfc8A560700D9ABd474&apos;,
      type: &apos;mined&apos;,
      id: &apos;log_ddf3b684&apos;,
      returnValues: [Result],
      event: &apos;MyData&apos;,
      signature: &apos;0xa8073d849fb4a3e09df83ab9787898c62652336cd0d79a6e402438f64af7aeac&apos;,
      raw: [Object]
    }
  }
}</code></pre><figcaption>Transaction&apos;s receipt</figcaption></figure><p>and from the get method, you should see our sensor&apos;s data:</p><pre><code>{&quot;server&quot;:&quot;Tasmota/9.5.0 (ESP8266EX)&quot;,&quot;timestamp&quot;:&quot;2021-08-22T16:51:23&quot;,&quot;temperature&quot;:24,&quot;humidity&quot;:63,&quot;dewpoint&quot;:17}</code></pre><p>Hurraaaa! It works &#x1F389;&#x1F973; ! Congrats, you successfully collect the data from the sensor, and store it in our local blockchain! </p><p>Hold on, this is not the end! Now, let&apos;s store this data on the Public Testnet Ropsten from Ethereum.</p><h2 id="step-5store-the-data-to-ropsten-public-testnet-ethereum">Step 5 - Store the Data to Ropsten (Public Testnet Ethereum)</h2><h3 id="what-is-ropsten">What is Ropsten?</h3><p>Here is a very good definition:</p><blockquote>Ropsten Ethereum, also known as &#x201C;Ethereum Testnet&#x201D;, are as the name implies, a testing network that runs the same protocol as Ethereum does and is used to testing purposes before deploying on the main network (Mainnet).</blockquote><blockquote>Ethereum has several networks. Your Valuable ETHs are in the Main Net. The rETHs are on the Ropsten one.</blockquote><blockquote>Ropsten ETHs are used for testing purposes. When developers are building dApps, or experimenting on the network, to avoid losing money paying real ETH for transaction fees and smart contract deployments, it&#x2019;s better to use the Ropsten Network.</blockquote><p>More info in <a href="https://medium.com/bitfwd/get-ropsten-ethereum-the-easy-way-f2d6ece21763#:~:text=Ropsten%20Ethereum%2C%20also%20known%20as,are%20in%20the%20Main%20Net.">this</a> very good article.</p><h3 id="step-51infura">Step 5.1. - Infura</h3><p>To deploy our Smart Contract to Ropsten, we need an access to an Ethereum node. Either, you are lucky, and you have your own node, or, like me, you don&apos;t, and you need another solution &#x1F603;. This solution is called <a href="https://infura.io/">Infura</a>.</p><blockquote>The World&#x2019;s Most Powerful Blockchain Development Suite</blockquote><blockquote>Our suite of high availability APIs and Developer Tools provide quick, reliable access to the Ethereum and IPFS networks so you can focus on building and scaling next generation software.</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-7.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1529" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-7.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-7.png 1000w, https://catchtheblock.com/content/images/2021/08/image-7.png 1529w" sizes="(min-width: 720px) 720px"><figcaption>Infura Homepage</figcaption></figure><p>Infura allows us to interact with Ethereum networks (Mainnet &amp; Testnets) by using an API. Hopefully this service is FREE.</p><p>Create your account, and let&apos;s move on.</p><p>Once signed up, let&apos;s create a project.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-8.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1529" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-8.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-8.png 1000w, https://catchtheblock.com/content/images/2021/08/image-8.png 1529w" sizes="(min-width: 720px) 720px"><figcaption>Infura - Create a Project</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-9.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1529" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-9.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-9.png 1000w, https://catchtheblock.com/content/images/2021/08/image-9.png 1529w" sizes="(min-width: 720px) 720px"><figcaption>Infura New Project called Temperature</figcaption></figure><p>Once created, you can copy the Testnet Ropsten endpoint.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-22-a--18.03.39.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1529" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/Capture-d-e-cran-2021-08-22-a--18.03.39.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/Capture-d-e-cran-2021-08-22-a--18.03.39.png 1000w, https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-22-a--18.03.39.png 1529w" sizes="(min-width: 720px) 720px"><figcaption>Infura - Ropsten Endpoints</figcaption></figure><h3 id="step-52setup-metamask">Step 5.2. - Setup Metamask</h3><p>If it&apos;s not the case already, install the Metamask extension to your chrome, by clicking <a href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en">here</a>. Follow the steps.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/08/image-12.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="2000" height="2080" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-12.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-12.png 1000w, https://catchtheblock.com/content/images/size/w1600/2021/08/image-12.png 1600w, https://catchtheblock.com/content/images/size/w2400/2021/08/image-12.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Once installed, and set up, click on the top right icon, create a new Account, and call it Test.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-17.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="354" height="599"><figcaption>Change to Ropsten Network (= Public Test Net)</figcaption></figure><p>Copy the Account address, right under the Test title. Now, we need to provide &apos;fake&apos; Ether to this account, in order to &apos;pay&apos; our deployment within the Testnet Network.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-18.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="351" height="596"><figcaption>Copy the Metamask Ropsten Account&apos;s address</figcaption></figure><p>&#x1F6B0; Go to <a href="https://faucet.ropsten.be/">https://faucet.ropsten.be/</a>, paste your account address, and click on &apos;Send me test Ether&apos;. After a couple of seconds/minutes, you will see the test Ether arrives on your Test account in Metamask.</p><p>&#x26A0;&#xFE0F; Warning&#x26A0;&#xFE0F; &#xA0;--&gt; Avoid clicking several times on the Send button, to avoid being blacklisted!</p><p>Once you received your 5 ETH, we can move on.</p><p>Now let&apos;s edit our index.js script to deploy on the Testnet.</p><p>Here is the code, comments are following:</p><pre><code>const HDWalletProvider = require(&apos;@truffle/hdwallet-provider&apos;);
const axios = require(&apos;axios&apos;);
const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const ropsten = &apos;https://ropsten.infura.io/v3/e944752a46184aaa8800e8c138886d1a&apos;;

const address = &apos;Your Metamask Account Address&apos;;
const privateKey = &apos;Your Metamask Private Key Account&apos;;

const url = &apos;http://192.168.1.62/cm?cmnd=Status%2010&apos;;

const getData = async() =&gt; {
    const response = await axios.get(url);
    let result;
    if(response.status == 200){
        const data = {
            server: response.headers.server,
            timestamp: response.data.StatusSNS.Time,
            temperature: parseInt(response.data.StatusSNS.DHT11.Temperature),
            humidity: parseInt(response.data.StatusSNS.DHT11.Humidity),
            dewpoint: parseInt(response.data.StatusSNS.DHT11.DewPoint),
        };
        result = JSON.stringify(data);
    }
    console.log(result);
    return result;
}

const main = async() =&gt; {

    const provider = new HDWalletProvider(
        privateKey,
        ropsten
    );

    const web3 = new Web3(provider);

    let contract = new web3.eth.Contract(
        MyContract.abi,
    );

    contract = await contract
        .deploy({data: MyContract.bytecode})
        .send({from: address});

    let result = await getData();
    console.log(result);

    try {
        const receipt = await contract.methods.set(result).send({
            from: address,
            gas: 3000000,
        });
    
        console.log(receipt);
    
        const x = await contract.methods.get().call({
            from: address, 
            gas: 3000000,
        });
        console.log(x);


    } catch (error) {

        console.log(error)
    
    }
}

main();</code></pre><h3 id="comments-1">Comments</h3><ul><li>We store the API address provided by Infura in the Ropsten constant</li><li>We store the Metamask Account address in the Address constant</li><li>We store the Metamask Account Private Key</li></ul><h3 id="where-to-find-the-metamask-account-private-key">Where to find the Metamask Account Private Key?</h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-22-a--18.24.26.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="352" height="595"><figcaption>Metamask Private Key</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-13.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="353" height="593"><figcaption>Click on Export the Private Key</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-22-a--18.26.29.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="338" height="549"><figcaption>Copy the Private Key</figcaption></figure><ul><li>We define our custom provider by using the Ropsten API address.</li><li>After, we instantiate again web3, and our Smart Contract, but we don&apos;t use the deployedNetwork as performed previously, which is our local blockchain.</li></ul><p>Now run the following code in your terminal:</p><pre><code>node index.js</code></pre><p>It will be a bit slower than before since it&apos;s on the public testnet now.</p><p>You should see the receipt, and the get data result.</p><figure class="kg-card kg-code-card"><pre><code>{
  blockHash: &apos;0xc078972c8c6a90b60d2ce677cae3f277380b0eb74d6bdbdabe78bc4131cc2586&apos;,
  blockNumber: 10888390,
  contractAddress: null,
  cumulativeGasUsed: 611127,
  effectiveGasPrice: &apos;0x59682f0e&apos;,
  from: &apos;0xdbd78940117b014c4738b850d5e1eb92adfe1b13&apos;,
  gasUsed: 138768,
  logsBloom: &apos;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000080000000000001000000000000000000000000000000000000000000000000000000000080000001002000000000000000000000000000000000000000000010000000000000000020000000000000000000000000&apos;,
  status: true,
  to: &apos;0x2472fe4510696302e31382229400822ec6b0fced&apos;,
  transactionHash: &apos;0x21acdc35d63c9e078bd86fe75f92b4f8b1dad2f758de4d872f282e623328ba34&apos;,
  transactionIndex: 3,
  type: &apos;0x0&apos;,
  events: {
    MyData: {
      address: &apos;0x2472FE4510696302e31382229400822ec6b0FceD&apos;,
      blockHash: &apos;0xc078972c8c6a90b60d2ce677cae3f277380b0eb74d6bdbdabe78bc4131cc2586&apos;,
      blockNumber: 10888390,
      logIndex: 9,
      removed: false,
      transactionHash: &apos;0x21acdc35d63c9e078bd86fe75f92b4f8b1dad2f758de4d872f282e623328ba34&apos;,
      transactionIndex: 3,
      id: &apos;log_a3f66bda&apos;,
      returnValues: [Result],
      event: &apos;MyData&apos;,
      signature: &apos;0xa8073d849fb4a3e09df83ab9787898c62652336cd0d79a6e402438f64af7aeac&apos;,
      raw: [Object]
    }
  }
}
{&quot;server&quot;:&quot;Tasmota/9.5.0 (ESP8266EX)&quot;,&quot;timestamp&quot;:&quot;2021-08-22T17:21:28&quot;,&quot;temperature&quot;:24,&quot;humidity&quot;:63,&quot;dewpoint&quot;:17}</code></pre><figcaption>Receipt</figcaption></figure><p>Now copy the &apos;to&apos; hash code (0x2472fe4510696302e31382229400822ec6b0fced), which is the contract address on the blockchain, and paste it to <a href="https://ropsten.etherscan.io/">https://ropsten.etherscan.io/</a> &#xA0;(we have to use ropsten etherscan since we are on the Test net).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-22-a--18.32.05.png" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="1529" height="1167" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/Capture-d-e-cran-2021-08-22-a--18.32.05.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/Capture-d-e-cran-2021-08-22-a--18.32.05.png 1000w, https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-22-a--18.32.05.png 1529w" sizes="(min-width: 720px) 720px"><figcaption>Ropsten Etherscan</figcaption></figure><p>On the printscreen:</p><ol><li>Corresponds to the contract deployment</li><li>Corresponds to the set data operation</li></ol><p>If you click on the Txn Hash of the Set Method, you should see our Sensor Data ! </p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/08/giphy.gif" class="kg-image" alt="&#x1F5C4;&#xFE0F; Store Sensor&apos;s Data to the Blockchain" loading="lazy" width="480" height="480"></figure><p>Congrats! &#xA0;We are all done now.</p><p>I hope you enjoyed this tutorial, feel free to reach out! &#xA0;</p>]]></content:encoded></item><item><title><![CDATA[💥 DIY IR Bridge for Home Assistant]]></title><description><![CDATA[<p>Tired using plenty of remote controllers at home for TV, AC, Leds, Internet Box...? With a simple DIY Infrared Bridge, control your IR devices through Home Assistant.</p><h2 id="%F0%9F%9A%A8-assumptions">&#x1F6A8; Assumptions</h2><p>Before we start, I&apos;m assuming in this tutorial that:</p><ul><li>Home Assistant is installed, configured, and running,</li><li>MQTT Broker is</li></ul>]]></description><link>https://catchtheblock.com/diy-ir-bridge-and-home-assistant/</link><guid isPermaLink="false">61000e7c4ef4410001d25a6a</guid><category><![CDATA[diy]]></category><category><![CDATA[esp8266]]></category><category><![CDATA[irtransmitter]]></category><category><![CDATA[homeassistant]]></category><category><![CDATA[hass]]></category><category><![CDATA[opensource]]></category><category><![CDATA[tasmota]]></category><category><![CDATA[tasmotafirmware]]></category><category><![CDATA[domotic]]></category><category><![CDATA[firmware]]></category><category><![CDATA[iot]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Sat, 21 May 2022 14:28:00 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/diy-ir-infrared-home-assistant-hass.png" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2021/09/diy-ir-infrared-home-assistant-hass.png" alt="&#x1F4A5; DIY IR Bridge for Home Assistant"><p>Tired using plenty of remote controllers at home for TV, AC, Leds, Internet Box...? With a simple DIY Infrared Bridge, control your IR devices through Home Assistant.</p><h2 id="%F0%9F%9A%A8-assumptions">&#x1F6A8; Assumptions</h2><p>Before we start, I&apos;m assuming in this tutorial that:</p><ul><li>Home Assistant is installed, configured, and running,</li><li>MQTT Broker is installed, configured, and running,</li><li>You know the Protocol, Code, and Length to transmit via IR. We will use NEC, 16712445, 32 in here.</li></ul><p>Check my other articles to see how to capture codes, protocol, and code&apos;s length.</p><hr><h2 id="%F0%9F%9B%8D%EF%B8%8F-required-materials">&#x1F6CD;&#xFE0F; Required Materials</h2><p>Links to Amazon are used for illustration, and not promotion. Of course, you can find the required materials elsewhere such as Aliexpress.</p><ul><li><a href="https://amzn.to/3wJV6fS">ESP8266</a></li></ul><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B06Y1ZPNMS&amp;asins=B06Y1ZPNMS&amp;linkId=4bf54bdf958576abab63fdb3ce693c8f&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><ul><li><a href="https://amzn.to/3Pxcddv">IR transmitter</a></li></ul><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B07BFNYGWR&amp;asins=B07BFNYGWR&amp;linkId=1208df17db29b536902fe40850e28f2f&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><ul><li><a href="https://amzn.to/3NtyQ0B">3 jumpers female-female</a> + 1 USB Cable</li></ul><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B074P726ZR&amp;asins=B074P726ZR&amp;linkId=5fb8ef7b39d1bdb589e615912b6078cd&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/esp8266-ir-transmitter-usb-materials-overview.jpeg" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="880" height="660" srcset="https://catchtheblock.com/content/images/size/w600/2021/07/esp8266-ir-transmitter-usb-materials-overview.jpeg 600w, https://catchtheblock.com/content/images/2021/07/esp8266-ir-transmitter-usb-materials-overview.jpeg 880w" sizes="(min-width: 720px) 720px"><figcaption>Required Materials Overview</figcaption></figure><h2 id="%E2%9A%A1-flashing-esp8266-with-tasmota">&#x26A1; Flashing ESP8266 with Tasmota</h2><p>Flashing the ESP8266 with Tasmota firmware is not the purpose of this tutorial. In case you don&apos;t know how to proceed, please have a look to my other tutorial.</p><h2 id="%F0%9F%94%8C-plugging-components-together">&#x1F50C; Plugging Components Together</h2><p>Now, we installed Tasmota firmware on our ESP8266, we can plug components together. Here are the required connections, from ESP8266 to IR Transmitter:</p><ul><li>GND -&gt; GND</li><li>3V3 -&gt; VCC</li><li>D3 -&gt; SIG</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/esp8266-pins-1.jpeg" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="664" height="900" srcset="https://catchtheblock.com/content/images/size/w600/2021/07/esp8266-pins-1.jpeg 600w, https://catchtheblock.com/content/images/2021/07/esp8266-pins-1.jpeg 664w"><figcaption>ESP8266 connection pins</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/ir-transmitter-pins-1.jpeg" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="531" height="650"><figcaption>IR Transmitter connection pins</figcaption></figure><h2 id="%F0%9F%AA%9B-tasmota-configuration">&#x1FA9B; Tasmota Configuration</h2><ul><li>Go to the allocated IP address of our wonderful Tasmota</li><li>In this case, we have 192.168.1.62</li><li>Go to : Configuration &gt; Configure Module, and select Generic module type, and allocate IRSend to the D3 GPIO0</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/esp8266-tasmota-configuration.png" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="880" height="655" srcset="https://catchtheblock.com/content/images/size/w600/2021/07/esp8266-tasmota-configuration.png 600w, https://catchtheblock.com/content/images/2021/07/esp8266-tasmota-configuration.png 880w" sizes="(min-width: 720px) 720px"><figcaption>Tasmota Configuration Panel to Allocate D3 GPIO0 to IRSend</figcaption></figure><p>In terms of our hardwares configuration, we are now good. Let&apos;s move on with Home Assistant.</p><hr><h2 id="%F0%9F%8F%A0-home-assistant-integration">&#x1F3E0; Home Assistant Integration</h2><p>If you didn&apos;t already add &#xA0;Tasmota entities to Home Assistant yet, go to Configuration &gt; Integrations &gt; Add Integration &gt; Tasmota.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/07/image-4.png" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="526" height="777"></figure><p>You should now be able to see Tasmota entities available on your network.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/image-5.png" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="292" height="176"><figcaption>Illustration of how it looks on my Hass. It could be different on yours.</figcaption></figure><h2 id="%F0%9F%A7%AA-testing-first">&#x1F9EA; Testing first!</h2><p>Before final integration, let&apos;s test the communication between MQTT, and our Tasmota device.</p><p>On a new tab of your favorite browser, open the Tasmota panel (192.168.1.62), and go to Console.</p><p>Open a new tab with Home Assistant, and go to Configuration &gt; Integrations, and click on the MQTT Configure button.</p><p>In the &quot;Publish a Packet&quot; part, we will add the topic (i.e. the name of our Tasmota), and the Payload (the code we want to execute).</p><h2 id="%F0%9F%94%8D-where-to-find-the-mqtt-topic">&#x1F50D; Where to find the MQTT Topic?</h2><p>On the Tasmota tab, go to the Information menu, and find the &quot;MQTT Full Topic&quot;. In our case, we have:</p><pre><code class="language-shell">cmnd/tasmota_E30D62/</code></pre><p>Add this topic name to our Home Assistant MQTT Configure panel, with IRsend at the end.</p><pre><code>cmnd/tasmota_E30D62/irsend</code></pre><h2 id="%F0%9F%94%8E-where-to-find-the-payload">&#x1F50E; Where to find the Payload?</h2><p>As previously explained, in this case, we assume having already the code, and protocol.</p><h3 id="payload">Payload</h3><pre><code>{&quot;Protocol&quot;:&quot;NEC&quot;,&quot;Bits&quot;:32,&quot;Data&quot;:16753245}</code></pre><p>And now click publish. </p><p>You should see the Tasmota&apos;s console displaying the below message:</p><pre><code>MQT: stat/tasmota_E30D62/RESULT = {&quot;IRSend&quot;:&quot;Done&quot;}</code></pre><h3 id="integration">Integration</h3><p>Open your configuration.yaml file and add the following lines:</p><pre><code>switch:
  - platform: mqtt
    name: &quot;TEST ESP8266 LED LIGHT&quot; #the entity name
    command_topic: &quot;cmnd/tasmota_E30D62/IRsend&quot;
    payload_on: &apos;{&quot;Protocol&quot;:&quot;NEC&quot;,&quot;Bits&quot;:32,&quot;Data&quot;:16712445}&apos;
    payload_off: &apos;{&quot;Protocol&quot;:&quot;NEC&quot;,&quot;Bits&quot;:32,&quot;Data&quot;:16712445}&apos;
</code></pre><p>Save and close the configuration.yaml file. For the tutorial, I&apos;m limiting the codes to toggle ON/OFF. Of course, you can add all the required codes.</p><p>Check the configuration within Home Assistant. Go to Configurations &gt; Server Controls &gt; Configuration Validation &gt; Check Configuration. </p><p>You must have the &quot;Configuration Valid!&quot; message.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/image-6.png" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="584" height="236"><figcaption>Home Assistant Configuration Valid! Message</figcaption></figure><p><br>Once the configuration valid message appears, you can restart Home Assistant server.</p><h2 id="%F0%9F%92%A1-new-entity-usage">&#x1F4A1; New Entity Usage</h2><p>Now, to see our brand new DIY IR Bridge in action, we can create a new view, and click the add card button.<br>Select the Button card type.<br>Find the Entity we just created, and save.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/image-7.png" class="kg-image" alt="&#x1F4A5; DIY IR Bridge for Home Assistant" loading="lazy" width="874" height="396" srcset="https://catchtheblock.com/content/images/size/w600/2021/07/image-7.png 600w, https://catchtheblock.com/content/images/2021/07/image-7.png 874w" sizes="(min-width: 720px) 720px"><figcaption>Home Assistant Adding our New IR Bridge Entity</figcaption></figure><p>Now, you have an IR Bridge working. </p><p>I hope you enjoyed this tutorial. </p><p>Do not hesitate to ask questions, or give improvements. I&apos;m always open to improve and share &#x1F919;.</p>]]></content:encoded></item><item><title><![CDATA[⚡ Flashing ESP8266 with Tasmota, in 5 steps]]></title><description><![CDATA[5-step tutorial showing you how to flash Tasmota firmware into the famous ESP8266.]]></description><link>https://catchtheblock.com/flashing-esp8266-with-tasmota-in-5-steps/</link><guid isPermaLink="false">61000bcd4ef4410001d25a1b</guid><category><![CDATA[tasmota]]></category><category><![CDATA[tasmotafirmware]]></category><category><![CDATA[flashing]]></category><category><![CDATA[esp8266]]></category><category><![CDATA[diy]]></category><category><![CDATA[domotic]]></category><category><![CDATA[homeassistant]]></category><category><![CDATA[hass]]></category><category><![CDATA[flash]]></category><category><![CDATA[boot]]></category><category><![CDATA[firmware]]></category><category><![CDATA[opensource]]></category><category><![CDATA[iot]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Mon, 16 May 2022 16:15:00 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/fashing-esp8266-tasmota.png" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2021/09/fashing-esp8266-tasmota.png" alt="&#x26A1; Flashing ESP8266 with Tasmota, in 5 steps"><p>In this tutorial, I will show you how I flashed an ESP8266 with Tasmota firmware.</p><h2 id="step-1-%F0%9F%93%A5-download-esp-flasher-tasmota">Step 1: <strong>&#x1F4E5; </strong>Download ESP Flasher &amp; Tasmota</h2><ul><li>ESP Flasher: <a href="https://github.com/Jason2866/ESP_Flasher/releases">github repo</a>, and download the appropriate version of ESP Flasher (no need to install)</li><li>Tasmota firmware: <a href="http://ota.tasmota.com/tasmota/release/">tasmota.bin.gz</a></li></ul><h2 id="step-2-%F0%9F%94%8C-plug-esp8266-to-your-computer-in-boot-mode">Step 2: &#x1F50C; Plug ESP8266 to your computer in Boot Mode</h2><p>Plug the ESP8266&apos;s USB to your computer, while pressing the <strong>Flash button</strong> simultaneously.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/esp8266-flash-button.jpeg" class="kg-image" alt="&#x26A1; Flashing ESP8266 with Tasmota, in 5 steps" loading="lazy" width="517" height="885"><figcaption>ESP8266 Flash Button</figcaption></figure><h2 id="step-3-%E2%9A%A1flashing">Step 3: &#x26A1;Flashing</h2><ul><li>Reload the Serial Port until you see your USB plug appearing</li><li>Browse the firmware Tasmota we downloaded locally in Step 1</li><li>Launch ESP-Flasher</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/07/esp-flasher.png" class="kg-image" alt="&#x26A1; Flashing ESP8266 with Tasmota, in 5 steps" loading="lazy" width="837" height="762" srcset="https://catchtheblock.com/content/images/size/w600/2021/07/esp-flasher.png 600w, https://catchtheblock.com/content/images/2021/07/esp-flasher.png 837w" sizes="(min-width: 720px) 720px"><figcaption>ESP-Flasher Tool</figcaption></figure><p>This process could take up to 30 sec. </p><p>Once done, unplug, and replug the ESP8266 to the computer or any other source of power.</p><h2 id="step-4-%F0%9F%93%A1-wifi-connection">Step 4: &#x1F4E1; WiFi Connection</h2><ul><li>Once relaunched, you should see a &quot;Tasmota_XXX&quot; WiFi appearing in your networks.</li><li>Connect your computer to the Tasmota WiFi</li><li>Connect your WiFi (SSID + Password)</li><li>Click Ok</li><li>Let the component restart</li></ul><h2 id="step-5-%F0%9F%94%A5-tasmota-configuration">Step 5: &#x1F525; Tasmota Configuration</h2><p>Configure MQTT Broker accordingly (host + port + login + password)</p>]]></content:encoded></item><item><title><![CDATA[✉️ How to Setup Mailgun in Ghost (self hosted, docker-compose)]]></title><description><![CDATA[This short blog post aims at helping those who are struggling (like me ) to setup properly Ghost and emails (using Mailgun).]]></description><link>https://catchtheblock.com/how-to-setup-mailgun-in-ghost-self-hosted-docker-compose/</link><guid isPermaLink="false">6280fc5eea34c90001842857</guid><category><![CDATA[tech]]></category><category><![CDATA[ghost]]></category><category><![CDATA[mailgun]]></category><category><![CDATA[self hosted]]></category><category><![CDATA[docker]]></category><category><![CDATA[docker-compose]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Sun, 15 May 2022 16:15:00 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2022/05/Frame-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2022/05/Frame-2.png" alt="&#x2709;&#xFE0F; How to Setup Mailgun in Ghost (self hosted, docker-compose)"><p>This short blog post aims at helping those who are struggling (like me ) to setup properly Ghost and emails (using <a href="https://www.mailgun.com/">Mailgun</a>).</p><p>I didn&apos;t find a lot of examples online, thus, I hope this methodology will help some people.</p><h2 id="mailgun">Mailgun</h2><blockquote>Mailgun is a Powerful APIs that enable you to send, receive and track email effortlessly</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/image-1.png" class="kg-image" alt="&#x2709;&#xFE0F; How to Setup Mailgun in Ghost (self hosted, docker-compose)" loading="lazy" width="1532" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-1.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/image-1.png 1000w, https://catchtheblock.com/content/images/2022/05/image-1.png 1532w" sizes="(min-width: 720px) 720px"><figcaption>Mailgun Homepage</figcaption></figure><p>First of all, you have to know that I could setup Ghost with the free version of Mailgun. Actually, it&apos;s only working as a sandbox, and cannot be used to send transaction emails...</p><p>Here is the error I get when I&apos;m using the sandbox domain.</p><pre><code class="language-shell">Failed to send email. Reason: Data command failed - 421 Domain sandboxf3d5782960c94fb0ab88532620e41c77.mailgun.org is not allowed to send: Sandbox subdomains are for test purposes only. Please add your own domain or add the address to authorized recipients in Account Settings..</code></pre><p>Thus, once you created your account in Mailgun (including you credit card &#x1F911;), you will be able to create a new domain (if you keep the free version, you won&apos;t see the Add Domain Button).</p><p>Now go to:</p><ol><li>Sending menu</li><li>Domains submenu</li><li>Add New Domain button</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-5.png" class="kg-image" alt="&#x2709;&#xFE0F; How to Setup Mailgun in Ghost (self hosted, docker-compose)" loading="lazy" width="1848" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-5.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-5.png 1000w, https://catchtheblock.com/content/images/size/w1600/2022/05/Group-5.png 1600w, https://catchtheblock.com/content/images/2022/05/Group-5.png 1848w" sizes="(min-width: 720px) 720px"><figcaption>Mailgun - Step 1: Add New Domain</figcaption></figure><p>Then, </p><ol><li>Edit your Domain name as in the illustration I&apos;m using <em>myawesome.website</em> </li><li>Select the appropriate domain region</li><li>Add Domain</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-6.png" class="kg-image" alt="&#x2709;&#xFE0F; How to Setup Mailgun in Ghost (self hosted, docker-compose)" loading="lazy" width="1848" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-6.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-6.png 1000w, https://catchtheblock.com/content/images/size/w1600/2022/05/Group-6.png 1600w, https://catchtheblock.com/content/images/2022/05/Group-6.png 1848w" sizes="(min-width: 720px) 720px"><figcaption>Mailgun - Step 2: more info about the new Domain you want to add</figcaption></figure><p>The next page will show you the DNS records to add to your host.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/Group-7-1.png" class="kg-image" alt="&#x2709;&#xFE0F; How to Setup Mailgun in Ghost (self hosted, docker-compose)" loading="lazy" width="1848" height="1139" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/Group-7-1.png 600w, https://catchtheblock.com/content/images/size/w1000/2022/05/Group-7-1.png 1000w, https://catchtheblock.com/content/images/size/w1600/2022/05/Group-7-1.png 1600w, https://catchtheblock.com/content/images/2022/05/Group-7-1.png 1848w" sizes="(min-width: 720px) 720px"><figcaption>Mailgun - Step 3: add and update DNS records</figcaption></figure><p>Depending on your Host solution, you could have to wait up to 24 hours to ensure 100% propagation of the new &amp; updated DNS records.</p><p>To check if it&apos;s properly deployed, you can use the Verify DNS settings in the Mailgun dashboard.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2022/05/image-2.png" class="kg-image" alt="&#x2709;&#xFE0F; How to Setup Mailgun in Ghost (self hosted, docker-compose)" loading="lazy" width="163" height="44"><figcaption>Mailgun - Step 4: verify DNS settings</figcaption></figure><p>Once these are good, you will be redirected to method (API vs SMTP). (don&apos;t have printscreen for that part). In our case, we will chose the SMTP methodology.</p><p>Mailgun will generate credentials we will need to add to our Ghost docker-compose.</p><h2 id="docker-compose-update">Docker-compose Update</h2><p>When using Docker image, Ghost is not using a config file (config.production.json), but mails settings must be referenced using ENV variables.</p><p>(Source: <a href="https://ghost.org/docs/config/#running-ghost-with-config-env-variables">https://ghost.org/docs/config/#running-ghost-with-config-env-variables</a>).</p><p>Here is my updated docker-compose.yml file:</p><pre><code class="language-yml">version: &apos;3&apos;
services:
  ghost:
    image: ghost:4-alpine
    ports:
      - ****:2368
    environment:
      url: https://myawesome.website
      mail__transport: SMTP
      mail__options__service: Mailgun
      mail__options__host: smtp.eu.mailgun.org
      mail__options__port: 587
      mail__options__auth__user: postmaster@myawesome.website
      mail__options__auth__pass: ************
    volumes:
      - ./data:/var/lib/ghost/content
    restart: unless-stopped
    [...]
</code></pre><p>Save and you should be good.</p><p>Now let&apos;s restart our docker-compose.yml:</p><pre><code class="language-shell">docker-compose up</code></pre><p>And try create a new users.</p><p>You should now receive the subscription confirmation email.</p><p>Well done, you have now your emails working :-).</p>]]></content:encoded></item><item><title><![CDATA[🍓 Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04]]></title><description><![CDATA[Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04]]></description><link>https://catchtheblock.com/raspberry-pi-headless-setup-in-9-steps-with-ubuntu-21-04/</link><guid isPermaLink="false">62810909ea34c9000184298f</guid><category><![CDATA[tech]]></category><category><![CDATA[raspberry]]></category><category><![CDATA[raspberry pi]]></category><category><![CDATA[ubuntu]]></category><category><![CDATA[ubuntu 21.04]]></category><category><![CDATA[flash]]></category><category><![CDATA[headless]]></category><category><![CDATA[setup]]></category><category><![CDATA[raspberry pi imager]]></category><category><![CDATA[ssh]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Sun, 15 May 2022 14:24:59 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2022/05/Frame-4.png" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2022/05/Frame-4.png" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04"><p>Hold-on, if you don&apos;t have a Raspberry Pi, yet, I can recommend these:</p><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B0899VXM8F&amp;asins=B0899VXM8F&amp;linkId=e198d2a5f022a0317a1c0a078e9fd938&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><h2 id="step-1-%F0%9F%8D%93-get-raspberry-pi-imager">Step 1: &#x1F353; Get Raspberry Pi Imager</h2><p>The Raspberry Pi Imager is used to install the OS on the microSD card. This program is compatible with MacOS, Windows, and Linux (click here to download).</p><h2 id="step-2-%F0%9F%94%8C-connect-your-microsd-card-to-your-computer">Step 2: &#x1F50C; Connect your microSD card to your computer</h2><p>A microSD Card reader may be required depending on your computer setup.<br>I&apos;m using this docker because I&apos;m on a Mac:</p><!--kg-card-begin: html--><iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=FR&amp;source=ss&amp;ref=as_ss_li_til&amp;ad_type=product_link&amp;tracking_id=catchtheblock-21&amp;language=fr_FR&amp;marketplace=amazon&amp;region=FR&amp;placement=B08BLQMWSD&amp;asins=B08BLQMWSD&amp;linkId=5d1662d529c788aaf942679b9c334bed&amp;show_border=true&amp;link_opens_in_new_window=true"></iframe><!--kg-card-end: html--><h2 id="step-3-%F0%9F%94%A5-flash-the-card-with-ubuntu-2104">Step 3: &#x1F525; Flash the Card with Ubuntu 21.04</h2><p>Launch the Raspberry Pi Imager tool.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-4.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="494" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-4.png 600w, https://catchtheblock.com/content/images/2022/05/image-4.png 700w"></figure><p>Depending on your Raspberry Pi, you&apos;ll need to select the appropriate operating system (64-bit vs 32-bit). I&apos;m using the 64-bit version in this situation).</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-5.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="494" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-5.png 600w, https://catchtheblock.com/content/images/2022/05/image-5.png 700w"></figure><p>Now it&apos;s time to select the SD Card (be careful to select the correct one!).</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-6.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="494" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-6.png 600w, https://catchtheblock.com/content/images/2022/05/image-6.png 700w"></figure><p>Now that we&apos;re ready, we can click on the write button to flash the SD card.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-7.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="494" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-7.png 600w, https://catchtheblock.com/content/images/2022/05/image-7.png 700w"></figure><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-8.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="494" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-8.png 600w, https://catchtheblock.com/content/images/2022/05/image-8.png 700w"></figure><p>Your microSD card will be flashed after a few minutes of writing and validating.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-9.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="494" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-9.png 600w, https://catchtheblock.com/content/images/2022/05/image-9.png 700w"></figure><h2 id="step-4-%F0%9F%93%A1-establish-a-wifi-connection">Step 4: &#x1F4E1; Establish a WiFi connection</h2><p>Eject the microSD card and reconnect it to your computer.</p><p>Now look for the &quot;network-config&quot; file in the microSD card directory (in the root folder).</p><p>Use your favorite IDE to open it. In this tutorial, I&apos;ll be utilizing Visual Studio Code.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-10.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="700" height="527" srcset="https://catchtheblock.com/content/images/size/w600/2022/05/image-10.png 600w, https://catchtheblock.com/content/images/2022/05/image-10.png 700w"></figure><p>The initial content of this file should look like this:</p><pre><code>#[...] some comments
version: 2
ethernets:
  eth0:
    dhcp4: true
    optional: true
#wifis:
#  wlan0:
#    dhcp4: true
#    optional: true
#    access-points:
#      myhomewifi:
#        password: &quot;S3kr1t&quot;
#      myworkwifi:
#        password: &quot;correct battery horse staple&quot;
#      workssid:
#        auth:
#          key-management: eap
#          method: peap
#          identity: &quot;me@example.com&quot;
#          password: &quot;passw0rd&quot;
#          ca-certificate: /etc/my_ca.pem</code></pre><p>As you can see, a section dedicated to wifis has already been written and commented on.</p><p>Edit the file as following:</p><pre><code>version: 2
ethernets:
  eth0:
    dhcp4: true
    optional: true
wifis:
  wlan0:
  dhcp4: true
  optional: true
  access-points:
    your_wifi_name:
    password: &quot;your_password&quot;</code></pre><p>Save the file and remove the microSD card from your computer correctly.</p><h2 id="step-5-%F0%9F%8F%81-turn-on-your-raspberry-pi">Step 5: &#x1F3C1; Turn on your Raspberry Pi.</h2><p>Let&apos;s plug the microSD card back into the Raspberry Pi and turn it on now that we have a correctly flashed microSD card and a wifi connection.</p><h2 id="step-6-%F0%9F%8F%A0-determine-the-ip-address-of-your-raspberry-pi">Step 6: &#x1F3E0; Determine the IP address of your Raspberry Pi.</h2><p>To connect to our Raspberry Pi, we must first determine its IP address.</p><p>There are several options here. The simplest method is to connect to your internet provider&apos;s box and look for our Raspberry Pi&apos;s new Ubuntu Server.</p><p>Here we have:</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2022/05/image-11.png" class="kg-image" alt="&#x1F353; Raspberry Pi Headless Setup in 9 Steps with Ubuntu 21.04" loading="lazy" width="374" height="75"></figure><h2 id="step-7-%F0%9F%9B%B0%EF%B8%8F-ssh-connection">Step 7: &#x1F6F0;&#xFE0F; SSH connection</h2><h3 id="what-exactly-is-an-ssh-connection">What exactly is an SSH connection?</h3><blockquote>SSH is often used to log into a remote machine and perform commands, according to Wikipedia.</blockquote><p><br>Open a Terminal command now.</p><pre><code class="language-shell">ssh ubuntu@192.168.1.45</code></pre><p>The default login is ubuntu, and @192.. is the IP address we found in the previous step.</p><pre><code class="language-shell">The authenticity of host &apos;192.168.1.45 (192.168.1.45)&apos; can&apos;t be established.
ECDSA key fingerprint is SHA256:xxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?</code></pre><p>Type Yes.</p><p>Ubuntu is also the default password. After your first sign-in, you&apos;ll be prompted to change your password.</p><p>The connection will be immediately ended after the new password has been set. The ssh connection must be restarted with the new password you specified.</p><h2 id="step-8-%F0%9F%8D%BF-enjoy">Step 8: &#x1F37F; Enjoy</h2><p>You&apos;re ready to go.</p><h2 id="comment-%E2%98%9D">Comment &#x261D;</h2><p>Remember that we didn&apos;t give our Raspberry Pi a static IP address. </p><p>It means that the IP address will be updated dynamically (DHCP) over time.<br>Please see my next article if you require a static IP address (soon).</p><h2 id="post-scriptum"><br>Post Scriptum</h2><p>I recommend viewing this video if you want to learn more about the process.</p><p>&#x1F449; <a href="https://www.youtube.com/watch?v=dJTqd90bwsI">https://www.youtube.com/watch?v=dJTqd90bwsI</a></p>]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 9/10] - Web3 & Metamask 🦊]]></title><description><![CDATA[<h2 id="what-is-metamask">What is Metamask?</h2><blockquote>Metamask is a crypto wallet and a gateway to blockchain apps</blockquote><p>More information on their website <a href="https://metamask.io/">here</a>.</p><h2 id="how-is-metamask-included-in-our-process">How is Metamask included in our process?</h2><p>When a transaction occurs, the frontend will send a signing request to Metamask. Then Metamask will ask the end user for signing or</p>]]></description><link>https://catchtheblock.com/web3-serie-part-9-10-web3-metamask/</link><guid isPermaLink="false">6131199ed125b10001e218ff</guid><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Tue, 14 Sep 2021 20:36:17 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-9.png" medium="image"/><content:encoded><![CDATA[<h2 id="what-is-metamask">What is Metamask?</h2><blockquote>Metamask is a crypto wallet and a gateway to blockchain apps</blockquote><img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-9.png" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;"><p>More information on their website <a href="https://metamask.io/">here</a>.</p><h2 id="how-is-metamask-included-in-our-process">How is Metamask included in our process?</h2><p>When a transaction occurs, the frontend will send a signing request to Metamask. Then Metamask will ask the end user for signing or refusing the transaction. </p><p>If the user accepts the transaction, Metamask will sign it before sending it to the chosen blockchain. Metamask can connect to various networks such as the Mainnet, Public Testnet (Kovan, Ropsten, etc.), or even our local Blockchain.</p><p>Metamask will take care itself how to send the transaction to the required network, using Infura for instance when the chosen network is Mainnet or Public Testnet.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/image-2.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="719" height="548" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-2.png 600w, https://catchtheblock.com/content/images/2021/09/image-2.png 719w"><figcaption>Process Overview including Metamask</figcaption></figure><h2 id="how-to-install-metamask">How to install Metamask?</h2><p>Installing Metamask is quite easy.</p><ol><li>Open Google Chrome or any other supported Browers (Chrome, Firefox, Brave, or Edge)</li><li>Add the Metamask extension, using this <a href="https://metamask.io/download">link</a></li><li>Follow the installation steps (don&apos;t forget to keep secret and in a safe place your Secret Backup Phrase)</li><li>Once installed you should be connected to the Ethereum Mainnet by default, on the Account 1</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/image-3.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="356" height="599"><figcaption>Metamask after installation Overview</figcaption></figure><p>By clicking to the top, where it&apos;s written &apos;R&#xE9;seau Principal Ethereum&apos;, you will see various available networks, as well as Custom RPC (mine is in French).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/image-4.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="306" height="483"><figcaption>Metamask Default Configured Networks</figcaption></figure><p>Now that we installed Metamask, we are ready to move on to our scripts.</p><h2 id="signing-transactions-from-an-app-using-metamask">Signing Transactions from an App using Metamask</h2><p>In this section, we will re-use the contract we deployed on Ropsten network, in the section 8.</p><p>We will also use a simple Vue-App to perform the signed transaction. No worries, you don&apos;t need to know Vue to perform this part. We won&apos;t go in details on that front App part.</p><h3 id="setup-vue-app">Setup Vue App</h3><p>First, to use Vue we need a global addon to be installed with the Vue CLI. More info, <a href="https://cli.vuejs.org/guide/prototyping.html">here</a>. Before launching this command, make sure we get the required permission, by switching to Super User mode. (E.g. using mac, we can type the following command, and enter your password).</p><pre><code>sudo su</code></pre><p>Then, we run:</p><pre><code>npm install -g @vue/cli @vue/cli-service-global</code></pre><p>Once installed, we can create our Vue App, by running the following command:</p><pre><code>vue create client</code></pre><p>In the menu, we select the Default Vue2 option:</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-5.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="349" height="193"></figure><p>Actually, we ask Vue to create a new App named client, using Vue2 here.</p><p>Now, you should have a directory tree similar to:</p><pre><code>&#x251C;&#x2500;&#x2500; client ==&gt; this is what we just created, using create vue client
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; README.md
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; babel.config.js
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; node_modules
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; package-lock.json
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; package.json
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; public
&#x2502;&#xA0;&#xA0; &#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; favicon.ico
&#x2502;&#xA0;&#xA0; &#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; index.html
&#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; src
&#x2502;&#xA0;&#xA0;     &#x251C;&#x2500;&#x2500; App.vue
&#x2502;&#xA0;&#xA0;     &#x251C;&#x2500;&#x2500; assets
&#x2502;&#xA0;&#xA0;     &#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; logo.png
&#x2502;&#xA0;&#xA0;     &#x251C;&#x2500;&#x2500; components
&#x2502;&#xA0;&#xA0;     &#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; HelloWorld.vue
&#x2502;&#xA0;&#xA0;     &#x2514;&#x2500;&#x2500; main.js
&#x2514;&#x2500;&#x2500; contract ==&gt; where our contract stuff are stored (cf. part 8)</code></pre><p>Let&apos;s clean a bit before going further.</p><p>In the client, directory, we find the &apos;HelloWorld.vue&apos; components:</p><pre><code>client/src/components/HelloWorld.vue</code></pre><p>We delete everything, and we paste the following code:</p><pre><code>&lt;template&gt;
  &lt;div&gt;
    &lt;button&gt;SendTransaction&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  
}</code></pre><p>In our terminal, in the client directory, we run </p><pre><code>npm run serve</code></pre><p>We have the following result:</p><pre><code>&gt; client@0.1.0 serve
&gt; vue-cli-service serve

 INFO  Starting development server...
98% after emitting CopyPlugin

 DONE  Compiled successfully in 1828ms                                                                                             21:08:18


  App running at:
  - Local:   http://localhost:8082/ 
  - Network: http://192.168.1.6:8082/

  Note that the development build is not optimized.
  To create a production build, run npm run build.</code></pre><p>Now, we go to the Network address &apos;<a href="http://192.168.1.6:8082/">http://192.168.1.6:8082/</a>&apos; and we make sure we have the following result:</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-6.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="1238" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-6.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-6.png 1000w, https://catchtheblock.com/content/images/2021/09/image-6.png 1238w" sizes="(min-width: 720px) 720px"></figure><p>We can see a SendTransaction button under the Vue logo.</p><p>Now let&apos;s code the interaction with Metamask. </p><p>We will split the next steps, in 2 parts: connect Metamask with our App, and then send a signed transaction. In our case, the transaction will consist in setting a new value using the set function.</p><p>In the next lines, I will do my best avoiding going in the Vue details, which is not the aim of the course.</p><h2 id="connect-metamask-with-our-vue-app">Connect Metamask with our Vue App</h2><p>First, we need to install some libraries: </p><ul><li>the Metamask &apos;<a href="https://docs.metamask.io/guide/ethereum-provider.html">detect-provider</a>&apos; libray and,</li><li>the <a href="https://web3js.readthedocs.io/en/v1.4.0/">Web3</a> library</li></ul><p> In our client directory, we run the following command in our terminal:</p><pre><code>npm install @metamask/detect-provider web3</code></pre><p>Now, we successfully installed the 2 libraries.</p><p>Here the updated &apos;HelloWorld.vue&apos; code. Comments are following.</p><pre><code>&lt;template&gt;
  &lt;div&gt;
    &lt;div &gt;{{ accounts[0] }}&lt;/div&gt;
    &lt;button&gt;SendTransaction&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import detectEthereumProvider from &apos;@metamask/detect-provider&apos;; 
import Web3 from &apos;web3&apos;;
import MyContract from &apos;../../../contract/build/contracts/MyContract.json&apos;;

export default {
  data() {
    return {
      contractAbi: MyContract.abi,
      contractAddress: &quot;0xe49082b47dA1f0E9FAEfc6463f0ef9aA114657A8&quot;,
      provider: &apos;&apos;,
      web3: &apos;&apos;,
      contract: &apos;&apos;,
      accounts: &apos;&apos;,
    }
  },

  async mounted() {
    await this.setup();
    this.provider = await detectEthereumProvider();
    if(this.provider){
      await this.getAccounts();
    }else{
      console.log(&apos;Please, Install Metamask!&apos;);
    }

  },

  methods: {
    async setup(){
      this.web3 = new Web3(window.ethereum);
      this.contract = new this.web3.eth.Contract(this.contractAbi, this.contractAddress);
    },

    async getAccounts(){
      this.accounts = await this.provider.request(
        {
          method: &apos;eth_requestAccounts&apos;,
        }
      )
    }
  }
}
&lt;/script&gt;</code></pre><p>For those who don&apos;t know Vue structure, .vue file are split into 2 main parts: the template, and the scripts. Here the template part is our HTML displaying the button, while the script part will include our Metamask logic.</p><p>Importations:</p><ul><li>We import the 2 libraries, we previously installed</li><li>We import our contract ABI we build in the part 8 of the course.</li></ul><p>In the data part, we define several variables we will be using:</p><ul><li>contractAbi: our contract generated ABI when we built and migrated our contract to the Ropsten network (cf. part 8).</li><li>contractAddress: our contract address is stored here. this is the address we got when we deployed our contract on the Ropsten network (cf. part 8) (if you lost it, please restart the deployment part to the Ropsten network. You will get a new address).</li><li>provider: our provider instance will be stored here</li><li>web3: our web3 instance will be stored here</li><li>contract: our contract instance will be stored here</li><li>accounts: this variable will be used to store the connected account(s) address with Metamask. In our case, it will include only one address. But, if we would connect several accounts with Metamask, they would be store in the accounts array.</li></ul><p>Now, let&apos;s generate the different required instances, and store them into our lovely variables. For this part, we need different methods:</p><p><strong>setup function</strong></p><ul><li>we instantiate our web3 using the <a href="https://docs.metamask.io/guide/ethereum-provider.html#basic-usage">window.ethereum</a> provider (detect the Ethereum provider) provided by Metamask.</li><li>we instantiate our contract using web3 instance, our contract ABI (&apos;including functions, and variables of our Smart Contract&apos;), and our contract address (&apos;where our contract is stored in the Ropsten Network&apos;).</li></ul><p><strong>getAccounts</strong></p><ul><li>Using the ethereum.request methods (more info from Metamask doc <a href="https://docs.metamask.io/guide/ethereum-provider.html#methods">here</a>), we ask Metamask to provide us with the list of connected accounts. This will be useful to sign the transaction later.</li></ul><p>Now, in the &apos;mounted&apos; part (part of the Vue lifecycle when the page is mounted. For those who are not familiar with Vue, keep in mind that this part will be ran when we load the page, more info <a href="https://vuejs.org/images/lifecycle.png">here</a>.), we need to run our methods to connect Metamask with our App, and get the available accounts:</p><ul><li>First we ran our setup method, to connect Metamask with our Vue App</li><li>Then, we detect the provider provided by Metamask. If available we collect the connected accounts addresses, else, we ask our user to install Metamask.</li></ul><p>Now, we successfully connected Metamask with our Vue App, and collected the available accounts.</p><p>When reloading your Vue App, we should see Metamask appearing, asking to select account(s) to connect with the App. We select an account (with some Faucet ETH), click Next, and Connect.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-7.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="1326" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-7.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-7.png 1000w, https://catchtheblock.com/content/images/2021/09/image-7.png 1326w" sizes="(min-width: 720px) 720px"></figure><p>We can see that we are successfully connected:</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-8.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="1326" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-8.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-8.png 1000w, https://catchtheblock.com/content/images/2021/09/image-8.png 1326w" sizes="(min-width: 720px) 720px"></figure><p>In the template, we print our accounts[0] value, to see that we are well connected.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-10.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="1419" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-10.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-10.png 1000w, https://catchtheblock.com/content/images/2021/09/image-10.png 1419w" sizes="(min-width: 720px) 720px"></figure><p>Please bear with me, we are close to our objective.</p><h2 id="send-signed-transaction-to-our-smart-contract">Send Signed Transaction to our Smart Contract</h2><p>To keep things simple, by pressing the button &apos;SendTransaction&apos; we created, we will change the uint in our contract from 10 to let&apos;s say 100.</p><p>Let&apos;s code it.</p><p>Now that we are connected, and we have the account address, we can send a signed transaction to our contract by simply adding the following function to our script part. Here are the updates to perform in our code. Comments are following.</p><p>In the data part, we add a new variable called message, with the value we want to set in our Smart Contract, 100.</p><pre><code>data() {
    return {
      contractAbi: MyContract.abi,
      contractAddress: &quot;0xe49082b47dA1f0E9FAEfc6463f0ef9aA114657A8&quot;,
      provider: &apos;&apos;,
      web3: &apos;&apos;,
      contract: &apos;&apos;,
      accounts: &apos;&apos;,
      message: 100,
    }
  },</code></pre><p>In the methods, we add a new method called setNewValue. Comments are following.</p><pre><code>async setNewValue(){
      const receipt = await this.contract.methods.set(this.message.toString()).send({
        from: this.accounts[0],
      });
      console.log(receipt);
    }</code></pre><ul><li>We use our contract instance, selecting the &apos;set&apos; method, and we send the new value stored in the message variable, that we convert into a String.</li><li>As parameter, we add the source accounts</li><li>Finally, we console log the receipt of the transaction.</li></ul><p>Now we need to link this method with our button, by updating the code as following:</p><pre><code>&lt;template&gt;
  &lt;div&gt;
    &lt;div &gt;{{ accounts[0] }}&lt;/div&gt;
    &lt;button @click=&quot;setNewValue&quot;&gt;SendTransaction&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;</code></pre><p>Now, in our App, we can click on the SendTransaction button. A Metamask window opens showing us our transaction details, and the gas fees we will pay to process the transaction.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-9.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="472" height="732"></figure><p>Click on Confirm, and now let&apos;s wait a couple of seconds/minutes.</p><p>In our Chrome Console (right click in the page &gt; inspect), we should see the Transaction receipt console.log when the transaction will be fully processed.</p><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-11.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="1419" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-11.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-11.png 1000w, https://catchtheblock.com/content/images/2021/09/image-11.png 1419w" sizes="(min-width: 720px) 720px"></figure><p>Let&apos;s check in Ropsten Etherscan, if we see our new value of 100 instead of 10.</p><ul><li>Go on <a href="https://ropsten.etherscan.io/">https://ropsten.etherscan.io/</a></li><li>Paste our Contract Address, in this case: 0xe49082b47dA1f0E9FAEfc6463f0ef9aA114657A8</li><li>We can see our transaction on the top of the table</li><li>Click on the transaction &gt; click to see more &gt; Decode Input Data</li></ul><figure class="kg-card kg-image-card"><img src="https://catchtheblock.com/content/images/2021/09/image-12.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 9/10] - Web3 &amp; Metamask &#x1F98A;" loading="lazy" width="1543" height="1192" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-12.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-12.png 1000w, https://catchtheblock.com/content/images/2021/09/image-12.png 1543w" sizes="(min-width: 720px) 720px"></figure><p>Hurra! &#xA0;We successfully send a signed transaction using Metamask on the Ropsten Network.</p><p>Here is the HelloWorld.vue full and final code:</p><pre><code>&lt;template&gt;
  &lt;div&gt;
    &lt;div &gt;{{ accounts[0] }}&lt;/div&gt;
    &lt;button @click=&quot;setNewValue&quot;&gt;SendTransaction&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import detectEthereumProvider from &apos;@metamask/detect-provider&apos;; 
import Web3 from &apos;web3&apos;;
import MyContract from &apos;../../../contract/build/contracts/MyContract.json&apos;;

export default {
  data() {
    return {
      contractAbi: MyContract.abi,
      contractAddress: &quot;0xe49082b47dA1f0E9FAEfc6463f0ef9aA114657A8&quot;,
      provider: &apos;&apos;,
      web3: &apos;&apos;,
      contract: &apos;&apos;,
      accounts: &apos;&apos;,
      message: 100,
    }
  },

  async mounted() {
    await this.setup();
    this.provider = await detectEthereumProvider();
    if(this.provider){
      await this.getAccounts();
    }else{
      console.log(&apos;Please, Install Metamask!&apos;);
    }

  },

  methods: {
    async setup(){
      this.web3 = new Web3(window.ethereum);
      this.contract = new this.web3.eth.Contract(this.contractAbi, this.contractAddress);
    },

    async getAccounts(){
      this.accounts = await this.provider.request(
        {
          method: &apos;eth_requestAccounts&apos;,
        }
      )
    },

    async setNewValue(){
      const receipt = await this.contract.methods.set(this.message.toString()).send({
        from: this.accounts[0],
      });
      console.log(receipt);
    }
  }
}
&lt;/script&gt;</code></pre><p></p><p>This is the end of the Web3 course. I hope you enjoyed it. Feel free to contact me if you had any questions, our improvement comments. Always keen to learn! Enjoy.</p>]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 7/10] - Listen to Smart Contract Events]]></title><description><![CDATA[<h2 id="introduction">Introduction</h2><h3 id="what-is-an-event">What is an Event?</h3><blockquote>An event emits data from a Smart Contract, when a transaction occurs.</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh3.googleusercontent.com/HVx9VXTnBIFqKtluOg3n97YtJFEDDNVIRf4_j41EHdU5cFv287bhIShcL3fdJ2fBC-dzF8WyRevdKbFQO6JjXHnWQJlHXzKWaw3xOc-wHt5P4YHSQl8jtc0HjicHUqDtB5XMv_S8=s0" class="kg-image" alt="Ethereum Smart Contracts Emitting Event Overview" loading="lazy"><figcaption>Ethereum Smart Contracts Emitting Event Overview</figcaption></figure><p>This is useful when you need to monitor certain transactions and update your Web App, for instance.</p><p>It&#x2019;s important to note that events are <strong><u>inheritable</u></strong></p>]]></description><link>https://catchtheblock.com/web3-serie-part-7-10-listen-to-smart-contract-evenets/</link><guid isPermaLink="false">612fd520d125b10001e217da</guid><category><![CDATA[web3]]></category><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[smart contract]]></category><category><![CDATA[events]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 01 Sep 2021 19:40:52 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-7.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><h3 id="what-is-an-event">What is an Event?</h3><blockquote>An event emits data from a Smart Contract, when a transaction occurs.</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh3.googleusercontent.com/HVx9VXTnBIFqKtluOg3n97YtJFEDDNVIRf4_j41EHdU5cFv287bhIShcL3fdJ2fBC-dzF8WyRevdKbFQO6JjXHnWQJlHXzKWaw3xOc-wHt5P4YHSQl8jtc0HjicHUqDtB5XMv_S8=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 7/10] - Listen to Smart Contract Events" loading="lazy"><figcaption>Ethereum Smart Contracts Emitting Event Overview</figcaption></figure><img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-7.png" alt="&#x1F9F0; Web3 [Serie Part 7/10] - Listen to Smart Contract Events"><p>This is useful when you need to monitor certain transactions and update your Web App, for instance.</p><p>It&#x2019;s important to note that events are <strong><u>inheritable</u></strong>, and when generated they are not accessible from within contracts, not even the one which has created and emitted them.</p><p>If you need more details, have a look to the Solidity&apos;s events doc, <a href="https://docs.soliditylang.org/en/v0.8.7/contracts.html#events">here</a>.</p><p>In the next sections we will go through 3 methods to read/listen to events.</p><h2 id="method-1trigger-emit-event-via-a-transaction">Method 1 - Trigger <u>Emit</u> Event via a Transaction</h2><p>In our contracts directory, we create a new file called MyContract3.sol . Here is the Smart Contract we will be using. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Solidity">pragma solidity &gt;=0.4.16 &lt;0.9.0;

contract MyContract3 {
    event MyPayment (
        uint indexed date,
        address indexed from,
        address indexed to,
        uint amount
    );

    function payment(address to, uint amount) external {
        emit MyPayment(block.timestamp, msg.sender, to, amount);
    }
} </code></pre><figcaption>MyContract3.sol</figcaption></figure><p>In this solidity script, we are defining a function called Payment. This payment function is simulating a token transfer from an address to another, and will emit an Event when the function is called.</p><p>Thus, we define an event called MyPayment first. Each &apos;MyPayment&apos; event will include 4 parameters:</p><ol><li>Date: the date when the event occured (integer in Solidity)</li><li>From: the address which triggered the event</li><li>To: the target address of the payment</li><li>Amount: the amount of payment</li></ol><h3 id="what-is-indexed">What is indexed?</h3><p>From <a href="https://docs.soliditylang.org/en/v0.8.7/contracts.html?highlight=indexed#events">Solidity Docs</a> we can read:</p><blockquote>&quot;You can add the attribute indexed to up to three parameters which adds them to a special data structure known as &#x201C;topics&#x201D; instead of the data part of the log. [...] Topics allow you to search for events, for example when filtering a sequence of blocks for certain events.&quot;</blockquote><p>Now, we can add the MyContract3.sol in our migration file 2_contract_deploy.js.</p><p>Here is the updated migration file:</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const MyContract = artifacts.require(&apos;MyContract&apos;);
const MyContract2 = artifacts.require(&apos;MyContract2&apos;);
const MyContract3 = artifacts.require(&apos;MyContract3&apos;);

module.exports = function(deployer){
    deployer.deploy(MyContract);
    deployer.deploy(MyContract2);
    deployer.deploy(MyContract3);
}</code></pre><figcaption>Updated 2_contract_deploy.js</figcaption></figure><p>Now, we can run the truffle migrate command to deploy our new MyContract3 to our local Blockchain.</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">truffle migrate --reset</code></pre><figcaption>migration command with truffle</figcaption></figure><p>We can see that our MyContract3.sol has been successfully migrated thanks to the output in terminal:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">Deploying &apos;MyContract3&apos;
   -----------------------
   &gt; transaction hash:    0x1c167be3bb3c551e015101aa09b977b927b3a49befe411eef089252ec0f382e9
   &gt; Blocks: 0            Seconds: 0
   &gt; contract address:    0xded0Ab79D2ECe65a6dC08885608804e9c5e80b75
   &gt; block number:        11
   &gt; block timestamp:     1630570766
   &gt; account:             0x65ca5ECfd87FaaFE35F63244133EFE9EDF2ABF55
   &gt; balance:             98.97514394
   &gt; gas used:            113737 (0x1bc49)
   &gt; gas price:           20 gwei
   &gt; value sent:          0 ETH
   &gt; total cost:          0.00227474 ETH</code></pre><figcaption>Terminal output after migrating MyContract3.sol using Truffle</figcaption></figure><p>Now, we can move on with our JS Script. Let&apos;s create a new index, called index3.js. Here is the code to paste in. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract3 = require(&apos;./build/contracts/MyContract3.json&apos;);

const init = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);
    
    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract3.abi,
        MyContract3.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

    const receipt = await contract.methods.payment(accounts[0], &apos;1000000000000000000&apos;).send({
        from: accounts[1],
    })
    console.log(receipt.events);
}

init();</code></pre><figcaption>index3.js</figcaption></figure><p>First, we import our MyContract3. Then, create our web3, and contract instances.</p><p>Next, we get the accounts addresses from Ganache, and finally we call our new &apos;payment&apos; method. As defined in our MyContract3.sol, we input the 2 required parameters (from and amount), and we send the transaction.</p><p>In our Terminal, we can see the following output, since we console.logged our receipt.events.</p><figure class="kg-card kg-code-card"><pre><code class="language-Shell">{
  MyPayment: {
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: &apos;0x3bc0cad631bee6e061f4b36a7a0c358831cde0edf7e05abae7dcc6a8a8ce76a0&apos;,
    blockHash: &apos;0x083ece81a048cda77732aac4358e53b7dfffa1a7429fef03b0c4aff4258287d7&apos;,
    blockNumber: 13,
    address: &apos;0xded0Ab79D2ECe65a6dC08885608804e9c5e80b75&apos;,
    type: &apos;mined&apos;,
    id: &apos;log_d92bbfed&apos;,
    returnValues: Result {
      &apos;0&apos;: &apos;1630571019&apos;,
      &apos;1&apos;: &apos;0x89d48bf3591db71C2EBd7Be9ea86Ce52442E474C&apos;,
      &apos;2&apos;: &apos;0x65ca5ECfd87FaaFE35F63244133EFE9EDF2ABF55&apos;,
      &apos;3&apos;: &apos;1000000000000000000&apos;,
      date: &apos;1630571019&apos;,
      from: &apos;0x89d48bf3591db71C2EBd7Be9ea86Ce52442E474C&apos;,
      to: &apos;0x65ca5ECfd87FaaFE35F63244133EFE9EDF2ABF55&apos;,
      amount: &apos;1000000000000000000&apos;
    },
    event: &apos;MyPayment&apos;,
    signature: &apos;0x3f149fb6578fdbf59cb6fffd764d2994d89b758e8dcadb7b14a8d37a05b90520&apos;,
    raw: {
      data: &apos;0x0000000000000000000000000000000000000000000000000de0b6b3a7640000&apos;,
      topics: [Array]
    }
  }
}</code></pre><figcaption>Receipt.event</figcaption></figure><ul><li>We can read the MyPayment event, the name of our event.</li><li>Then a few lines below, we can read the date, the from &amp; to addresses, and finally the amount.</li></ul><p>It works! Great! </p><h3 id="%F0%9F%91%8E-limitations">&#x1F44E; Limitations</h3><p>Thus, this option works great, but it has a limit. You need to be the sender of the transaction to read the event. Most of the time, it will not happen this way.</p><p>In most cases, we will need to read events triggered by other people.</p><p>Let&#x2019;s move on to the next method.</p><h2 id="method-2getpastevents">Method 2 - <u>getPastEvents</u></h2><p>This method allows us to read all the events that occurred from a Smart Contract. We will still using our MyContract3.sol for this method. The only changes are made in our index3.js file.</p><p>(Before going, further, we will restart our Ganache Local Blockchain. Otherwise we will have noises in the events we will display. Don&apos;t forget to perform the migration using truffle).</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract3 = require(&apos;./build/contracts/MyContract3.json&apos;);

const init = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);
    
    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract3.abi,
        MyContract3.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

	//Triggering Event 1
    await contract.methods.payment(accounts[0], &apos;1000000000000000000&apos;).send({
        from: accounts[1],
    });

	//Triggering Event 2
    await contract.methods.payment(accounts[1], &apos;1000000000000000000&apos;).send({
        from: accounts[2],
    });

    const receipt = await contract.getPastEvents(
        &apos;allEvents&apos;,
        {
            fromBlock: 0
        });

    console.log(receipt);
}

init();

</code></pre><figcaption>Updated index3.js</figcaption></figure><p>In this script, we call twice the payment methods, and thus we emitted twice an event. </p><p>At the end, we call the getPastEvents method. As we can see, we ask for &apos;allEvents&apos;, and we want to search from the block 0, i.e. since the beginning. The &apos;allEvents&apos; could have been replaced by the name of our event, which would have been &apos;MyPayment&apos; in this case. You can try to replace &apos;allEvents&apos; by &apos;MyPayment&apos;, and you will see the same output, including 2 additional events.</p><p>More info about getPastEvents method in web3 docs <a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html?highlight=getpastevents#getpastevents">here</a>.</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">[
  {
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: &apos;0xc8e47f0d25dad437ea866c63d65aee634d6b7cb2d3cef832bb337864a26e9767&apos;,
    blockHash: &apos;0xd0f7c551453fdffd9cf2555c6cf2fb8a5506ccc6bba08b44841457902a175d3c&apos;,
    blockNumber: 15,
    address: &apos;0xaE76c14CF39f32f88985264AC5471745F9150fE2&apos;,
    type: &apos;mined&apos;,
    id: &apos;log_39908cd0&apos;,
    returnValues: Result {
      &apos;0&apos;: &apos;1630595111&apos;,
      &apos;1&apos;: &apos;0x3577B769c0bA9a762211E6F6b006730f8399b231&apos;,
      &apos;2&apos;: &apos;0xbabbE01661c3ac49B3D5B10A890F8DDD5e60eC7f&apos;,
      &apos;3&apos;: &apos;1000000000000000000&apos;,
      date: &apos;1630595111&apos;,
      from: &apos;0x3577B769c0bA9a762211E6F6b006730f8399b231&apos;,
      to: &apos;0xbabbE01661c3ac49B3D5B10A890F8DDD5e60eC7f&apos;,
      amount: &apos;1000000000000000000&apos;
    },
    event: &apos;MyPayment&apos;,
    signature: &apos;0x3f149fb6578fdbf59cb6fffd764d2994d89b758e8dcadb7b14a8d37a05b90520&apos;,
    raw: {
      data: &apos;0x0000000000000000000000000000000000000000000000000de0b6b3a7640000&apos;,
      topics: [Array]
    }
  },
  {
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: &apos;0x3d719b3ed229daf7b693560b46c3d8754859254d8fce47364416a2e390ffcb92&apos;,
    blockHash: &apos;0x5ec007acc00ec909b97f14e0c961cb2c4249f8b270c24bafeaf5addf9277b21b&apos;,
    blockNumber: 16,
    address: &apos;0xaE76c14CF39f32f88985264AC5471745F9150fE2&apos;,
    type: &apos;mined&apos;,
    id: &apos;log_f83c791c&apos;,
    returnValues: Result {
      &apos;0&apos;: &apos;1630595111&apos;,
      &apos;1&apos;: &apos;0x2804795Cfb92516345EABDE87A58b4341004b667&apos;,
      &apos;2&apos;: &apos;0x3577B769c0bA9a762211E6F6b006730f8399b231&apos;,
      &apos;3&apos;: &apos;1000000000000000000&apos;,
      date: &apos;1630595111&apos;,
      from: &apos;0x2804795Cfb92516345EABDE87A58b4341004b667&apos;,
      to: &apos;0x3577B769c0bA9a762211E6F6b006730f8399b231&apos;,
      amount: &apos;1000000000000000000&apos;
    },
    event: &apos;MyPayment&apos;,
    signature: &apos;0x3f149fb6578fdbf59cb6fffd764d2994d89b758e8dcadb7b14a8d37a05b90520&apos;,
    raw: {
      data: &apos;0x0000000000000000000000000000000000000000000000000de0b6b3a7640000&apos;,
      topics: [Array]
    }
  }
]</code></pre><figcaption>index3.js output</figcaption></figure><h3 id="%F0%9F%91%8E-limitations-1">&#x1F44E; Limitations</h3><ul><li>Asking to check events from block 0 on the Mainnet would take some time, since it has to scan all the blocks looking for our events.</li><li>By default, the getPastEvents method is looking in the &#x2018;earliest&#x2019; block (cf. doc <a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html?highlight=getPastEvents#getpastevents">here</a>). Thus, to retrieve all events, we have to check from the initial block (fromBlock: 0). If we don&#x2019;t define the block parameter, we will get the events from the earliest block (you can try ;-)).</li></ul><h3 id="%E2%98%9D%EF%B8%8Falternative">&#x261D;&#xFE0F;Alternative</h3><ul><li>It&#x2019;s possible to filter on specific event&#x2019;s parameters, by adding the filter key to the getPastEvents method. </li><li>In that case, you will also need to indicate the name of the event.</li></ul><p>Example including a filter on the &apos;to&apos; parameter:</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract3 = require(&apos;./build/contracts/MyContract3.json&apos;);

const init = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);
    
    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract3.abi,
        MyContract3.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

	//Triggering Event 1
    await contract.methods.payment(accounts[0], &apos;1000000000000000000&apos;).send({
        from: accounts[1],
    });

	//Triggering Event 2
    await contract.methods.payment(accounts[1], &apos;1000000000000000000&apos;).send({
        from: accounts[2],
    });

    const receipt = await contract.getPastEvents(
        &apos;MyPayment&apos;,
        {
            filter:{
                to: &apos;0x3577B769c0bA9a762211E6F6b006730f8399b231&apos;,
            }
        },
        {
            fromBlock: 0
        });

    console.log(receipt);
}

init();

</code></pre><figcaption>index3.js including filters</figcaption></figure><p>To be able to use specific parameters as filters, we need to add the &#x2018;<strong><u>indexed</u></strong>&#x2019; key in our Smart Contract. </p><p>The indexed variables must be chosen widely since we are limited <strong><u>to a maximum of 3</u></strong>.</p><p><u>From the Solidity doc:</u></p><blockquote>&quot;You can add the attribute indexed to up to three parameters which adds them to a special data structure known as &#x201C;topics&#x201D; instead of the data part of the log&quot;.</blockquote><p>More info <a href="https://docs.soliditylang.org/en/v0.8.7/contracts.html?highlight=indexed#events">here</a>.</p><h2 id="method-3websocket-to-read-real-time-events">Method 3 - <u>WebSocket</u> to read Real-Time events</h2><h3 id="what-is-a-websocket">What is a WebSocket?</h3><blockquote>&quot;A WebSocket is a persistent connection between a client and server. WebSockets provide a bidirectional, full-duplex communications channel that operates over HTTP through a single TCP/IP socket connection. At its core, the WebSocket protocol facilitates message passing between a client and server&quot;.</blockquote><p>I got this nice definition from <a href="https://sookocheff.com/post/networking/how-do-websockets-work/">this great article</a>, which I recommend if you need more information about the subject.</p><p>The advantage of using WebSocket is that we can monitor events in real-time. To simulate this, we will use 2 different scripts. The first script will be listening to event in real-time, while the second script will trigger events.</p><p><u>What we will achieve:</u></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/web3-tutorial-websocket-real-time-events-monitoring.gif" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 7/10] - Listen to Smart Contract Events" loading="lazy" width="1920" height="1080"><figcaption>Websocket Real Time Monitoring Events</figcaption></figure><p>Again, we will relaunch Ganache to get a clean blockchain (don&apos;t forget to migrate again using Truffle).</p><pre><code class="language-shell">truffle migrate --reset</code></pre><h3 id="script-1">Script 1</h3><p>We create the &apos;listener.js&apos; script. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract3 = require(&apos;./build/contracts/MyContract3.json&apos;);

const init = async() =&gt; {
    const web3 = new Web3(
        new Web3.providers.WebsocketProvider(
            &apos;ws://127.0.0.1:7545&apos;
        )
    );

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract3.abi,
        MyContract3.networks[id].address
    );

    contract.events.MyPayment({fromBlock: 0})
    	.on(&apos;data&apos;, event =&gt; console.log(event));
}

init();</code></pre><figcaption>listener.js</figcaption></figure><p>Instead of using new Web3( &apos;Ganache address&apos; ), we know use the WebsocketProvider.</p><p>At the end, we launch a &apos;listener&apos; console.logging events when they occur.</p><p>We launch listener.js in a Terminal 1. You should see a script waiting.</p><h3 id="script-2">Script 2</h3><p>Our second script &apos;events.js&apos; will be quite similar as the one used in the 2 previous methods, since it will only trigger twice the same events.</p><p>Here is the code. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract3 = require(&apos;./build/contracts/MyContract3.json&apos;);

const init = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);
    
    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract3.abi,
        MyContract3.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

	//Triggering Event 1
    await contract.methods.payment(accounts[0], &apos;1000000000000000000&apos;).send({
        from: accounts[1],
    });

    await sleep(5000);

	//Triggering Event 2
    await contract.methods.payment(accounts[1], &apos;1000000000000000000&apos;).send({
        from: accounts[2],
    });
}

init();


function sleep(ms) {
    return new Promise(resolve =&gt; setTimeout(resolve, ms));
  }</code></pre><figcaption>events.js</figcaption></figure><p>The only additional part is the &apos;sleep&apos; method for 5 sec.</p><p>We are launching this script in a second terminal.</p><p>Now, we see the results: 1 event occurs live, then 5 sec later, the second one is displayed.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/web3-tutorial-websocket-real-time-events-monitoring.gif" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 7/10] - Listen to Smart Contract Events" loading="lazy" width="1920" height="1080"><figcaption>Websocket Real Time Monitoring Events</figcaption></figure><p>Hurra! It works! We successfully use 3 differents methods to listen to Smart Contract&apos;s events ! Congrats!</p><!--kg-card-begin: html--><iframe src="https://giphy.com/embed/400IbOQGqOWQgTLCvx" width="480" height="480" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/DesusAndMeroOnShowtime-desus-and-mero-bodega-boys-hive-400IbOQGqOWQgTLCvx"></a></p><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 6/10] - Send Ether to a Smart Contract]]></title><description><![CDATA[<h2 id="introduction">Introduction</h2><p>Sometimes it&apos;s necessary to load the Smart Contract with Ethers. Thus, we need to be able to send some token to our Smart Contract. </p><p>Since we are modifying the Blockchain, it will have to be mined, and by consequence it will cost some gas fees.</p><p>Actually, there</p>]]></description><link>https://catchtheblock.com/web3-serie-part-6-10-send-ether-to-a-smart-contract/</link><guid isPermaLink="false">612e7a39d125b10001e216be</guid><category><![CDATA[web3]]></category><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[smart contract]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 01 Sep 2021 19:36:55 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-6.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-6.png" alt="&#x1F9F0; Web3 [Serie Part 6/10] - Send Ether to a Smart Contract"><p>Sometimes it&apos;s necessary to load the Smart Contract with Ethers. Thus, we need to be able to send some token to our Smart Contract. </p><p>Since we are modifying the Blockchain, it will have to be mined, and by consequence it will cost some gas fees.</p><p>Actually, there are two ways to send Ether to a Smart Contract. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh3.googleusercontent.com/M6LuEWjwKdVBI6bXQvRagHOXng9iN0R5s_B3_-O5hhRxVdevbW0ALFgtO3B5UVggwaXvM3tQCURXq1or0jFtLiNfLduGRRGly4WXRYK9M9SB8_MqBrdot10Ayc_vH1AsSDm-X0jt=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 6/10] - Send Ether to a Smart Contract" loading="lazy"><figcaption>Two ways to send Ether to a Smart Contract</figcaption></figure><h2 id="method-1-execute-a-function">Method #1: Execute a Function</h2><p>We will be using a different Smart Contract code for this new part. Thus, let&apos;s create a new file &apos;MyContract2.sol&apos; in our contracts directory, and copy the code below. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Solidity">pragma solidity &gt;=0.4.16 &lt;0.9.0;

contract MyContract2 {
    string public message;

    function sendEther() external payable {
        message = &apos;Ether sent!&apos;;
    }

    function() external payable {
        message = &apos;Fallback function!&apos;;
    }
}</code></pre><figcaption>MyContract2.sol</figcaption></figure><ul><li>We define a new contract MyContract2 including 2 functions.</li><li>We declare a public variable called message as a string type.</li><li>Function sendEther() is simulating a payment, while the second function is a fallback function. It will be detailed in section.</li></ul><p>Don&apos;t forget to adapt the migration file (2_contract_deploy.js) accordingly.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const MyContract = artifacts.require(&apos;MyContract&apos;);
const MyContract2 = artifacts.require(&apos;MyContract2&apos;);

module.exports = function(deployer){
    deployer.deploy(MyContract);
    deployer.deploy(MyContract2);
}</code></pre><figcaption>2_contract_deploy.js</figcaption></figure><p>We simply added the MyContract2 to be deployed. If you want things cleaner, you can drop the MyContract since we won&apos;t use it anymore. It&apos;s up to you.</p><p>Now, we can migrate our new MyContract2.sol by running the following command in our terminal:</p><pre><code class="language-Shell">truffle migrate --reset</code></pre><p>Among the results, you should see our MyContract2 deployment feedback:</p><figure class="kg-card kg-code-card"><pre><code class="language-Shell">Deploying &apos;MyContract2&apos;
   -----------------------
   &gt; transaction hash:    0x21f9754b72d2bfc595bda75c8a3c12e7fc9e0b415bf757c561d86b51d81e845d
   &gt; Blocks: 0            Seconds: 0
   &gt; contract address:    0xE5704600e4f2a0B2b2Fb5F07002F819D0EDC86A4
   &gt; block number:        9
   &gt; block timestamp:     1630438020
   &gt; account:             0x8ba7dDC383130c3D5c3afC76AD3f3343571246E8
   &gt; balance:             99.98120808
   &gt; gas used:            209894 (0x333e6)
   &gt; gas price:           20 gwei
   &gt; value sent:          0 ETH
   &gt; total cost:          0.00419788 ETH
</code></pre><figcaption>MyContract2.sol migration &amp; deployment results</figcaption></figure><p>Now, that we deployed our new MyContract2.sol successfully, we can move on our Javascript script. We will create a new index2.js and copy the below code. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract2 = require(&apos;./build/contracts/MyContract2.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract2.abi,
        MyContract2.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();
}

main();</code></pre><figcaption>Initial index2.js</figcaption></figure><p>Now, let&apos;s change this index2.js script to send 1 ETH to our Smart Contract MyContract2.sol.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract2 = require(&apos;./build/contracts/MyContract2.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract2.abi,
        MyContract2.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

    const receipt = await contract.methods.sendEther().send({
        from: accounts[0],
        value: &apos;1000000000000000000&apos;
    });

    console.log(receipt);
    console.log(await contract.methods.message().call());
}

main();</code></pre><figcaption>Updated index2.js</figcaption></figure><p>Here we call our sendEther() methods, using &apos;send API&apos;. The send method requires several parameters. We will be using the 2 following parameters (more details <a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html?highlight=methods.MyMethod.send#methods-mymethod-send">here</a> in the doc):</p><ul><li>From: The address the transaction should be sent from.</li><li>Value: The value transferred for the transaction in <strong>wei</strong>.</li></ul><p><strong><u>Note</u></strong>: 1 WEI = 10^(-18) ETH.</p><h3 id="%F0%9F%9A%A8-warning-there-is-a-caveat-here-%F0%9F%9A%A8">&#x1F6A8; WARNING, there is a <u>caveat</u> here &#x1F6A8;</h3><ul><li>As you can see, the value we are transferring is written as a <strong><u>String</u></strong> type with quite a lot of 0.</li><li>If we don&#x2019;t write the value as above, the value will be in Wei (i.e. 10^-18 ETH). Thus, you should write 1 000 000 000 000 000 000 . The problem is that such big numbers are not managed by Javascript. That&#x2019;s why the trick is to write it as a String type.</li><li>If you have to perform math operations on this number, I recommend using the bn.js library. Here we keep it simple, and use the String version.</li></ul><p>This being said, let&apos;s run our index2.js . We will see the following results:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">{
  transactionHash: &apos;0x033bf75f4e6891bdc130dc172ad18f0df9d08ab7675c0d6976f3e0ca21e35a57&apos;,
  transactionIndex: 0,
  blockHash: &apos;0x2ac3d17d28f36a594cb778b631efe33f69a08bb88bfefc2e77190ef2cff2f035&apos;,
  blockNumber: 11,
  from: &apos;0x8ba7ddc383130c3d5c3afc76ad3f3343571246e8&apos;,
  to: &apos;0xe5704600e4f2a0b2b2fb5f07002f819d0edc86a4&apos;,
  gasUsed: 42365,
  cumulativeGasUsed: 42365,
  contractAddress: null,
  status: true,
  logsBloom: &apos;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&apos;,
  events: {}
}
Ether sent!</code></pre><figcaption>index2.js outputs</figcaption></figure><p>Hurra ! It works. We get the receipt of our transaction, as well as the message &#x2018;Ether sent!&#x2019;. Thus, we successfully sent 1 ETH to our Smart Contract (MyContract2).</p><h2 id="method-2-send-ether-directly">Method #2: Send Ether Directly</h2><p>The second method consists in sending Ether to our Smart Contract, without calling any function. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh3.googleusercontent.com/M6LuEWjwKdVBI6bXQvRagHOXng9iN0R5s_B3_-O5hhRxVdevbW0ALFgtO3B5UVggwaXvM3tQCURXq1or0jFtLiNfLduGRRGly4WXRYK9M9SB8_MqBrdot10Ayc_vH1AsSDm-X0jt=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 6/10] - Send Ether to a Smart Contract" loading="lazy"><figcaption>Two ways to send Ether to a Smart Contract</figcaption></figure><p>In our Smart Contract, if you remember, we added what we call a &#x2018;fallback&#x2019; method. This method will be fired by default, if a wrong function name is called in our JS file, or if no function name is used. It serves as a fallback&#x2026;</p><p>Here is the updated index2.js. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract2 = require(&apos;./build/contracts/MyContract2.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract2.abi,
        MyContract2.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

    const receipt = await web3.eth.sendTransaction({
        from: accounts[0],
        to: contract.options.address,
        value: &apos;1000000000000000000&apos;,
    });

    console.log(receipt);
    console.log(await contract.methods.message().call());
}

main();</code></pre><figcaption>Updated index2.js</figcaption></figure><p>Instead of calling a method from the Smart Contract, we call directly the <a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth.html#sendtransaction">sendTransaction</a> method. </p><p>Thus we are not referencing a specific method from our Smart Contract. As parameters we are using:</p><ul><li>From: same as previous.</li><li>To: the contract address we want to send ETH to: contract.<a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html?highlight=options.address#options-address">options.address</a>.</li><li>Value: same as previous.</li></ul><p>Our fallback function should be fired. Like the previous test, we are console.logging the receipt, as well as the value of our public message. It should print &#x2018;Fallback function!&#x2019;.<br><br>After running the code, we see the results below:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">{
  transactionHash: &apos;0xb5617cef2b868aef7c296d0a6a6141f0b0e73266c328f8371d7ef474107aadda&apos;,
  transactionIndex: 0,
  blockHash: &apos;0x42a605890ba8ea0eb1046490ecdd76c4267c8eaff15b400a7fbf06acd1c60605&apos;,
  blockNumber: 12,
  from: &apos;0x8ba7ddc383130c3d5c3afc76ad3f3343571246e8&apos;,
  to: &apos;0xe5704600e4f2a0b2b2fb5f07002f819d0edc86a4&apos;,
  gasUsed: 28100,
  cumulativeGasUsed: 28100,
  contractAddress: null,
  logs: [],
  status: true,
  logsBloom: &apos;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&apos;
}
Fallback function!</code></pre><figcaption>index2.js outputs</figcaption></figure><p>&#x1F389; &#x1F973; &#x1F46F;&#x200D;&#x2642;&#xFE0F; &#x1F388; Congratulations, it works , hurra ! We successfully sent 1 ETH to our Smart Contract using the <strong><u>fallback method</u></strong>.</p><h2 id="send-ether-from-an-account-to-another-one">Send Ether from an Account to another One</h2><p>In this additional part, we just want to send some Ethers from an account to another one. </p><p>Here, we won&apos;t use any Smart Contract.</p><p>Let&apos;s say, we want to send 1 ETH from Ganache&apos;s account #1 to the #2.</p><p>Before we start, here are the balances of our Ganache&apos;s accounts.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/image.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 6/10] - Send Ether to a Smart Contract" loading="lazy" width="1322" height="912" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image.png 1000w, https://catchtheblock.com/content/images/2021/09/image.png 1322w" sizes="(min-width: 720px) 720px"><figcaption>Initial Balances on Ganache i.e. Before the transfer</figcaption></figure><p>The code is simple, I&apos;m sure you could to do it by yourself :-). Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract2 = require(&apos;./build/contracts/MyContract2.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract2.abi,
        MyContract2.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

    const receipt = await web3.eth.sendTransaction({
        from: accounts[0],
        to: accounts[1],
        value: &apos;1000000000000000000&apos;,
    });

    console.log(receipt);
}

main();</code></pre><figcaption>index2.js - Transfer Ether from Account #1 to Account #2</figcaption></figure><ul><li>We use the sendTransaction method without mentioning any Smart Contract here, and we give 3 parameters.</li><li>From: the account from which the Ether will be withdrew.</li><li>To: the credited account.</li><li>Value: the amount of WEI we want to transfer. Again, we use the string format otherwise, we will have issue with Javascript (cf. Big Numbers).</li><li>Remember, 1 WEI = 1*10^(-18) ETH</li></ul><p>Here is our console.log receipt:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">{
  transactionHash: &apos;0xd4fb774a9dda670d887785adb36f03505e80a6ae45a2f6dc468ebcd9fedca372&apos;,
  transactionIndex: 0,
  blockHash: &apos;0xd927a7cd0746670ae94a53c8ca0f6c23fd72d14b50d7ad6ef25b786e9c77befd&apos;,
  blockNumber: 1,
  from: &apos;0x65ca5ecfd87faafe35f63244133efe9edf2abf55&apos;,
  to: &apos;0x89d48bf3591db71c2ebd7be9ea86ce52442e474c&apos;,
  gasUsed: 21000,
  cumulativeGasUsed: 21000,
  contractAddress: null,
  logs: [],
  status: true,
  logsBloom: &apos;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&apos;
}</code></pre><figcaption>index2.js outputs</figcaption></figure><p>And we can check our accounts balances from Ganache. We can see that 1ETH has been transfered from Account #1 to Account #2 ! </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/09/image-1.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 6/10] - Send Ether to a Smart Contract" loading="lazy" width="1322" height="912" srcset="https://catchtheblock.com/content/images/size/w600/2021/09/image-1.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/09/image-1.png 1000w, https://catchtheblock.com/content/images/2021/09/image-1.png 1322w" sizes="(min-width: 720px) 720px"><figcaption>Ganache - Accounts Balance post transfer</figcaption></figure><p>Hurra! It works! We successfully transferred 1 ETH from Account 1 to Account 2.</p><!--kg-card-begin: html--><iframe src="https://giphy.com/embed/l0Ex6kAKAoFRsFh6M" width="480" height="360" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/yvngswag-yvng-swag-l0Ex6kAKAoFRsFh6M"></a></p><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 5/10] - Send Transactions to a Smart Contract (sendTransactions API)]]></title><description><![CDATA[<h2 id="introduction">Introduction</h2><p>In the previous lecture, we read data from our Smart Contract. In this lecture, we are going to write data in our Smart Contract. To perform this operation, we will be using the second API, called eth_sendTransaction.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh5.googleusercontent.com/P1g-BCoihk67qePP9ttBzgONVIvTA4EdPf3EPJzcLFMgogU3X4Wo2ybQXXrkZiD3RiO73mDIXw_NHkA0R6IUmBUAwdvFTmYiW5WIXkBFl3Jx8f7d0k1Hx0vt75a5q3wAdbYXRMme=s0" class="kg-image" alt loading="lazy"><figcaption>2 APIs</figcaption></figure><p><strong><u>Reminder</u></strong>: if we send transactions to a Smart Contract,</p>]]></description><link>https://catchtheblock.com/web3-serie-part-5-10-call-a-smart-contract/</link><guid isPermaLink="false">612e6fe8d125b10001e21611</guid><category><![CDATA[web3]]></category><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[smart contract]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 01 Sep 2021 19:36:37 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-5.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-5.png" alt="&#x1F9F0; Web3 [Serie Part 5/10] - Send Transactions to a Smart Contract (sendTransactions API)"><p>In the previous lecture, we read data from our Smart Contract. In this lecture, we are going to write data in our Smart Contract. To perform this operation, we will be using the second API, called eth_sendTransaction.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh5.googleusercontent.com/P1g-BCoihk67qePP9ttBzgONVIvTA4EdPf3EPJzcLFMgogU3X4Wo2ybQXXrkZiD3RiO73mDIXw_NHkA0R6IUmBUAwdvFTmYiW5WIXkBFl3Jx8f7d0k1Hx0vt75a5q3wAdbYXRMme=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 5/10] - Send Transactions to a Smart Contract (sendTransactions API)" loading="lazy"><figcaption>2 APIs</figcaption></figure><p><strong><u>Reminder</u></strong>: if we send transactions to a Smart Contract, we actually change the blockchain. If changes occur, it must be mined, thus it will cost some <strong><u>gas fees</u></strong>.</p><h2 id="send-transactions">Send Transactions</h2><p>Let&apos;s reuse our previous <em>index.js</em> initial code:</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract.abi,
        MyContract.networks[id].address
    );
}

main();</code></pre><figcaption>Initial index.js</figcaption></figure><p>In this case, we will be using the other method called &apos;<a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html#methods-mymethod-send">methods.myMethod.send</a>&apos;. Unlike the call method, we cannot leave parameters blank here. Since the execution will cost some gas, we have to define what address we will pay with.</p><ul><li><strong>From</strong>: the address from which we will send the transaction. In this case, we will use one among the 10 automatically generated addresses from Ganache. In production, we would have use Metamask for instance. This part will be covered in next parts of this tutorial.</li></ul><p>It&#x2019;s important to use an <strong><u>async</u></strong> function. Since we are using a local development environment, the mining will be executed immediately. But, on the Mainnet or any other Public Test environment, a transaction mining could take up to 15sec. Thus, it&#x2019;s important to wait for the results. </p><p>Here is the code. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract.abi,
        MyContract.networks[id].address
    );

    const accounts = await web3.eth.getAccounts();

    const result1 = await contract.methods.get().call();

    const receipt = await contract.methods.set(100).send({
        from: accounts[0]
    });

    const result2 = await contract.methods.get().call();

    console.log(result1);
    console.log(receipt);
    console.log(result2);
    
}

main();</code></pre><figcaption>index.js including sendTransaction method</figcaption></figure><ul><li>First, we collect the generated accounts by Ganache, and store it in the array accounts. In this case, we will be using the first account, thus accounts[0].</li><li>Next, we use our previous method, to check the value of data, with the get function. We will see that its value is 0 (cf. previous part).</li><li>Then, we use the &apos;send&apos; method, and we set the value to 100.</li><li>Finally, we reuse the &apos;call&apos; method to check if the data was properly updated to 100.</li></ul><p>Here is our results:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">0
{
  transactionHash: &apos;0x9fbfd81501900d167879cd9bd5bda508726af622993eed09d297e7d7acfaa971&apos;,
  transactionIndex: 0,
  blockHash: &apos;0x9ded0d30c75b6a881fbf3382973e81c6cdac070741912028a635652face5f5ec&apos;,
  blockNumber: 5,
  from: &apos;0x8ba7ddc383130c3d5c3afc76ad3f3343571246e8&apos;,
  to: &apos;0xdfc6bf4043de741a57f57d1f065e365849f5af7c&apos;,
  gasUsed: 41424,
  cumulativeGasUsed: 41424,
  contractAddress: null,
  status: true,
  logsBloom: &apos;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&apos;,
  events: {}
}
100</code></pre><figcaption>Results of the updated index.js</figcaption></figure><p>First, we see 0. Which is what we expected.</p><p>Then, we get the receipt of the transaction, which corresponds to the Transaction Hash: </p><ul><li><strong>transactionHash: </strong>hexadecimal string that uniquely identifies the transaction on the blockchain. In prod, you could use that transactionHash in Etherscan to see your transaction details.</li><li><strong>blockHash</strong>: the hash of the block in which the transaction was mined,</li><li><strong>From</strong>: the address that sends the transaction. As you can see, we recognize our previously stated address there.</li><li><strong>To</strong>: is the recipient address of the transaction, which is our Smart Contract address,</li><li><strong>gasUsed</strong>: how much gas were used to mine the transaction</li></ul><p>Finally, we get the updated value of 100.</p><p>As you can see in Ganache, our first account has less than 100 ETH now, since it paid the transaction.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-28.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 5/10] - Send Transactions to a Smart Contract (sendTransactions API)" loading="lazy" width="1312" height="912" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-28.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-28.png 1000w, https://catchtheblock.com/content/images/2021/08/image-28.png 1312w" sizes="(min-width: 720px) 720px"><figcaption>Ganache Accounts Overview Post Transaction</figcaption></figure><p>&#x1F389; &#x1F973; &#x1F46F;&#x200D;&#x2642;&#xFE0F; &#x1F388; Congratulations! We successfully send our first transaction using the set() method from our Smart Contract. In the next lecture, we will send Ether to the Smart Contract !</p><!--kg-card-begin: html--><iframe src="https://giphy.com/embed/xT5LMDjUD70GVSqShq" width="480" height="360" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/season-12-the-simpsons-12x6-xT5LMDjUD70GVSqShq"></a></p><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 4/10] - Call A Smart Contract]]></title><description><![CDATA[<h2 id="introduction">Introduction</h2><p>In this chapter, we are going to interact with our Smart Contract. </p><p>First, we will use the Call API. This API will allow us to retrieve data from the Smart Contract.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh5.googleusercontent.com/P1g-BCoihk67qePP9ttBzgONVIvTA4EdPf3EPJzcLFMgogU3X4Wo2ybQXXrkZiD3RiO73mDIXw_NHkA0R6IUmBUAwdvFTmYiW5WIXkBFl3Jx8f7d0k1Hx0vt75a5q3wAdbYXRMme=s0" class="kg-image" alt loading="lazy"><figcaption>2 APIs</figcaption></figure><h2 id="call-api">Call API</h2><p>We will start from the index.js script we developed in the past lecture.</p>]]></description><link>https://catchtheblock.com/web3-serie-part-4-10-call-a-smart-contract/</link><guid isPermaLink="false">612e44a9d125b10001e215cb</guid><category><![CDATA[web3]]></category><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[smart contract]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 01 Sep 2021 19:36:20 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-4.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-4.png" alt="&#x1F9F0; Web3 [Serie Part 4/10] - Call A Smart Contract"><p>In this chapter, we are going to interact with our Smart Contract. </p><p>First, we will use the Call API. This API will allow us to retrieve data from the Smart Contract.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh5.googleusercontent.com/P1g-BCoihk67qePP9ttBzgONVIvTA4EdPf3EPJzcLFMgogU3X4Wo2ybQXXrkZiD3RiO73mDIXw_NHkA0R6IUmBUAwdvFTmYiW5WIXkBFl3Jx8f7d0k1Hx0vt75a5q3wAdbYXRMme=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 4/10] - Call A Smart Contract" loading="lazy"><figcaption>2 APIs</figcaption></figure><h2 id="call-api">Call API</h2><p>We will start from the index.js script we developed in the past lecture.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);
    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract.abi,
        MyContract.networks[id].address
    );    
}

main();</code></pre><figcaption>Initial index.js</figcaption></figure><p>Now, let&apos;s add a &apos;call&apos; to our Smart Contract, using the &apos;<a href="https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html#methods-mymethod-call">methods.myMethod.call</a>&apos; methods from Web3. As we can see in the Web3 doc, we can add several parameters to this methods. For this first Call, we will keep things simple, and leave it blank.</p><p>Here is the code, and comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract.abi,
        MyContract.networks[id].address
    );

    const data = await contract.methods.get().call();
    console.log(data);
}

main();</code></pre><figcaption>index.js</figcaption></figure><ul><li>We use the contract.methods.get().call() to call the &apos;get&apos; method we defined in our Smart Contract.</li><li>Then, we console.log the result stored in data.</li></ul><p>We can see the following result in the terminal:</p><pre><code class="language-shell">0</code></pre><p>Since, we didn&apos;t initialize our Smart Contract uint variable, this is empty, and our get function is thus returning 0.</p><p>&#x1F389; &#x1F973; &#x1F46F;&#x200D;&#x2642;&#xFE0F; &#x1F388; Congratulations! We successfully call our method get in our Smart Contract, directly from our index.js script. In the next lecture, we will send transaction !</p><!--kg-card-begin: html--><iframe src="https://giphy.com/embed/3o6ZtnjHxx2KlheEEM" width="480" height="266" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/ufc-mma-ufc-205-3o6ZtnjHxx2KlheEEM"></a></p><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 3/10] - Create A Contract Instance]]></title><description><![CDATA[<h2 id="introduction">Introduction</h2><p>In this chapter, we will learn how to create an instance of our Smart Contract. This part is required to interact with our contract.</p><h3 id="what-is-a-contract-instance">What is a Contract Instance?</h3><p>The Contract Instance is an object produced by the library Web3 creating a contract instance to interact with our Smart</p>]]></description><link>https://catchtheblock.com/web3-serie-part-3-10/</link><guid isPermaLink="false">612e3106d125b10001e2146e</guid><category><![CDATA[web3]]></category><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[smart contract]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 01 Sep 2021 19:36:00 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-3.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-3.png" alt="&#x1F9F0; Web3 [Serie Part 3/10] - Create A Contract Instance"><p>In this chapter, we will learn how to create an instance of our Smart Contract. This part is required to interact with our contract.</p><h3 id="what-is-a-contract-instance">What is a Contract Instance?</h3><p>The Contract Instance is an object produced by the library Web3 creating a contract instance to interact with our Smart Contract.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh3.googleusercontent.com/9rFT5cuIKrnPV_S6yZK0w6E_mg-GkHIfYQ-hbgFNDhPR7Hks8j5f9EOORT92j30t3ktdW62QmoShpigCJs12aNTxIwjkE6ai1MiZnWLkSC7DcZEAgMkDlAMlSFrIQEyQB4d9S4xS=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 3/10] - Create A Contract Instance" loading="lazy"><figcaption>Web3 Instances Levels Overview</figcaption></figure><h3 id="why-dont-we-interact-directly-with-the-smart-contract">Why don&apos;t we interact directly with the Smart Contract?</h3><p>Well, each Smart Contracts are different and have their own functions, and addresses. So, we need to teach Web3 how to &apos;speak&apos; with our Smart Contract.</p><p>To create our Contract Instance, Web3 is requiring 2 parameters:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://lh4.googleusercontent.com/DPGnKcgxuU6hdON5d1yyKOG6p6O5tBsV4BPdk9GqyhjrEK5O_17zFPToY6B9apqlSKaxXKkx3oRcXqK4MoWpSOwSxh4TQ3IxgtciRLIvEtqgmN5mNxjKf7g85mW1HxSOdqxVjMqK=s0" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 3/10] - Create A Contract Instance" loading="lazy"><figcaption>Two parameters required by Web3 to create a Contract Instance: the Contract Address, and the Contract ABI</figcaption></figure><h3 id="contract-address">Contract Address</h3><p>A Contract Address is the address of the place where our Smart Contract is stored on the Ethereum Blockchain. It will allow us to send, or withdraw funds for instance.</p><h3 id="contract-abi">Contract ABI</h3><blockquote>ABI stands for &#x2018;Application Binary Interface&#x2019;. </blockquote><p>The Contract ABI is a JSON document describing all the functions, and variables used in the Smart Contract, callable from outside the Blockchain. </p><p>The ABI is generated by compiling/building our Smart Contract written in Solidity.</p><h2 id="smart-contract-development-building">Smart Contract Development &amp; Building</h2><p>In this Serie, we won&apos;t cover the Solidity development part. Thus, we will use an already developed <strong><u>simple</u></strong> Smart Contract code. &#xA0;Nevertheless, we will go the 3 steps of deploying a Smart Contract.</p><h3 id="step-1code-the-smart-contract"><br>Step 1 - Code the Smart Contract</h3><p>First, we are going to generate a basic development framework thanks to Truffle (installed in the part 1 of this serie). In our main directory, we run the following command:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">truffle init</code></pre><figcaption>Initialize with Truffle</figcaption></figure><p>As a result you should have the following directory tree:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">&#x251C;&#x2500;&#x2500; contracts
&#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; Migrations.sol
&#x251C;&#x2500;&#x2500; index.js
&#x251C;&#x2500;&#x2500; migrations
&#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; 1_initial_migration.js
&#x251C;&#x2500;&#x2500; node_modules
&#x251C;&#x2500;&#x2500; package-lock.json
&#x251C;&#x2500;&#x2500; package.json
&#x251C;&#x2500;&#x2500; test
&#x2514;&#x2500;&#x2500; truffle-config.js</code></pre><figcaption>Directory Tree post &apos;truffle init&apos; command (node_modules have been simplified for readability)</figcaption></figure><p>In the Contracts directory, create a new file &apos;MyContract.sol&apos; (.sol is standing for Solidity language).</p><p>To keep things simple, we will be using the Smart Contract used as example in Solidity <a href="https://docs.soliditylang.org/en/v0.8.7/introduction-to-smart-contracts.html">documentation</a>. We will just change a few things.</p><p>Initial code from Solidity documentation</p><figure class="kg-card kg-code-card"><pre><code class="language-Solidity">// SPDX-License-Identifier: GPL-3.0
pragma solidity &gt;=0.4.16 &lt;0.9.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}</code></pre><figcaption>Smart Contract initial code from Solidity Documentation (before our small changes)</figcaption></figure><p>Here is the final code we will be using. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Solidity">pragma solidity &gt;=0.4.16 &lt;0.9.0;

contract MyContract {
    uint data;

    function set(uint x) public {
        data = x;
    }

    function get() public view returns (uint) {
        return data;
    }
}</code></pre><figcaption>MyContract.sol</figcaption></figure><ul><li>First we define the Solidity version we are using.</li><li>Then, we define a new contract, called MyContract.</li><li>Next, we define an &apos;uint&apos; (standing for Unsigned Integer) called data.</li><li>The two functions below are respectively a setter function, i.e. replacing data value by x, and a getter function, i.e. returning data value.</li><li>The public keywords mean that we can access these functions from outside the Smart Contract, thanks to Web3. Without that keyword, we could not access the variable or the function.</li></ul><h3 id="step-2code-the-migration-file">Step 2 - Code the Migration File</h3><p>Now, we need to script a migration file. This script is telling Truffle how to migrate our Smart Contract to the blockchain.</p><p>In the migration directory, we create a new file named 2_contract_deploy.js (2 is important).</p><p>We add the following script in the migration file:</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const MyContract = artifacts.require(&apos;MyContract&apos;);

module.exports = function(deployer){
    deployer.deploy(MyContract);
}</code></pre><figcaption>2_contract_deploy.js</figcaption></figure><h3 id="step-3compile-migrate-the-smart-contract">Step 3 - Compile &amp; Migrate the Smart Contract</h3><p>Now that we scripted our Smart Contract, and wrote our Migration file, we can launch the building process, and the migration.</p><p>In our main directory, we run the following command:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">truffle migrate --reset</code></pre><figcaption>Truffle Migration Command</figcaption></figure><p><strong>Comment</strong></p><ul><li>the reset tag stands for resetting potential previous migration. In this first case, this is not required, but if you encounter error in the compilation, you would restart your truffle migration adding the --reset to start from scratch.</li></ul><p>We will see the following results:</p><pre><code class="language-shell">Compiling your contracts...
===========================
&gt; Compiling ./contracts/Migrations.sol
&gt; Compiling ./contracts/MyContract.sol
&gt; Artifacts written to /Users/henririon/Documents/Tutorials/web3-tutorial/build/contracts
&gt; Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang



Starting migrations...
======================
&gt; Network name:    &apos;ganache&apos;
&gt; Network id:      5777
&gt; Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying &apos;Migrations&apos;
   ----------------------
   &gt; transaction hash:    0x9907bdca7b17841fac28db587cf3b674481348e9bb730fb1e6b6722d1d09bc31
   &gt; Blocks: 0            Seconds: 0
   &gt; contract address:    0x3aa84f14eC87a764a4950AA2A1C1F4849bCC60d1
   &gt; block number:        1
   &gt; block timestamp:     1630419782
   &gt; account:             0x8ba7dDC383130c3D5c3afC76AD3f3343571246E8
   &gt; balance:             99.99616114
   &gt; gas used:            191943 (0x2edc7)
   &gt; gas price:           20 gwei
   &gt; value sent:          0 ETH
   &gt; total cost:          0.00383886 ETH


   &gt; Saving migration to chain.
   &gt; Saving artifacts
   -------------------------------------
   &gt; Total cost:          0.00383886 ETH


2_contract_deploy.js
====================

   Deploying &apos;MyContract&apos;
   ----------------------
   &gt; transaction hash:    0xd24cdd7f0a11fe02a747fa3bc701a7de3a893c2995da145cbe360c57a93b47c4
   &gt; Blocks: 0            Seconds: 0
   &gt; contract address:    0xdfC6BF4043dE741A57f57d1f065e365849f5af7C
   &gt; block number:        3
   &gt; block timestamp:     1630419782
   &gt; account:             0x8ba7dDC383130c3D5c3afC76AD3f3343571246E8
   &gt; balance:             99.9933906
   &gt; gas used:            96189 (0x177bd)
   &gt; gas price:           20 gwei
   &gt; value sent:          0 ETH
   &gt; total cost:          0.00192378 ETH


   &gt; Saving migration to chain.
   &gt; Saving artifacts
   -------------------------------------
   &gt; Total cost:          0.00192378 ETH


Summary
=======
&gt; Total deployments:   2
&gt; Final cost:          0.00576264 ETH

</code></pre><p>A few comments about this results:</p><ul><li>First, as indicated, Truffle compile our Smart Contract.</li><li>Next, it starts the migration. First, the initial migration, and second our &apos;2_contract_deploy.js&apos;.</li><li>For each migration, we got the transaction hash parameter informing us about the block number, the contract address, the total cost, etc.</li></ul><p>Our Smart Contract has been successfully compiled, and migrated to our local blockchain, Ganache.</p><p>If we check our main directory, we should see a new directory called &apos;build&apos;. Inside, we will find a file called MyContract.json, which is our Contract ABI.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-27.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 3/10] - Create A Contract Instance" loading="lazy" width="1299" height="1178" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-27.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-27.png 1000w, https://catchtheblock.com/content/images/2021/08/image-27.png 1299w" sizes="(min-width: 720px) 720px"><figcaption>VS Code Directory Overview - Focusing on Build directory, and the Contract ABI</figcaption></figure><p>As explained earlier, to create our Smart Contract Instance, Web3 is requiring 2 parameters: the Contract Address, and the Contract ABI. We now have both, and we can start coding.</p><h2 id="create-our-smart-contract-instance">Create our Smart Contract Instance</h2><p>Now, that we generate our Smart Contract ABI, we can actually retrieve both parameters we need inside the generated MyContract.json file.</p><p>If we open the ABI Json file, we can see at the end of the file, the following piece of code:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">[...]

&quot;networks&quot;: {
    &quot;5777&quot;: {
      &quot;events&quot;: {},
      &quot;links&quot;: {},
      &quot;address&quot;: &quot;0xdfC6BF4043dE741A57f57d1f065e365849f5af7C&quot;,
      &quot;transactionHash&quot;: &quot;0xd24cdd7f0a11fe02a747fa3bc701a7de3a893c2995da145cbe360c57a93b47c4&quot;
    }
    
[...]</code></pre><figcaption>MyContract.json = MyContract ABI</figcaption></figure><p>The mentioned address is our Smart Contract address deployed in our local Blockchain, Ganache.</p><p>Now, we have everything to create our Smart Contract instance. </p><p>Here is the complete code. Comments are following.</p><figure class="kg-card kg-code-card"><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const MyContract = require(&apos;./build/contracts/MyContract.json&apos;);

const main = async() =&gt; {
    const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

    const id = await web3.eth.net.getId();
    const contract = new web3.eth.Contract(
        MyContract.abi,
        MyContract.networks[id].address
    );

    console.log(contract);
}

main();</code></pre><figcaption>index.js</figcaption></figure><ul><li>We import MyContract.json, our Contract ABI as MyContract.</li><li>Then, we use the web3.eth.net.getId() methods to retrieve the current Network ID. It will help us finding our Smart Contract address.</li><li>Next we create our Contract Instance by giving the two required parameters: the Contract ABI, and the Contract address.</li><li>To check if everything is fine we console.log our contract instance.</li></ul><p>&#x1F389; &#x1F973; &#x1F46F;&#x200D;&#x2642;&#xFE0F; &#x1F388; Congratulations! We successfully instantiate our first Smart Contract. Let&apos;s move on and interact with our Smart Contract now.</p><!--kg-card-begin: html--><iframe src="https://giphy.com/embed/26xBFGiC9ENdOtTSU" width="480" height="480" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/communication-likemoi-26xBFGiC9ENdOtTSU"></a></p><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[🧰 Web3 [Serie Part 2/10] - Connect Web3 to Ganache]]></title><description><![CDATA[<p>At the end of this chapter, we will be able to connect our code to our local blockchain (Ganache), and retrieve account balance in Ether.</p><h2 id="introduction">Introduction</h2><p>In this part, we are going to configure Web3 to enable communication with Ganache, or any other nodes.</p><p>To allow interactions, Web3 is requiring</p>]]></description><link>https://catchtheblock.com/web3-js-serie-part-2-10-setup-environment/</link><guid isPermaLink="false">612df748d125b10001e21366</guid><category><![CDATA[web3]]></category><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[smart contract]]></category><dc:creator><![CDATA[Henri Rion]]></dc:creator><pubDate>Wed, 01 Sep 2021 19:35:36 GMT</pubDate><media:content url="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://catchtheblock.com/content/images/2021/09/web3js-tutorial-part0-2.png" alt="&#x1F9F0; Web3 [Serie Part 2/10] - Connect Web3 to Ganache"><p>At the end of this chapter, we will be able to connect our code to our local blockchain (Ganache), and retrieve account balance in Ether.</p><h2 id="introduction">Introduction</h2><p>In this part, we are going to configure Web3 to enable communication with Ganache, or any other nodes.</p><p>To allow interactions, Web3 is requiring a &apos;provider&apos;.</p><h3 id="what-is-a-web3-provider">What is a Web3 provider?</h3><p>A provider is a data structure providing a bridge with the publicly reachable Ethereum nodes. In other words, a provider is how Web3 talks to the blockchain (more info <a href="https://web3py.readthedocs.io/en/stable/providers.html">here</a>).</p><p>The provider actually sends the call in JSON-RPC to the Ethereum nodes. Thanks to this design, the users keep flexibility, and is able to decide what wallet he is going to use.</p><p>Usually, the Ethereum wallet exposes the provider object as a global object in Javascript. In any case, our dApp will test whether the provider is public, and if it is, we will create a Web3 instance to connect to the blockchain using the wallet provider.</p><h2 id="lets-dive-in-the-code">Let&apos;s dive in the code</h2><p>In our main directory, where we installed our dependencies, we create a file &apos;index.js&apos;.</p><pre><code class="language-shell">touch index.js</code></pre><p>In this file, let&apos;s write the following code. Comments are following.</p><pre><code class="language-Javascript">const Web3 = require(&apos;web3&apos;);
const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);</code></pre><ul><li>We import the library in our code. It&apos;s important to write Web3 with an Uppercase to differentiate the Object, from the instance we create after.</li><li>Finally, we instantiate Web3 using the RPC Service url provided by Ganache http://127.0.0.1:7545.</li></ul><figure class="kg-card kg-image-card kg-width-full"><img src="https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-31-a--11.55.40.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 2/10] - Connect Web3 to Ganache" loading="lazy" width="644" height="140" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/Capture-d-e-cran-2021-08-31-a--11.55.40.png 600w, https://catchtheblock.com/content/images/2021/08/Capture-d-e-cran-2021-08-31-a--11.55.40.png 644w"></figure><p>We are now connected to our local Blockchain.</p><h2 id="smoke-test">Smoke Test</h2><p>Now we are connected, let&apos;s test our code. We will try to retrieve the Ether Balance from 1st account generated by Ganache.</p><p>Here is the code. Comments are following.</p><pre><code>const Web3 = require(&apos;web3&apos;);
const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

const main = async() =&gt; {
    const address = &apos;0x8ba7dDC383130c3D5c3afC76AD3f3343571246E8&apos;;
    const balance = await web3.eth.getBalance(address);
    console.log(balance);
}

main();</code></pre><ul><li>We define a async function called main.</li><li>Then, we copy the first account address provided by Ganache.</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://catchtheblock.com/content/images/2021/08/image-26.png" class="kg-image" alt="&#x1F9F0; Web3 [Serie Part 2/10] - Connect Web3 to Ganache" loading="lazy" width="1312" height="912" srcset="https://catchtheblock.com/content/images/size/w600/2021/08/image-26.png 600w, https://catchtheblock.com/content/images/size/w1000/2021/08/image-26.png 1000w, https://catchtheblock.com/content/images/2021/08/image-26.png 1312w" sizes="(min-width: 720px) 720px"><figcaption>Ganache First Account Address - Illustration</figcaption></figure><ul><li>Finally, we use the <a href="https://web3js.readthedocs.io/en/v1.2.11/web3-eth.html?highlight=getBalance#getbalance">web3.eth.getBalance(address [, defaultBlock] [, callback])</a> method allowing us to retrieve the balance for specific account.</li></ul><p>After launching the code, we will see the following result in the Terminal</p><pre><code class="language-shell">100000000000000000000</code></pre><h3 id="why-don%E2%80%99t-we-see-100-eth">Why don&#x2019;t we see 100 ETH? </h3><p>By default, the <strong>getBalance</strong> function returns the value in <strong>Wei</strong>, which corresponds to 10^-18 ETH.</p><p>We can use the &apos;utils&apos; toolbox from web3 to convert this <strong>Wei</strong> amount into <strong>Eth</strong>.</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const Web3 = require(&apos;web3&apos;);
const web3 = new Web3(&apos;http://127.0.0.1:7545&apos;);

const main = async() =&gt; {
    const address = &apos;0x8ba7dDC383130c3D5c3afC76AD3f3343571246E8&apos;;
    const balanceWei = await web3.eth.getBalance(address);
    const balanceEth = await web3.utils.fromWei(balanceWei);
    console.log(balanceEth);
}

main();</code></pre><figcaption>Converting Wei into Eth</figcaption></figure><p>After running that script, we will see 100 ETH as a result.</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">100</code></pre><figcaption>Results in ETH instead of Wei</figcaption></figure><p>&#x1F389; &#x1F973; &#x1F46F;&#x200D;&#x2642;&#xFE0F; &#x1F388; Congratulations! We successfully setup our provider, and communicate with Ganache ! </p><!--kg-card-begin: html--><iframe src="https://giphy.com/embed/UxYj8W8coKjcY" width="480" height="216" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/humble-lada-snownuts-UxYj8W8coKjcY"></a></p><!--kg-card-end: html--><p>Let&apos;s move on to the next part.</p>]]></content:encoded></item></channel></rss>