鏈上智能合約互動

閱讀時間約 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
    查看全部
    發表第一個留言支持創作者!
    Laura 重點專案實作
    閱讀時間約 2 分鐘
    4.11 Twitter Dapp 02 Javascript
    閱讀時間約 17 分鐘
    React Hook - useContext
    閱讀時間約 1 分鐘
    React Forms
    閱讀時間約 1 分鐘
    React Hook
    閱讀時間約 1 分鐘
    Git
    閱讀時間約 5 分鐘
    你可能也想看
    【禾聯家電HERAN】智能變頻禾聯抑菌風扇,奈米銀粒子抑菌扇葉,可遠端遙控超方便! 能夠打擊病菌的電風扇!居家生活實用熱「HERAN禾聯」是土生土長本土家電體系品牌商及自行研發製造商 堅持在台灣一步一腳印 開墾出屬於台灣真正本土技術與行銷差異~ 「HERAN禾聯」銀粒子雙效抑菌扇葉 總共推出黃 紫 綠三款顏色 一眼相中繽紛明亮的黃色 HDF-14AH73Y(黃):https://reurl.cc/o0AZ7q HDF
    Thumbnail
    avatar
    金亮亮部落客吃喝玩樂趣
    2023-06-06
    加密貨幣投資者注意!詐騙集團發行大量與ChatGPT相關的假代幣,幣安智能鏈上就有上百個最近幾週,各個區塊鏈上開始出現ChatGPT token,但這些通通都不是真正由微軟或是OpenAI所發行。目前已經有上百個假代幣在鏈上,各位投資者一定要小心 詐騙集團發行假ChatGPT Token
    Thumbnail
    avatar
    C 琳
    2023-03-06
    用區塊鏈做地方創生──小鎮智能‧黃俊毓做地方創生也需要科技化嗎?何培鈞笑稱做社造的人都不喜歡科技,也不想談數據,「我愛鄉土耶,你要檢視我愛的程度嗎?」然而這卻是他看到的困境,人雖然有了鄉土意識,但只是感情投射,實際執行起來沒有效率和效益,也無法做長期反省,因為經驗都累積在人的情感和腦海中。
    Thumbnail
    avatar
    可可雅。是旅行,也是生活
    2022-07-20
    Blackbear 聯手 Tate McRae,愛上自私的人只能自怨自艾 Hi there,在去年中時 Blackbear 和 Tate McRae 發行了一首合作曲〈u love u〉(2021),目前收錄於 blackbear 的 EP《misery lake》(2021) 中。當時忘記什麼原因我沒有馬上去聽,直到今年初想起這首歌來,一聽之後讓我覺得驚為天人,
    Thumbnail
    avatar
    睿忒
    2022-04-27
    FLOKI INU 通過幣安智能鏈擴展 估值上看百億美金剛開始只是個梗,但是,由伊隆·馬斯克的柴犬(Shiba Inu)所啟發的第一個加密貨幣 FLOKI INU 的發展卻來勢洶洶
    Thumbnail
    avatar
    Top News
    2021-07-20
    Bsc幣安智能鏈上的Btcst比特幣算力幣怎麼挖礦?快來看看到底要怎麼用BTCST挖礦吧~
    Thumbnail
    avatar
    小E班長
    2021-04-20
    BSC幣安智能鏈上的PancakeSwap怎麼玩?Cake怎麼挖礦?如果你還不知道怎麼創建錢包,怎麼把幣轉入錢包的話,請先看這邊👉dapp怎麼玩?cake流動性挖礦?btcst算力幣挖礦?手機黨快看這邊     當我們點完發現後,就會看到pancakeswap在推薦裡,直接點進去 如果沒看到也沒關係,在最上邊的地方直接搜索“pancakeswap"也可以找得
    Thumbnail
    avatar
    小E班長
    2021-04-20
    《無聲救援》:向亂世中進行人道救援的無名英雄致敬假若你活在希特勒統治的法國,你身為自由法國軍團的一員,而你的同胞被他們抓去,活生生剝皮慘死,你會選擇站出來為他報仇、同歸於盡,或是將你身旁成群的猶太孤兒們,護送到中立國瑞士去呢? 《無聲救援》,正是這樣一部充滿掙扎的電影。
    Thumbnail
    avatar
    貓心—龔佑霖
    2020-04-01
    當連儂牆在黑暗中再度盛開 致敬那牆上永不倒下的香港精神連儂牆的再度盛開,體現出香港人對一起出來用公民抗命方式反對極權的戰友一種互相認同的方式;他們深知運動一旦過後,關於那些黑夜的記憶往往慣性地模糊,只留下依稀的影影綽綽,就算偶爾念及,最終往往也無跡可尋。偏偏有些不甘心的人留下墨痕,就算註定將被歷史抹去,也依然頑強提醒世人曾經的可貴。
    Thumbnail
    avatar
    楊勁業
    2019-07-09