鏈上智能合約互動

更新於 2024/06/12閱讀時間約 36 分鐘

0. 大綱Outline

  1. 以太坊交易
  2. 發起交易
  3. 與智能合約互動
  4. receive & fallback function

1. 舊以太坊交易

Ethereum Gas Tracker - 7 Gwei - Etherscan

//交易技術, 表示特定帳戶的交易數量,是計數器, 每發一筆交易一直累加
1. nonce: 0x15

//gas價格 用戶願意為每個gas單位支付的價格
// gas fee= gas price*gas amount 
2. gasPrice 0x4a817c880

//gas限制, 交易可以消耗的最大gas數量
3. gasLimit 0x5208

//接收著地址, 可以是人, 也可以是合約(比方說mint function)
4. to 0x353535353535353533535

//轉移的ETH數量, 這裡是0(native token, 原生幣)
5. value 0x0

//與交易相關的數據, 這裡是空(送這筆交易的附加訊息)
6. data 0x

// ------以上為送交易出去的資訊---------
//-------以下為用私鑰加密這筆簽名-------

// 簽名後產生的參數
7. v 0x1c

// 簽名後產生的參數
8. r 0x....(十六進制數據)

// 簽名後產生的參數
9. s 0x....(十六進制數據)

2. EIP-1559新交易格式

