在區塊鏈中
最重要的其中一個核心理念就是 "不可篡改性"
自然會很希望能查詢到 所期待的歷史資訊
因此透過查詢能獲得區塊鏈資訊
亦是去中心化應用程序(DApp)中非常重要的一環
這篇將以下重點進行敘述:
另外可參考 GitHub 專案位置:
https://github.com/weiawesome/dapp_website
寫下本頁面的目標
可以自己填寫要連接的乙太坊網路
各種查詢區塊資訊的方式 (左 web3.js 右 ethers.js)
各種查詢交易資訊的方式 (左 web3.js 右 ethers.js)
├── src
│ ├── app
│ ├── pages
│ │ ├── get_information.tsx
│ ├── style
│ │ ├── get_information.css
│
"src/app/pages/get_information.tsx" 邏輯與基本布局
"src/app/style/get_information.css" 對上述畫面的修飾
因此 最後畫面會顯示在 /get_information 這個路由下
// 區塊的資訊
class BlockInfo{
// 區塊高度
BlockHeight:number
// 區塊哈希值
BlockHash:string
// 前一區塊哈希值
PreviousHash:string
}
// 交易的資訊
class TransactionInfo{
// 交易所在區塊的區塊高度
BlockHeight:number
// 交易哈希值
Hash:string
// 交易發起人地址
From:string
// 交易接收人地址
To:string
// 交易金額
Amount:string
// 交易手續費
Fee:string
}
由於二者完整資訊過多 不方便作為呈現
因此就選擇數個屬性作為展示的效果
// 獲取當前最新區塊高度
const getBlockHeightWeb3=()=>{
const url=urlRef.current?.value.toString()
const web3 = new Web3(url);
web3.eth.getBlockNumber()
.then(blockNumber => {
console.log('最新區塊高度:', blockNumber);
setLastBlockNumberWeb3(Number(blockNumber));
})
.catch(error => {
console.error('獲取區塊高度時發生錯誤:', error);
});
}
// 從區塊高度尋找區塊
const getBlockByHeightWeb3=()=>{
const url=urlRef.current?.value.toString()
const web3 = new Web3(url);
const blockNumber=Number(heightRef.current?.value);
web3.eth.getBlock(blockNumber).then(blockInfo => {
if (blockInfo) {
let tmp=new BlockInfo();
tmp.BlockHeight=Number(blockInfo.number);
tmp.BlockHash=blockInfo.hash;
tmp.PreviousHash=blockInfo.parentHash;
setBlockByHeightWeb3(tmp);
console.log('區塊資訊:', blockInfo);
} else {
alert(`找不到區塊號 ${blockNumber} 的資訊。`);
}
}).catch(error => {
alert('發生錯誤:'+ error);
});
}
// 從區塊哈希尋找區塊
const getBlockByHashWeb3=()=>{
const url=urlRef.current?.value.toString()
const web3 = new Web3(url);
const blockHash=hashRef.current?.value;
web3.eth.getBlock(blockHash,true).then(blockInfo => {
if (blockInfo) {
let tmp=new BlockInfo();
tmp.BlockHeight=Number(blockInfo.number);
tmp.BlockHash=blockInfo.hash;
tmp.PreviousHash=blockInfo.parentHash;
setBlockByHashWeb3(tmp);
console.log('區塊資訊:', blockInfo);
} else {
alert(`找不到區塊號 ${blockHash} 的資訊。`);
}
}).catch(error => {
alert('發生錯誤:'+ error);
});
}
其實就是獲取目前區塊鏈的長度
可以直接根據區塊高度尋找到相對應的區塊資訊 並更新相關資訊
可以直接根據區塊哈希尋找到相對應的區塊資訊 並更新相關資訊
// 從交易哈希獲取交易相關資訊
const getTransactionWeb3=()=>{
const url=urlRef.current?.value.toString()
const web3 = new Web3(url);
const transactionHash = transactionHashRef.current?.value.toString();
web3.eth.getTransaction(transactionHash)
.then(transactionInfo => {
if (transactionInfo) {
console.log('交易資訊:', transactionInfo);
let tmp=new TransactionInfo();
tmp.From=transactionInfo.from;
tmp.To=transactionInfo.to!;
tmp.Amount=formatEther(transactionInfo.value);
tmp.Fee=formatEther(transactionInfo.gasPrice);
tmp.BlockHeight=Number(transactionInfo.blockNumber);
tmp.Hash=transactionInfo.hash;
setTransactionWeb3(tmp);
} else {
alert(`找不到交易哈希 ${transactionHash} 的資訊。`);
}
}).catch(error => {
alert('發生錯誤:'+ error);
});
}
從交易哈希去尋找相符合的交易 並設定相關資訊
// 獲取最新區塊高度
const getBlockHeightEthers=()=>{
const url=urlRef.current?.value.toString()
const provider = new ethers.JsonRpcProvider(url);
provider.getBlockNumber().then(blockNumber => {
setLastBlockNumberEthers(blockNumber);
}).catch((e)=>{
alert("error: "+e);
});
}
// 從區塊高度尋找區塊
const getBlockByHeightEthers=()=>{
const url=urlRef.current?.value.toString()
const provider = new ethers.JsonRpcProvider(url);
const blockNumber=Number(heightRef.current?.value);
provider.getBlock(blockNumber).then(blockInfo => {
if (blockInfo) {
let tmp=new BlockInfo();
tmp.BlockHeight=blockInfo.number;
tmp.BlockHash=blockInfo.hash;
tmp.PreviousHash=blockInfo.parentHash;
setBlockByHeightEthers(tmp);
console.log('區塊資訊:', blockInfo);
} else {
alert(`找不到區塊號 ${blockNumber} 的資訊。`);
}
}).catch(error => {
alert('發生錯誤:'+ error);
});
}
// 從區塊哈希尋找區塊
const getBlockByHashEthers=()=>{
const url=urlRef.current?.value.toString()
const provider = new ethers.JsonRpcProvider(url);
const blockHash=hashRef.current?.value;
provider.getBlock(blockHash).then(blockInfo => {
if (blockInfo) {
let tmp=new BlockInfo();
tmp.BlockHeight=blockInfo.number;
tmp.BlockHash=blockInfo.hash;
tmp.PreviousHash=blockInfo.parentHash;
setBlockByHashEthers(tmp);
console.log('區塊資訊:', blockInfo);
} else {
alert(`找不到區塊號 ${blockHash} 的資訊。`);
}
}).catch(error => {
alert('發生錯誤:'+ error);
});
}
可以直接獲得最新區塊的區塊高度 即獲得區塊鏈長度
// 從交易哈希獲取交易相關資訊
const getTransactionEthers=()=>{
const url=urlRef.current?.value.toString();
const provider = new ethers.JsonRpcProvider(url);
const transactionHash=transactionHashRef.current?.value.toString();
provider.getTransaction(transactionHash).then(transactionInfo => {
if (transactionInfo) {
console.log('交易資訊:', transactionInfo);
let tmp=new TransactionInfo();
tmp.From=transactionInfo.from;
tmp.To=transactionInfo.to;
tmp.Amount=formatEther(transactionInfo.value);
tmp.Fee=formatEther(transactionInfo.gasPrice);
tmp.BlockHeight=transactionInfo.blockNumber;
tmp.Hash=transactionInfo.hash;
setTransactionEthers(tmp);
} else {
alert(`找不到交易哈希 ${transactionHash} 的資訊。`);
}
}).catch(error => {
alert('發生錯誤:'+ error);
});
}
從交易哈希去尋找相符合的交易 並設定相關資訊
如果想要連接到以太坊主網(Ethereum Mainnet)
可以使用 以太坊節點提供者 或 自己運行的以太坊節點
以太坊節點提供者 可以使用 Infura
以下為介紹如何使用 Infura
Infura 官方網站: https://www.infura.io/zh
上圖取自於(https://www.infura.io/zh)網頁畫面
上圖取自於(https://www.infura.io/zh)網頁登入畫面
上圖取自於(https://www.infura.io/zh)網頁主畫面
上圖取自於(https://www.infura.io/zh)網頁API-KEY創建畫面
上圖取自於(https://www.infura.io/zh)網頁API-KEY畫面
乙太坊區塊鏈連覽器: https://etherscan.io/blocks
區塊鏈連覽器(對應區塊資料): https://etherscan.io/block/18314410
資料取自於(https://etherscan.io/block/18314410)
透過以下交易為例子:
圖片與資料取自於(https://etherscan.io/tx/0xa674e253eec4ebf4cfd4c83f708fd32cc5e3c938a0e1d6b7ab4b15452847d1c5)
圖片與資料取自於(https://etherscan.io/tx/0xa674e253eec4ebf4cfd4c83f708fd32cc5e3c938a0e1d6b7ab4b15452847d1c5)
備註:
在此處也可以使用 Ganache 模擬區塊鏈
相對資訊可能也沒有現實區塊鏈麼複雜 也比較容易觀察
如果要使用 Ganache 模擬區塊鏈 網路
則 URL 部分直接填入 HTTP://127.0.0.1:7545 即可
(根據自己設定可能會有所不同)
現在可以輕鬆地拿到區塊鏈上所有資料
這就是區塊鏈的公開性
正是因為透過這樣的特性 可以衍伸出許多有趣的應用
希望透過這篇能夠理解
嗚嗚嗚 這下還能觀察區塊鏈上所有資訊了
資訊是看透透了 不過比起看資訊 更想創建資訊!!!
虛擬貨幣 最基礎的就是交易
那那 可以直接進行交易嗎?
感覺超酷的吧 ~~~