4.11 Twitter Dapp 02 Javascript

更新 發佈閱讀 17 分鐘

Overview

1. Request Wallet Connection from Metamask get account function

get account function

2. Set your smart contract address

injected provider address

3. connect to the contract using web3

connect app and smart contract with web3.js

4. call the contract createTweet method in order to crete the actual TWEET

call the function to create the actual tweet

waiting for the function to complete completely

5. call the function getAllTweets from smart contract to get all the tweets

.send - I'm giving you this data

.call - give it to me



6. Call the displayTweets function with address as input

7. Uncomment the displayTweets function! PRETTY EASY 🔥

8. call the likeTweet function from smart contract


index.js

import contractABI from "./abi.json";

// 2️⃣ Set your smart contract address 👇
const contractAddress = "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4";

let web3 = new Web3(window.ethereum);
// 3️⃣ connect to the contract using web3
// HINT: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#new-contract
// let contract = YOUR CODE
let contract = new web3.eth.Contract(contractABI, contractAddress);


async function connectWallet() {
if (window.ethereum) {
// 1️⃣ Request Wallet Connection from Metamask
// ANSWER can be found here: https://docs.metamask.io/wallet/get-started/set-up-dev-environment/
// const accounts = YOUR CODE
const accounts = await window.ethereum
.request({method: "eth_requestAccounts"})
.catch((err) => {
if (err.code === 4001) {
console.log("Please connect to MetaMask.");
} else {
console.error(err);
}
});

console.log(accounts);

setConnected(accounts[0]);
} else {
console.error("No web3 provider detected");
document.getElementById("connectMessage").innerText =
"No web3 provider detected. Please install MetaMask.";
}
}

async function createTweet(content) {
const accounts = await web3.eth.getAccounts();
try {
// 4️⃣ call the contract createTweet method in order to crete the actual TWEET
// HINT: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-send
// use the "await" feature to wait for the function to finish execution
// what is await? https://javascript.info/async-await
await contract.methods.createTweet(content).send({from: accounts[0]});


// 7️⃣ Uncomment the displayTweets function! PRETTY EASY 🔥
// GOAL: reload tweets after creating a new tweet
displayTweets(accounts[0]);
} catch (error) {
console.error("User rejected request:", error);
}
}

async function displayTweets(userAddress) {
const tweetsContainer = document.getElementById("tweetsContainer");
const tempTweets = [];
tweetsContainer.innerHTML = "";
// 5️⃣ call the function getAllTweets from smart contract to get all the tweets
// HINT: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-call
// tempTweets = await YOUR CODE
tempTweets = await contract.methods.getAllTweets(userAddress).call();

// we do this so we can sort the tweets by timestamp
const tweets = [...tempTweets];
tweets.sort((a, b) => b.timestamp - a.timestamp);
for (let i = 0; i < tweets.length; i++) {
const tweetElement = document.createElement("div");
tweetElement.className = "tweet";

const userIcon = document.createElement("img");
userIcon.className = "user-icon";
userIcon.src = `https://avatars.dicebear.com/api/human/${tweets[i].author}.svg`;
userIcon.alt = "User Icon";

tweetElement.appendChild(userIcon);

const tweetInner = document.createElement("div");
tweetInner.className = "tweet-inner";

tweetInner.innerHTML += `
<div class="author">${shortAddress(tweets[i].author)}</div>
<div class="content">${tweets[i].content}</div>
`;

const likeButton = document.createElement("button");
likeButton.className = "like-button";
likeButton.innerHTML = `
<i class="far fa-heart"></i>
<span class="likes-count">${tweets[i].likes}</span>
`;
likeButton.setAttribute("data-id", tweets[i].id);
likeButton.setAttribute("data-author", tweets[i].author);

addLikeButtonListener(
likeButton,
userAddress,
tweets[i].id,
tweets[i].author
);
tweetInner.appendChild(likeButton);
tweetElement.appendChild(tweetInner);

tweetsContainer.appendChild(tweetElement);
}
}

function addLikeButtonListener(likeButton, address, id, author) {
likeButton.addEventListener("click", async (e) => {
e.preventDefault();

e.currentTarget.innerHTML = '<div class="spinner"></div>';
e.currentTarget.disabled = true;
try {
await likeTweet(author, id);
displayTweets(address);
} catch (error) {
console.error("Error liking tweet:", error);
}
});
}