2021年提出

  • maxFeePerGas:用戶願意支付的每單位 gas 的最高價格。
  • maxPriorityFeePerGas:用戶願意支付給礦工的每單位 gas 的小費。(Base + Priority(可以自己決定, 多給礦工, 礦工先處理) = Gas Price
  • gasLimit:用戶願意為交易支付的最多 gas 單位數。(不要超過個區間)
  • accesslist: 如果可以預知能夠訪問到哪些合約地址, 可以比較好的去預測gas fee
  • chainId: 用chainlist去查

    ChainList

3. 以太坊三種基本交易

a. 轉帳

{
"from": "0x17eeeeeeeeeeeeee", //傳送者
"to": "ox302222222333333333", //接收者
"value": "1000000", // 以wei為單位
"data": "0xe, //16進制的附加訊息,有的話就是0xxxxeeee, 沒有的話就是0x
//比方說curve附加訊息出的狀況是語言版本差異造成駭客掏空池子的錢,網址如下
"gasLimit": "300000",
}

掏空並返還Curve池子錢的駭客留下的訊息

b. 智能合約互動

{
"from": "0x17eeeeeeeeeeeeee", //傳送者
"to": "ox302222222333333333", //接收者
"value": "1000000", // 以wei為單位
"data": "0xeeeeeeeeeeeeee, // 0x後面前八個字串表達function, 後面一整串, 表達帶進這個function的參數
//讓節點知道是跟哪個function互動(function selector)
//後面用abi.encode封裝成16進制的字串
"gasLimit": "300000",
}

Keccak-256 - Online Tools

4. 實際鏈上交易

https://etherscan.io/tx/0xbf636aa5c7405377b42bfc6b154a09f4458f5e91c9d256741e9f0ec96a7c4caa

範例合約

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.20;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";


contract MyNFT is ERC721{

using Strings for uint256;

address owner;
uint256 public maxSupply = 10; // 最大發行量, 最多發十張
bool private isOpened = false;//盲盒是否打開

uint256 public counter = 0;

modifier onlyOwner{
require(msg.sender == owner);
_;
}

constructor (string memory _name, string memory _symbol) ERC721(_name, _symbol){
owner = msg.sender;
}

//1. 開盲盒的功能
function openBlindBox() external onlyOwner{
isOpened = true;
}


//2. 設定NFT的baseURI的功能(盲盒)
function _baseURI() internal pure override returns (string memory) {
return "ipfs://QmXxZBg4RnGxC2dDxfUSAmxgGooHsoncPQgCLiNw8kj3Ls/";
}

//3. 查看NFT Metadata網址的功能
function tokenURI(uint256 tokenId) public view override returns (string memory) {
if (!isOpened){
return _baseURI();
}
return string(abi.encodePacked("ipfs://QmWQcaFFCm9ofyVN2ZwGbTGopLEbQ6QSc2Xn1C7ekKAYDF/", tokenId.toString(), ".json"));

}

// 4. 實作mint function的功能,主要用來demo確認用
function mint (address to, uint256 amount) external payable{
require(amount + counter <= maxSupply, "over max supply.");
//這個合約NFT是賣錢的, 一個NFT賣0.01ETH
require(amount * 10000000000000000 == msg.value, "balance error!");
// 迴圈批量鑄造NFT
for(uint256 i=0; i < amount ; i++){
// 鑄造 NFT, counter為NFT的tokenId
_mint(to, counter);
counter ++ ;
}
}

}

Ethereum Unit Converter | Ether to Gwei, Wei, Finney, Szabo ...

鏈上互動套件

  • web3.js
  • ether.js
  • viem

5. Ethers.js

  • js的函式庫, 用於與以太坊RPC交互的工具
  • 以太坊RPC(Remote Procedure Call)是一種通信協議,使開發者能夠通過網絡請求遠程執行各種操作,比如查詢區塊鏈數據、發送交易、部署智能合約等。
  • 註冊RPC

RPC Provider


範例code

import {ethers} from "ethers"; // 引入ethers
import dotenv from 'dotenv';
dotenv.config();

const RPC_URL = process.env.RPC_URL;
const PRIVATE_KEY= process.env.PRIVATE_KEY;

const main = async()=>{

if (!RPC_URL) {
throw new Error("RPC_URL 環境變數未設置。");
}

if (!PRIVATE_KEY) {
throw new Error("PRIVATE_KEY 環境變數未設置。");
}

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const signer = new ethers.Wallet(PRIVATE_KEY, provider);

const contract_address = "0x9c6471C2a6099993299Ca7E1a7E5a22D1F26902C";
const nft_abi = '[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openBlindBox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]';

const contract = new ethers.Contract(contract_address, nft_abi, signer);

try {
const res = await contract.mint("0x3D71D7DC971e9f8405f287A340E8f65a7a1d392a",3, {value: ethers.utils.parseEther("0.03")});
console.log("交易資訊", res);
await res.wait();

} catch (error) {
console.log(error);
}
}


main();

6. 與智能合約互動


[Reference]

1. 鏈上互動

  1. Solidity 教學工作坊第 4 場: 鏈上智能合約互動


    尋大神腳印, 亦步亦趨。
    留言0
    查看全部
    avatar-img
    發表第一個留言支持創作者!
    1. Outline Takeaway Setting up Git and verifying installation Configuring your Git username and email Initializing a new Git repository Stagin
    React Hooks 是 React 16.8 中引入的一組新的 API,允許你在函數組件中使用狀態和其他 React 特性,而不需要寫類組件。 狀態管理: useState 鉤子允許在函數組件中添加狀態。 副作用管理: useEffect 鉤子允許處理副作用,如數據獲取、訂閱和手動 DO
    06. React Forms: Dynamically Add New Input Fields On Click || Learn React Through Mini Projects
    07. React useContext Hook (User Context Example) || Learn React Through Mini Projects
    Overview 1. Request Wallet Connection from Metamask get account function get account function 2. Set your smart contract address injected provide
    1. ERC-20 ERC20 (KryptoCamp) ERC20 (Naz Dumansky) 多簽錢包的設計 - 23:02 🌳 基礎題 1 解答說明: 發行總量100億顆、位數 18 的代幣 - 07:15 🌳 自製 ERC20 交換腦西幣 (HaHow 朱西西) 2. ER
    1. Outline Takeaway Setting up Git and verifying installation Configuring your Git username and email Initializing a new Git repository Stagin
    React Hooks 是 React 16.8 中引入的一組新的 API,允許你在函數組件中使用狀態和其他 React 特性,而不需要寫類組件。 狀態管理: useState 鉤子允許在函數組件中添加狀態。 副作用管理: useEffect 鉤子允許處理副作用,如數據獲取、訂閱和手動 DO
    06. React Forms: Dynamically Add New Input Fields On Click || Learn React Through Mini Projects
    07. React useContext Hook (User Context Example) || Learn React Through Mini Projects
    Overview 1. Request Wallet Connection from Metamask get account function get account function 2. Set your smart contract address injected provide
    1. ERC-20 ERC20 (KryptoCamp) ERC20 (Naz Dumansky) 多簽錢包的設計 - 23:02 🌳 基礎題 1 解答說明: 發行總量100億顆、位數 18 的代幣 - 07:15 🌳 自製 ERC20 交換腦西幣 (HaHow 朱西西) 2. ER
    你可能也想看
    Google News 追蹤
    Thumbnail
    *合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
    Thumbnail
    「HERAN禾聯」是土生土長本土家電體系品牌商及自行研發製造商 堅持在台灣一步一腳印 開墾出屬於台灣真正本土技術與行銷差異~ 「HERAN禾聯」銀粒子雙效抑菌扇葉 總共推出黃 紫 綠三款顏色 一眼相中繽紛明亮的黃色 HDF-14AH73Y(黃):https://reurl.cc/o0AZ7q HDF
    Thumbnail
    最近幾週,各個區塊鏈上開始出現ChatGPT token,但這些通通都不是真正由微軟或是OpenAI所發行。目前已經有上百個假代幣在鏈上,各位投資者一定要小心 詐騙集團發行假ChatGPT Token
    Thumbnail
    做地方創生也需要科技化嗎?何培鈞笑稱做社造的人都不喜歡科技,也不想談數據,「我愛鄉土耶,你要檢視我愛的程度嗎?」然而這卻是他看到的困境,人雖然有了鄉土意識,但只是感情投射,實際執行起來沒有效率和效益,也無法做長期反省,因為經驗都累積在人的情感和腦海中。
    Thumbnail
    Hi there,在去年中時 Blackbear 和 Tate McRae 發行了一首合作曲〈u love u〉(2021),目前收錄於 blackbear 的 EP《misery lake》(2021) 中。當時忘記什麼原因我沒有馬上去聽,直到今年初想起這首歌來,一聽之後讓我覺得驚為天人,
    Thumbnail
    剛開始只是個梗,但是,由伊隆·馬斯克的柴犬(Shiba Inu)所啟發的第一個加密貨幣 FLOKI INU 的發展卻來勢洶洶
    Thumbnail
    如果你還不知道怎麼創建錢包,怎麼把幣轉入錢包的話,請先看這邊👉dapp怎麼玩?cake流動性挖礦?btcst算力幣挖礦?手機黨快看這邊     當我們點完發現後,就會看到pancakeswap在推薦裡,直接點進去 如果沒看到也沒關係,在最上邊的地方直接搜索“pancakeswap"也可以找得
    Thumbnail
    假若你活在希特勒統治的法國,你身為自由法國軍團的一員,而你的同胞被他們抓去,活生生剝皮慘死,你會選擇站出來為他報仇、同歸於盡,或是將你身旁成群的猶太孤兒們,護送到中立國瑞士去呢? 《無聲救援》,正是這樣一部充滿掙扎的電影。
    Thumbnail
    連儂牆的再度盛開,體現出香港人對一起出來用公民抗命方式反對極權的戰友一種互相認同的方式;他們深知運動一旦過後,關於那些黑夜的記憶往往慣性地模糊,只留下依稀的影影綽綽,就算偶爾念及,最終往往也無跡可尋。偏偏有些不甘心的人留下墨痕,就算註定將被歷史抹去,也依然頑強提醒世人曾經的可貴。
    Thumbnail
    *合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
    Thumbnail
    「HERAN禾聯」是土生土長本土家電體系品牌商及自行研發製造商 堅持在台灣一步一腳印 開墾出屬於台灣真正本土技術與行銷差異~ 「HERAN禾聯」銀粒子雙效抑菌扇葉 總共推出黃 紫 綠三款顏色 一眼相中繽紛明亮的黃色 HDF-14AH73Y(黃):https://reurl.cc/o0AZ7q HDF
    Thumbnail
    最近幾週,各個區塊鏈上開始出現ChatGPT token,但這些通通都不是真正由微軟或是OpenAI所發行。目前已經有上百個假代幣在鏈上,各位投資者一定要小心 詐騙集團發行假ChatGPT Token
    Thumbnail
    做地方創生也需要科技化嗎?何培鈞笑稱做社造的人都不喜歡科技,也不想談數據,「我愛鄉土耶,你要檢視我愛的程度嗎?」然而這卻是他看到的困境,人雖然有了鄉土意識,但只是感情投射,實際執行起來沒有效率和效益,也無法做長期反省,因為經驗都累積在人的情感和腦海中。
    Thumbnail
    Hi there,在去年中時 Blackbear 和 Tate McRae 發行了一首合作曲〈u love u〉(2021),目前收錄於 blackbear 的 EP《misery lake》(2021) 中。當時忘記什麼原因我沒有馬上去聽,直到今年初想起這首歌來,一聽之後讓我覺得驚為天人,
    Thumbnail
    剛開始只是個梗,但是,由伊隆·馬斯克的柴犬(Shiba Inu)所啟發的第一個加密貨幣 FLOKI INU 的發展卻來勢洶洶
    Thumbnail
    如果你還不知道怎麼創建錢包,怎麼把幣轉入錢包的話,請先看這邊👉dapp怎麼玩?cake流動性挖礦?btcst算力幣挖礦?手機黨快看這邊     當我們點完發現後,就會看到pancakeswap在推薦裡,直接點進去 如果沒看到也沒關係,在最上邊的地方直接搜索“pancakeswap"也可以找得
    Thumbnail
    假若你活在希特勒統治的法國,你身為自由法國軍團的一員,而你的同胞被他們抓去,活生生剝皮慘死,你會選擇站出來為他報仇、同歸於盡,或是將你身旁成群的猶太孤兒們,護送到中立國瑞士去呢? 《無聲救援》,正是這樣一部充滿掙扎的電影。
    Thumbnail
    連儂牆的再度盛開,體現出香港人對一起出來用公民抗命方式反對極權的戰友一種互相認同的方式;他們深知運動一旦過後,關於那些黑夜的記憶往往慣性地模糊,只留下依稀的影影綽綽,就算偶爾念及,最終往往也無跡可尋。偏偏有些不甘心的人留下墨痕,就算註定將被歷史抹去,也依然頑強提醒世人曾經的可貴。