在 Ethereum 部署智慧型合約及管理交易
若要在 Ethereum 建立分散式應用程式,您必須了解如何傳送交易、登入並向網路廣播。交易可讓您傳輸乙太、部署您自己的合約,以及與其他智慧型合約互動。在本教學課程中,我們將逐步說明如何安心執行這些操作,也會說明一些相關的資料庫和指令,讓您能以更輕鬆的方式製作開發工作流程。
若要在 Ethereum 建立分散式應用程式,您必須了解如何傳送交易、登入並向網路廣播。交易可讓您傳輸乙太、部署您自己的合約,以及與其他智慧型合約互動。在本教學課程中,我們將逐步說明如何安心執行這些操作,也會說明一些相關的資料庫和指令,讓您能以更輕鬆的方式製作開發工作流程。
建立 Ethereum 交易
交易是在區塊鍊中的狀態變更操作。交易的範例包括傳送乙太、語彙基元,以及建立或使用智慧型合約中的功能。如果您是初次接觸 Ethereum 中的交易,請參閱這篇 Ethereum 交易的帳戶、合約及類型實用介紹。此外,在此存放庫中,您可以找到一系列的指令碼,讓您了解如何使用兩種最熱門的 Javascript 資料庫與 Ethereum 互動:web3.js 和 ethers.js。如要進一步了解 web3.js 與 ethers.js 的差異,請參閱我們的技術指南,其中我們有細述其相同點與差異處。
程序中的第一步,就是建立交易裝載。這可讓您設定您要執行的操作類型,以及您為了執行該操作願意支付的金額 (燃料費用)。讓我們來看看這些屬性:
from:DATA,20 位元
- 送出交易的位址。
to:DATA,20 位元
- (建立新合約時為非必要):要將交易導向至的位置。
value:數量
- (選擇性):與此交易一起傳送的值整數。
gas:數量
- (選擇性,預設:90000):執行交易提供的燃料整數。將傳回未使用的燃料。
gasPrice:數量
- (選擇性,預設:尚未決定):您為了執行交易而願意針對每個燃料單位所支付的金額整數 (以 gwei 為單位)。
data:DATA
- 合約部署:合約的編譯程式碼。
- 合約互動:呼叫的方法簽章及編碼的參數雜湊。如需詳細資料,請參閱《Ethereum 合約 ABI》。
- 簡易乙太傳輸:「data」將為空白。
nonce:數量
- (選擇性):Nonce 的整數。這會維持處理交易的順序,並讓您可以覆寫自己使用相同 Nonce 的待處理交易。
身為 Dapp 開發人員,您可以利用自己的 Web3 公用程式程式庫來填寫大多數的詳細資料。您可以在下方查看更詳細的描述,了解如何依照您要執行的操作類型製作這些交易。
簽署交易
產生交易後,您必須簽署,然後 Ethereum 網路才能接受交易。簽章有兩個目的:1) 授權交易為自您的帳戶發出,以及 2) 授權網路從您的帳戶扣除交易燃料費用。
簽署 Ethereum 交易的方式有很多,其中包括:
- 搭配於本機管理的不公開金鑰使用您偏好使用的 Web3 資料庫簽署功能
- 使用個別的簽署服務 (EthSigner)
- 委派簽署程序至使用者錢包 (例如:Metamask 或 Gnosis、Argent,透過 WalletConnect)
- 使用 Ethereum 節點內建的簽署功能
以下是不同方式的幾個範例:
在大多數的情況下,您的 Web3 公用程式程式庫 (例如 ethers.js 或 web3.js) 通常會擷取完成簽署的交易並加以序列化,然後透過 eth_sendRawTransaction RPC 呼叫將其傳送至節點。
如果您選擇使用 Ethereum 節點內建的簽署功能 (上一個案例),則資料庫會使用不同的 RPC 呼叫,也就是 eth_sendTransaction,而這會以純文字格式傳送未簽署的交易詳細資料至節點。Infura 不支援此互動模式,因此如果您要使用此方法,目前您必須提供自己節點的主機服務。請注意,由於這個功能需要您的節點儲存不公開金鑰並向網路公開 RPC,因此並非安全的方式 (未經授權存取節點可能導致您的不公開金鑰遭竊,也會讓攻擊者可以代表您簽署交易)。如果您是執行自己的節點,Hyperledger Besu 有非常實用的 Proxy 服務,也就是 EthSigner,這可以協助您簽署交易,並將您的金鑰安全地儲存在個別的檔案或 Keystore,然後採取 eth_sendTransaction 方式。Ethsigner 可搭配任何 Ethereum 用戶端使用,並且也支援 Infura。您必須使用單一登入工具或多重登入工具設定 Ethsigner,然後才能進行交易。
使用 Infura 傳送 Ethereum 交易
簽署交易後,就必須向 Ethereum 網路進行廣播,這樣其他節點才能查看,而挖礦程式也才能將其納入區塊鍊中。
Infura 提供標準的 eth_sendRawTransaction RPC 方式,使用者種方式時,資料庫通常會在背景中廣播交易,這樣您就不需要手動呼叫 RPC 方式。
有的時候 Ethereum 挖礦程式會取得交易的副本、為包含副本的新區塊完成工作驗證,並向網路的其他地方廣播有其工作驗證的區塊。每個收到此區塊的節點會在內部重新執行交易,並更新 Ethereum Virtual Machine (EVM)* 的狀態。
*注意:挖礦程式收到和選擇交易的過程,以及當挖礦程式完成工作驗證後區塊如何傳播至網路的方式其實相當複雜。為了簡化此教學課程,我們在這裡不會深入說明這些主題。
乙太傳輸
乙太傳輸是最簡單的交易型態,因為乙太傳輸是原生 EVM 指示,不需要智慧型合約。我們只要指定目的地位址、燃料價格及我們要傳送的乙太值 (以 wei 計價,也就是 1e-18 乙太) 即可。然後我們要簽署交易,這樣系統就會指派 nonce 值和簽章給該筆交易。
範例:使用簡單交易簽署並傳送乙太
先決條件:確認您已安裝 Node.js 12+,並且可使用 Infura 專案 ID。複製此存放庫然後執行:
cd demo-eth-tx/
npm install
# Add your Infura Project ID below
echo 'INFURA_PROJECT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' > .env
現在,這裡有一個可以在兩個帳戶之間,使用 ethers.js 資料庫傳送小額乙太的指令碼。執行後,等待交易挖礦完成:
node ethers/send.js
相同的指令碼,使用 web3.js 資料庫。執行時請搭配:
node web3/send.js
Smart Contract Compilation and Deployment
智慧型合約編譯和部署
合約部署是另一種原生 EVM 操作,與乙太傳輸非常相向,但是在此案例中,我們將提供 data 參數的值,而不是 to 參數。
我們將針對 data 傳輸的引數將包含我們部署的合約 Bytecode。合約的 Bytecode 可使用 Solc Compiler 衍生 (如果使用 Solidity (建議))。
注意:開始建立您自己的智慧型合約時,建議您使用開發套件,例如:Truffle、Buidler 或 Remix。使用這些工具,您就不需要手動編譯自己的智慧型合約程式碼,讓您更輕鬆
範例:使用智慧型合約
現在我們將說明撰寫、部署智慧型合約及與之互動所需的步驟。
讓我們從簡易型合約 (Demo.sol) 開始說起:
contract Demo {
event Echo(string message);
function echo(string calldata message) external {
emit Echo(message);
}
}
這種合約只有單一方式 (稱為 echo),可由任何有 message 的人士呼叫,而且會發出與輸入 message 相同的事件。
合約編譯
在網路中部署合約前,我們必須先加以編譯。這裡附上的 compile.js 簡易指令碼目前就已經足夠使用:
node compile.js
完成編譯合約後,Demo.json 檔案就會在主目錄中顯示。此檔案包含合約 Bytecode (部署時需要),以及合約互動需要的 Application Binary Interface (ABI)。
合約部署
以下是 ethers.js 和 web3.js 的部署指令碼。執行任一指令碼即可部署您的合約:
node ethers/deploy.js
# or
node web3/deploy.js
合約部署完成後,您就會收到交易雜湊。您可以使用區塊總管或使用 getTransaction() 和 eth.getTransactionReceipt() 進行檢視。部署交易挖礦完成後,指令碼就會輸出新合約的位址。
合約互動
現在合約已經部署完成,您可以與之互動。若要製作交易,您將必須傳輸合約的位址至 to 參數及部分資料,指示合約如何執行至 data 參數。
Web3 公用程式程式庫可為您提供高層級的介面,讓您可以發出合約並建立 data 參數。
以下我們將簡短說明這些資料庫在背景中執行的操作:data 欄的第一個部分,是功能選擇工具,這個工具與叫用的合約方式相關聯。我們可以擷取功能名稱雜湊的前 4 個位元,及其小括號內的引數類型 (刪除所有空格) 來計算功能選擇工具。舉例來說,字串傳輸 (address,uint256) 可以雜湊成 4 位元功能簽章 0xa9059cbb。功能簽章會與 RLP 編碼的功能引數 (此範例中語彙基元的位址和數量) 串聯,填入交易 data 欄。若要進一步了解合約 ABI 規格和引數編碼,請參閱《Solidity ABI 規格》。
現在,以下是 ethers.js 和 web3.js 的合約互動指令碼。指令碼會設定為與較舊、現有的合約互動,但是您也可以編輯 ethers/call.js 的此行,或 web3/call.js 的此行,然後以您新部署合約的位址加以取代。
現在您可以執行:
node ethers/call.js
# or
node web3/call.js
恭喜!您已部署 Ethereum 智慧型合約並與之互動。現在您可以施展身手了!🚀
Infura 為開發人員提供快速、可靠的 Ethereum 和 IPFS 網路存取。我們的核心服務為免費提供,並且可為開發人員提供一切所需,協助開發人員製作分散式應用程式。如果您需要更多要求量和直接支援,請參閱我們的 Infura+ 以選擇適合您專案的方案。
非常感謝 Lucian Boca 在本指南中提供的豐富知識與詳細介紹。如需更多 Web3 教學課程,請參閱《Infura 網誌 》,或訂閱我們的電子報。 🧡