function shortAddress(address, startLength = 6, endLength = 4) {
return `${address.slice(0, startLength)}...${address.slice(-endLength)}`;
}

async function likeTweet(author, id) {
try {
// 8️⃣ call the likeTweet function from smart contract
// INPUT: author and id
// GOAL: Save the like in the smart contract
// HINT: don't forget to use await 😉 👇
await contract.methods.likeTweet(author, id).send({from: accounts[0 ]})
} catch (error) {
console.error("User rejected request:", error);
}
}

function setConnected(address) {
document.getElementById("userAddress").innerText =
"Connected: " + shortAddress(address);
document.getElementById("connectMessage").style.display = "none";
document.getElementById("tweetForm").style.display = "block";

// 6️⃣ Call the displayTweets function with address as input
// This is the function in the javascript code, not smart contract 😉
// GOAL: display all tweets after connecting to metamask
displayTweets(address);
}

document
.getElementById("connectWalletBtn")
.addEventListener("click", connectWallet);

document.getElementById("tweetForm").addEventListener("submit", async (e) => {
e.preventDefault();
const content = document.getElementById("tweetContent").value;
const tweetSubmitButton = document.getElementById("tweetSubmitBtn");
tweetSubmitButton.innerHTML = '<div class="spinner"></div>';
tweetSubmitButton.disabled = true;
try {
await createTweet(content);
} catch (error) {
console.error("Error sending tweet:", error);
} finally {
// Restore the original button text
tweetSubmitButton.innerHTML = "Tweet";
tweetSubmitButton.disabled = false;
}
});

abi.json

just like a IKEA instruction manual to check the information when you get lost



[Reference]

  1. code sandbox
  2. Ultimate Solidity Smart Contract Course - For Complete Beginners
  3. Wallet connection from Metamask document
  4. web3.ethContract
