時(shí)間:2023-08-12|瀏覽:275
原文標(biāo)題:《部署你的第一個(gè)以太坊智能合約》 撰文:談國鵬,Ownbit創(chuàng)始人
以太坊智能合約的學(xué)習(xí)需要理論和實(shí)踐相結(jié)合。最近有不少留言問如何學(xué)習(xí)智能合約,我覺得上手實(shí)踐是學(xué)習(xí)智能合約最有效的方法。
前期準(zhǔn)備 我們將在以太坊主網(wǎng)上部署屬于你的第一個(gè)智能合約,所以你需要一個(gè)ETH賬號(hào),并且擁有一定的ETH,和一個(gè)可以部署合約的以太坊錢包。 本文以使用Ownbit錢包為例講解。
編寫合約 我們編寫一個(gè)非常簡單的合約:MyFirst。它是一個(gè)簡單的合約賬戶,可以接收和發(fā)送ETH。初學(xué)者可以使用Remix工具編寫合約,它具有豐富的編譯調(diào)試功能。
pragma solidity ^0.4.26; // This is the Ownbit 5.0 Contract account. // copyright@2020 ownbit.io contract MyFirst{ address private owner; // An event sent when funds are received. event Funded(uint new_balance); // An event sent when a spend is triggered to the given address. event Withdrawn(address to, uint transfer);
constructor() public payable { owner = msg.sender; }
// The fallback function for this contract. function() public payable{ emit Funded(address(this).balance); }
modifier onlyOwner{ require(msg.sender == owner, "Operation only for the owner!"); _; }
// get the current owner address function getOwner() public view returns(address){ return owner; }
// withdraw ETH to the destination function withdraw(address destination, uint256 value) public onlyOwner{ // check amount require(address(this).balance >= value && address(this).balance > 0, "balance or widthdraw value invalid");
// value 0 means withdraw all if(value == 0){ value = address(this).balance; } // transfer will throw if fails destination.transfer(value);
emit Withdrawn(destination, value); }
// destroy this contract and release some gas function destroyContract() public onlyOwner{ // transfer ether if any if(address(this).balance > 0){ owner.transfer(address(this).balance); }
selfdestruct(owner); } }
一些解釋: modifier是方法的修飾,其中_;表示執(zhí)行該方法。如果未能執(zhí)行_;那么整個(gè)方法體不會(huì)被執(zhí)行; view表示是只讀方法,不修改狀態(tài); require表示驗(yàn)證,如果驗(yàn)證不通過則revert。詳見技術(shù)|Revert,Assert和Require的使用。
編譯合約 在Remix中點(diǎn)擊“Compile first.sol”對(duì)源碼進(jìn)行編譯: 編譯完成后點(diǎn)擊“Compilation Details”可以查看該合約的二進(jìn)制代碼(BYTECODE)和ABI(Application Binary Interface)。
部署合約 向以太坊主網(wǎng)發(fā)送一條交易,讓to為空,data填寫上一步得到的bytecode,即可創(chuàng)建合約。具體步驟如下: 1. 在Ownbit中選擇發(fā)送ETH交易,接收方填寫:deploy-contract 2. 金額處填寫0.01ETH,我們發(fā)送一些ETH給新創(chuàng)建的合約,如果該步驟不想發(fā)送ETH,也可以填寫0。 3. 在高級(jí)選項(xiàng)中將上一步得到的bytecode粘貼進(jìn)去,并且調(diào)整Gas Limit至1,000,000左右。 4. 輸入密碼,交易發(fā)送成功。 5. 交易確認(rèn)后,進(jìn)入etherscan查詢,確認(rèn)合約已成功創(chuàng)建。 至此,合約已成功部署至以太坊主網(wǎng),并且我們得到了新創(chuàng)建的合約賬號(hào)。例子中為:0x164ce3a1d29355e803a0bed9c9e7f8cbbac25139。
和合約互動(dòng) 我們在部署合約的時(shí)候給新建的合約轉(zhuǎn)賬了0.01ETH,因此新合約擁有該數(shù)量的余額。下面我們將該余額轉(zhuǎn)移至另外一個(gè)賬戶。這就要調(diào)用合約的方法。在我們的例子中MyFirst.sol提供了withdraw方法,允許我們將合約的ETH余額向任意地址轉(zhuǎn)移。
因?yàn)榘踩目紤],我們限制了只有合約的創(chuàng)建者(owner)才可以調(diào)用withdraw方法。所以以下步驟必須仍然使用部署合約的地址進(jìn)行操作: 1. 在Remix中獲取withdraw方法的方法哈希(function hash),本例子中該哈希為:f3fef3a3。 2. 在Ownbit中使用owner地址發(fā)送ETH交易,接收方地址填寫該合約地址: 3. 發(fā)送金額填寫0,在高級(jí)選項(xiàng)中填入以下HEX字符串(去掉解釋和回車空行),Gas Limit填寫適當(dāng)較大(如50萬): 0xf3fef3a3 --> 方法哈希 00000000000000000000000097B65aD59C8c96F2dD786751e6279a1A6D34A481 --> 接收方地址,補(bǔ)齊64位 0000000000000000000000000000000000000000000000000000000000000000 --> 0表示發(fā)送所有 4. 交易確認(rèn)后,進(jìn)入etherscan查詢,看到成功調(diào)用的記錄: 5. 可以在etherscan中查看該筆交易發(fā)送參數(shù)的細(xì)節(jié):
以上和合約互動(dòng)(調(diào)用)的例子是以解釋原理為主,從而采用了手動(dòng)封裝參數(shù)的方法。你也可以利用web3js以及Remix中的ABI直接編寫程序調(diào)用合約,而無需手動(dòng)封裝參數(shù)。
結(jié)語 以上詳解了自己部署一個(gè)合約賬戶,并且和它互動(dòng)的詳細(xì)過程。通過實(shí)踐,有了感官認(rèn)識(shí),再補(bǔ)充理論知識(shí),則可事半功倍!
本文例子合約地址。
至于哪些地方學(xué)習(xí)理論,google一下會(huì)有很多。這里跟大家簡單推薦兩處: - 《Solidity docs》 - 《Mastering Ethereum》