
這篇文章繼承了上一篇 智能合約 Solidity 教學 (中) 我們開發一個 DApp 的前端,理解如何透過 Web3.js 連接區塊鏈上我們所部署的合約。
在過去兩章節中,我們已經完成了智能合約,並且將其部署到測試鏈 Sepolia 上
Sepolia 是全球公開的以太坊測試網絡,已經算是個半公開環境了
在實際項目開發中,我們會使用 Ganache 之類的程序,來架設自己的私人區塊鏈,並且在上頭測試合約,以獲得更高的調測性與開發效率。
在本教學中則因為時間問題,省略了這一部分。
npm create vite@latest 來初始化專案)。my-web3-project)cd my-web3-projectnpm install web3執行完 npm create vite@latest 之後,你的專案結構大致會長這樣:
my-web3-project
├─ index.html
├─ package.json
├─ vite.config.js
└─ src
├─ main.js
└─ style.css
為了方便教學,所有的程式碼都會放在 index.html 中來展示結果。



1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Document</title>
7</head>
8<body>
9
10</body>
11</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 // ... 之後的程式碼就放這吧
10 </script>
11</head>
12
13<body>
14
15</body>
16
17</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 </script>
11</head>
12
13<body>
14
15</body>
16
17</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
11
12 const contractABI = [
13 {
14 inputs: [
15 ....
16 ],
17 stateMutability: "nonpayable",
18 type: "constructor",
19 },
20 ...
21 ];
22 </script>
23</head>
24
25<body>
26
27</body>
28
29</html>1// abi.js
2export const contractABI = [
3 {
4 inputs: [
5 ....
6 ],
7 stateMutability: "nonpayable",
8 type: "constructor",
9 },
10 ...
11];
1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13 </script>
14</head>
15
16<body>
17
18</body>
19
20</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 </script>
15</head>
16
17<body>
18 <div>
19 <button id="connectButton">連線錢包</button>
20 </div>
21</body>
22
23</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 // 找到 網頁 中的按鈕
15 const connectButton = document.getElementById("connectButton");
16 connectButton.addEventListener("click", async () => {
17 // ...點擊後要做的事情
18 });
19 </script>
20</head>
21
22<body>
23 <div>
24 <button id="connectButton">連線錢包</button>
25 </div>
26</body>
27
28</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 const connectButton = document.getElementById("connectButton");
15 connectButton.addEventListener("click", async () => {
16 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
17 if (typeof window.ethereum !== 'undefined') {
18 // ... 設定錢包
19 } else {
20 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
21 }
22 });
23 </script>
24</head>
25
26<body>
27 <div>
28 <button id="connectButton">連線錢包</button>
29 </div>
30</body>
31
32</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 const connectButton = document.getElementById("connectButton");
15 connectButton.addEventListener("click", async () => {
16 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
17 if (typeof window.ethereum !== 'undefined') {
18 try {
19 // 請求錢包授權
20 await window.ethereum.request({ method: 'eth_requestAccounts' });
21 } catch (error) {
22 console.error(error);
23 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
24 }
25 } else {
26 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
27 }
28 });
29 </script>
30</head>
31
32<body>
33 <div>
34 <button id="connectButton">連線錢包</button>
35 </div>
36</body>
37
38</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 const connectButton = document.getElementById("connectButton");
16 connectButton.addEventListener("click", async () => {
17 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
18 if (typeof window.ethereum !== 'undefined') {
19 try {
20 // 請求錢包授權
21 await window.ethereum.request({ method: 'eth_requestAccounts' });
22
23 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
24 web3 = new Web3(window.ethereum);
25 } catch (error) {
26 console.error(error);
27 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
28 }
29 } else {
30 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
31 }
32 });
33 </script>
34</head>
35
36<body>
37 <div>
38 <button id="connectButton">連線錢包</button>
39 </div>
40</body>
41
42</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 const connectButton = document.getElementById("connectButton");
16 connectButton.addEventListener("click", async () => {
17 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
18 if (typeof window.ethereum !== 'undefined') {
19 try {
20 // 請求錢包授權
21 await window.ethereum.request({ method: 'eth_requestAccounts' });
22
23 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
24 web3 = new Web3(window.ethereum);
25
26 // 印出當前使用的帳戶
27 const accounts = await web3.eth.getAccounts();
28 console.log('已連線帳戶:', accounts[0]);
29 } catch (error) {
30 console.error(error);
31 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
32 }
33 } else {
34 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
35 }
36 });
37 </script>
38</head>
39
40<body>
41 <div>
42 <button id="connectButton">連線錢包</button>
43 </div>
44</body>
45
46</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43 </script>
44</head>
45
46<body>
47 <div>
48 <button id="connectButton">連線錢包</button>
49 </div>
50</body>
51
52</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43 </script>
44</head>
45
46<body>
47 <div>
48 <button id="connectButton">連線錢包</button>
49 </div>
50
51 <div>
52 <p>目前合約訊息:<span id="currentMessage">---</span></p>
53 <button id="readMessageButton">讀取合約訊息</button>
54 </div>
55
56</body>
57
58</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45
46 readMessageButton.addEventListener("click", async () => {
47 if (!contractInstance) {
48 alert("請先按 [連線錢包] 按鈕,再進行操作。");
49 return;
50 }
51 });
52 </script>
53</head>
54
55<body>
56 <div>
57 <button id="connectButton">連線錢包</button>
58 </div>
59
60 <div>
61 <p>目前合約訊息:<span id="currentMessage">---</span></p>
62 <button id="readMessageButton">讀取合約訊息</button>
63 </div>
64
65</body>
66
67</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45
46 readMessageButton.addEventListener("click", async () => {
47 if (!contractInstance) {
48 alert("請先按 [連線錢包] 按鈕,再進行操作。");
49 return;
50 }
51 try {
52 const message = await contractInstance.methods.message().call();
53 console.log("合約訊息為:", message);
54 } catch (error) {
55 console.error(error);
56 alert("讀取合約訊息失敗!");
57 }
58 });
59 </script>
60</head>
61
62<body>
63 <div>
64 <button id="connectButton">連線錢包</button>
65 </div>
66
67 <div>
68 <p>目前合約訊息:<span id="currentMessage">---</span></p>
69 <button id="readMessageButton">讀取合約訊息</button>
70 </div>
71
72</body>
73
74</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45 const currentMessageSpan = document.getElementById("currentMessage");
46
47 readMessageButton.addEventListener("click", async () => {
48 if (!contractInstance) {
49 alert("請先按 [連線錢包] 按鈕,再進行操作。");
50 return;
51 }
52 try {
53 const message = await contractInstance.methods.message().call();
54 console.log("合約訊息為:", message);
55 currentMessageSpan.textContent = message;
56 } catch (error) {
57 console.error(error);
58 alert("讀取合約訊息失敗!");
59 }
60 });
61 </script>
62</head>
63
64<body>
65 <div>
66 <button id="connectButton">連線錢包</button>
67 </div>
68
69 <div>
70 <p>目前合約訊息:<span id="currentMessage">---</span></p>
71 <button id="readMessageButton">讀取合約訊息</button>
72 </div>
73
74</body>
75
76</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45 const currentMessageSpan = document.getElementById("currentMessage");
46
47 readMessageButton.addEventListener("click", async () => {
48 if (!contractInstance) {
49 alert("請先按 [連線錢包] 按鈕,再進行操作。");
50 return;
51 }
52 try {
53 const message = await contractInstance.methods.message().call();
54 console.log("合約訊息為:", message);
55 currentMessageSpan.textContent = message;
56 } catch (error) {
57 console.error(error);
58 alert("讀取合約訊息失敗!");
59 }
60 });
61 </script>
62</head>
63
64<body>
65 <div>
66 <button id="connectButton">連線錢包</button>
67 </div>
68
69 <div>
70 <p>目前合約訊息:<span id="currentMessage">---</span></p>
71 <button id="readMessageButton">讀取合約訊息</button>
72 </div>
73
74 <div>
75 <input type="text" id="newMessageInput" placeholder="輸入新的訊息" />
76 <button id="setMessageButton">寫入合約訊息</button>
77 </div>
78</body>
79
80</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45 const currentMessageSpan = document.getElementById("currentMessage");
46
47 readMessageButton.addEventListener("click", async () => {
48 if (!contractInstance) {
49 alert("請先按 [連線錢包] 按鈕,再進行操作。");
50 return;
51 }
52 try {
53 const message = await contractInstance.methods.message().call();
54 console.log("合約訊息為:", message);
55 currentMessageSpan.textContent = message;
56 } catch (error) {
57 console.error(error);
58 alert("讀取合約訊息失敗!");
59 }
60 });
61
62 // 5. 寫入合約訊息
63 const setMessageButton = document.getElementById("setMessageButton");
64 const newMessageInput = document.getElementById("newMessageInput");
65
66 setMessageButton.addEventListener("click", async () => {
67 if (!contractInstance) {
68 alert("請先按 [連線錢包] 按鈕,再進行操作。");
69 return;
70 }
71 // ... 點擊按鈕並確認連線錢包後要做的事情
72 });
73 </script>
74</head>
75
76<body>
77 <div>
78 <button id="connectButton">連線錢包</button>
79 </div>
80
81 <div>
82 <p>目前合約訊息:<span id="currentMessage">---</span></p>
83 <button id="readMessageButton">讀取合約訊息</button>
84 </div>
85
86 <div>
87 <input type="text" id="newMessageInput" placeholder="輸入新的訊息" />
88 <button id="setMessageButton">寫入合約訊息</button>
89 </div>
90</body>
91
92</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45 const currentMessageSpan = document.getElementById("currentMessage");
46
47 readMessageButton.addEventListener("click", async () => {
48 if (!contractInstance) {
49 alert("請先按 [連線錢包] 按鈕,再進行操作。");
50 return;
51 }
52 try {
53 const message = await contractInstance.methods.message().call();
54 console.log("合約訊息為:", message);
55 currentMessageSpan.textContent = message;
56 } catch (error) {
57 console.error(error);
58 alert("讀取合約訊息失敗!");
59 }
60 });
61
62 // 5. 寫入合約訊息
63 const setMessageButton = document.getElementById("setMessageButton");
64 const newMessageInput = document.getElementById("newMessageInput");
65
66 setMessageButton.addEventListener("click", async () => {
67 if (!contractInstance) {
68 alert("請先按 [連線錢包] 按鈕,再進行操作。");
69 return;
70 }
71 const newMessage = newMessageInput.value;
72 if (!newMessage) {
73 alert("請輸入新的訊息再嘗試。");
74 return;
75 }
76 });
77 </script>
78</head>
79
80<body>
81 <div>
82 <button id="connectButton">連線錢包</button>
83 </div>
84
85 <div>
86 <p>目前合約訊息:<span id="currentMessage">---</span></p>
87 <button id="readMessageButton">讀取合約訊息</button>
88 </div>
89
90 <div>
91 <input type="text" id="newMessageInput" placeholder="輸入新的訊息" />
92 <button id="setMessageButton">寫入合約訊息</button>
93 </div>
94</body>
95
96</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45 const currentMessageSpan = document.getElementById("currentMessage");
46
47 readMessageButton.addEventListener("click", async () => {
48 if (!contractInstance) {
49 alert("請先按 [連線錢包] 按鈕,再進行操作。");
50 return;
51 }
52 try {
53 const message = await contractInstance.methods.message().call();
54 console.log("合約訊息為:", message);
55 currentMessageSpan.textContent = message;
56 } catch (error) {
57 console.error(error);
58 alert("讀取合約訊息失敗!");
59 }
60 });
61
62 // 5. 寫入合約訊息
63 const setMessageButton = document.getElementById("setMessageButton");
64 const newMessageInput = document.getElementById("newMessageInput");
65
66 setMessageButton.addEventListener("click", async () => {
67 if (!contractInstance) {
68 alert("請先按 [連線錢包] 按鈕,再進行操作。");
69 return;
70 }
71 const newMessage = newMessageInput.value;
72 if (!newMessage) {
73 alert("請輸入新的訊息再嘗試。");
74 return;
75 }
76 try {
77 // 發送交易需要指定哪個帳戶做為 from
78 const accounts = await web3.eth.getAccounts();
79 const usedAccount = accounts[0]
80
81 } catch (error) {
82 console.error(error);
83 alert("寫入合約訊息失敗,請查看控制台訊息。");
84 }
85 });
86 </script>
87</head>
88
89<body>
90 <div>
91 <button id="connectButton">連線錢包</button>
92 </div>
93
94 <div>
95 <p>目前合約訊息:<span id="currentMessage">---</span></p>
96 <button id="readMessageButton">讀取合約訊息</button>
97 </div>
98
99 <div>
100 <input type="text" id="newMessageInput" placeholder="輸入新的訊息" />
101 <button id="setMessageButton">寫入合約訊息</button>
102 </div>
103</body>
104
105</html>1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Document</title>
8 <script type="module">
9 import Web3 from "web3";
10 import { contractABI } from "./src/abi.js";
11
12 const contractAddress = "0xFEA4f2C9B99Df0B2b7da67e60371BE4275C3d749";
13
14 let web3; // 用來存放 Web3 物件實例
15 let contractInstance; // 用來存放合約實例
16 const connectButton = document.getElementById("connectButton");
17 connectButton.addEventListener("click", async () => {
18 // 檢查瀏覽器是否安裝了 MetaMask(或其他注入 web3 的錢包)
19 if (typeof window.ethereum !== 'undefined') {
20 try {
21 // 請求錢包授權
22 await window.ethereum.request({ method: 'eth_requestAccounts' });
23
24 // 建立 web3 物件(連到當前 MetaMask 所指向的網路)
25 web3 = new Web3(window.ethereum);
26
27 // 印出當前使用的帳戶
28 const accounts = await web3.eth.getAccounts();
29 console.log('已連線帳戶:', accounts[0]);
30
31 // 建立合約實例
32 contractInstance = new web3.eth.Contract(contractABI, contractAddress);
33
34 alert("錢包連線成功!");
35 } catch (error) {
36 console.error(error);
37 alert("連線錢包失敗,請查看控制台訊息或再次嘗試。");
38 }
39 } else {
40 alert('請先安裝 MetaMask 或其他以太坊錢包外掛!');
41 }
42 });
43
44 const readMessageButton = document.getElementById("readMessageButton");
45 const currentMessageSpan = document.getElementById("currentMessage");
46
47 readMessageButton.addEventListener("click", async () => {
48 if (!contractInstance) {
49 alert("請先按 [連線錢包] 按鈕,再進行操作。");
50 return;
51 }
52 try {
53 const message = await contractInstance.methods.message().call();
54 console.log("合約訊息為:", message);
55 currentMessageSpan.textContent = message;
56 } catch (error) {
57 console.error(error);
58 alert("讀取合約訊息失敗!");
59 }
60 });
61
62 // 5. 寫入合約訊息
63 const setMessageButton = document.getElementById("setMessageButton");
64 const newMessageInput = document.getElementById("newMessageInput");
65
66 setMessageButton.addEventListener("click", async () => {
67 if (!contractInstance) {
68 alert("請先按 [連線錢包] 按鈕,再進行操作。");
69 return;
70 }
71 const newMessage = newMessageInput.value;
72 if (!newMessage) {
73 alert("請輸入新的訊息再嘗試。");
74 return;
75 }
76 try {
77 // 發送交易需要指定哪個帳戶做為 from
78 const accounts = await web3.eth.getAccounts();
79 const usedAccount = accounts[0]
80 const receipt = await contractInstance.methods
81 .setMessage(newMessage)
82 .send({ from: usedAccount });
83
84 console.log("交易回執:", receipt);
85 alert("寫入訊息成功,請再度點擊 [讀取合約訊息] 查看更新。");
86 } catch (error) {
87 console.error(error);
88 alert("寫入合約訊息失敗,請查看控制台訊息。");
89 }
90 });
91 </script>
92</head>
93
94<body>
95 <div>
96 <button id="connectButton">連線錢包</button>
97 </div>
98
99 <div>
100 <p>目前合約訊息:<span id="currentMessage">---</span></p>
101 <button id="readMessageButton">讀取合約訊息</button>
102 </div>
103
104 <div>
105 <input type="text" id="newMessageInput" placeholder="輸入新的訊息" />
106 <button id="setMessageButton">寫入合約訊息</button>
107 </div>
108</body>
109
110</html>