留言
avatar-img
Follow the Rainmaker 🌧️
5會員
91內容數
尋大神腳印, 亦步亦趨。
2024/06/12
0. 大綱Outline 以太坊交易 發起交易 與智能合約互動 receive & fallback function 1. 舊以太坊交易 Ethereum Gas Tracker - 7 Gwei - Etherscan //交易技術, 表示特定帳戶的交易數量,是計數器, 每發一筆交
2024/06/12
0. 大綱Outline 以太坊交易 發起交易 與智能合約互動 receive & fallback function 1. 舊以太坊交易 Ethereum Gas Tracker - 7 Gwei - Etherscan //交易技術, 表示特定帳戶的交易數量,是計數器, 每發一筆交
2024/05/28
在 Solidity 中,constant 變量用於定義不可變的常數值。這些常數在合約的生命週期內不會改變,並且它們的值必須在宣告時設定。使用 constant 關鍵字可以節省 gas,因為它們在編譯時就已經被嵌入到字節碼中,不需要在運行時讀取存儲。 用法 定義常數: 常數變量必須在宣告時初始
2024/05/28
在 Solidity 中,constant 變量用於定義不可變的常數值。這些常數在合約的生命週期內不會改變,並且它們的值必須在宣告時設定。使用 constant 關鍵字可以節省 gas,因為它們在編譯時就已經被嵌入到字節碼中,不需要在運行時讀取存儲。 用法 定義常數: 常數變量必須在宣告時初始
2024/05/27
msg.sender 定義:msg.sender 是 Solidity 中的一個全局變量,表示當前調用合約函數的外部地址。這個地址可以是普通用戶賬戶(EOA)或另一個智能合約。 用途:用於識別誰在調用當前函數。在每次函數調用期間,msg.sender 都會動態地更新為當前調用該函數的賬戶地址。
2024/05/27
msg.sender 定義:msg.sender 是 Solidity 中的一個全局變量,表示當前調用合約函數的外部地址。這個地址可以是普通用戶賬戶(EOA)或另一個智能合約。 用途:用於識別誰在調用當前函數。在每次函數調用期間,msg.sender 都會動態地更新為當前調用該函數的賬戶地址。
看更多
你可能也想看
Thumbnail
在Web3相關技術──比特幣、NFT、以太坊等區塊鏈技術及相關生態系發展下,能源領域的應用與其對能源系統減碳及永續發展的影響,也發揮不少實際的運用案例。
Thumbnail
在Web3相關技術──比特幣、NFT、以太坊等區塊鏈技術及相關生態系發展下,能源領域的應用與其對能源系統減碳及永續發展的影響,也發揮不少實際的運用案例。
Thumbnail
比特幣區塊鏈為了滿足各種不同的需求與技術,目前衍生出四種不同型態的地址形式,主要是針對安全性、靈活性與新版本兼容性的改革。
Thumbnail
比特幣區塊鏈為了滿足各種不同的需求與技術,目前衍生出四種不同型態的地址形式,主要是針對安全性、靈活性與新版本兼容性的改革。
Thumbnail
本文指导如何添加自定义公链,介绍两种方法:通过 Chainlist 添加和手动设置,支持添加多种公链节点,包括以太坊、币安智能链、火币生态链等,方便用户在浏览器中使用自定义公链。 🚀 币安 - 全球最大加密货币交易所 💥 独家优惠 💥 💰 注册即享 20% 手续费返佣 🔑 专属邀请码
Thumbnail
本文指导如何添加自定义公链,介绍两种方法:通过 Chainlist 添加和手动设置,支持添加多种公链节点,包括以太坊、币安智能链、火币生态链等,方便用户在浏览器中使用自定义公链。 🚀 币安 - 全球最大加密货币交易所 💥 独家优惠 💥 💰 注册即享 20% 手续费返佣 🔑 专属邀请码
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
今天談到的 DAO、Web3、DID、加密貨幣錢包⋯⋯都根源於區塊鏈技術。
Thumbnail
今天談到的 DAO、Web3、DID、加密貨幣錢包⋯⋯都根源於區塊鏈技術。
Thumbnail
Mode network 模块化L2 明牌5.5%=550,000,000空投 参与链接https://ref.mode.network/crJzsn邀请码crJzsn 链接钱包验证推特就有基础分,跨链小额即可激活账户 详情 https://mode.network/about-the-airdro
Thumbnail
Mode network 模块化L2 明牌5.5%=550,000,000空投 参与链接https://ref.mode.network/crJzsn邀请码crJzsn 链接钱包验证推特就有基础分,跨链小额即可激活账户 详情 https://mode.network/about-the-airdro
Thumbnail
Launchpad指的是透過交易所或鏈上發行平台指定的代幣,優先申購新的代幣發行ICO(Initial Coin Offering,貨幣首次募資或販售)、IEO(Initial Exchange Offerings,首次交易發行)專案。
Thumbnail
Launchpad指的是透過交易所或鏈上發行平台指定的代幣,優先申購新的代幣發行ICO(Initial Coin Offering,貨幣首次募資或販售)、IEO(Initial Exchange Offerings,首次交易發行)專案。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
Web3钱包是一种数字货币钱包,专为与Web3.0技术和去中心化应用(DApps)集成而设计,Web3.0是指下一代互联网技术,它着重于去中心化、区块链和加密货币等技术的应用,那么,Web3钱包是什么呢?Web3钱包安全吗?下面,我们一起来看看 🚀 币安 - 全球最大加密货币交易所 💥 独家
Thumbnail
Web3钱包是一种数字货币钱包,专为与Web3.0技术和去中心化应用(DApps)集成而设计,Web3.0是指下一代互联网技术,它着重于去中心化、区块链和加密货币等技术的应用,那么,Web3钱包是什么呢?Web3钱包安全吗?下面,我们一起来看看 🚀 币安 - 全球最大加密货币交易所 💥 独家
Thumbnail
介紹: DOP 是一種區塊鏈隱私協議,在以太坊上運行,使用戶能夠精確管理他們希望分享的資訊(資產持有、交易信息等),主打『您的數據,您的選擇』 項目無融資資料,但推特有大佬追蹤,Kevin Susanto、nftguyy和哥吉拉聯合創辦人shan
Thumbnail
介紹: DOP 是一種區塊鏈隱私協議,在以太坊上運行,使用戶能夠精確管理他們希望分享的資訊(資產持有、交易信息等),主打『您的數據,您的選擇』 項目無融資資料,但推特有大佬追蹤,Kevin Susanto、nftguyy和哥吉拉聯合創辦人shan
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News