1. 程式人生 > >第十課 Solidity語言編輯器REMIX指導大全

第十課 Solidity語言編輯器REMIX指導大全

1. 文章摘要

【說明】未列出的課程為知識普及的非實操類課程,所有區塊鏈文章參考“區塊鏈入口”專欄。

#2. 使用REMIX編輯器執行"HELLO WORLD"的智慧合約 REMIX是一個智慧合約程式語言Solidity的整合開發環境。 最簡單的入門就是進行"HELLO WORLD"的程式執行。

##2.1 智慧合約編譯 在CHROME瀏覽器上點選連結REMIX官網瀏覽器版編輯器即可開啟REMIX編輯器。部分不能正常訪問官網的,可以訪問筆者的國內REMIX編輯器。 新增一個命名為“HelloWorld.sol”的檔案,複製以下程式碼:

pragma solidity ^0.4.17;

contract Hello         
{
    address creator;     
    string greeting;     

    function Hello(string _greeting) public   
    {
        creator = msg.sender;
        greeting = _greeting;
    }
    

    function greet() public constant returns (string)           
    {
        return greeting;
    }
    
    function setGreeting(string _newgreeting) public
    {
        greeting = _newgreeting;
    }
    
     /**********
     Standard kill() function to recover funds 
     **********/
    
    function kill() public
    { 
        if (msg.sender == creator)
            suicide(creator);  // kills this contract and sends remaining funds back to creator
    }

}

點選"Start to compile"按鈕,會得到一下結果:0.智慧合約編譯.png 除一些函式的告警提示外,結果表明該智慧合約編譯成功。

###2.1.1 編譯告警 如果編寫的程式有告警,REMIX會有提示。一般來說,提示不必修改。REMIXD編譯告警

###2.1.2 編譯錯誤 為了說明編譯錯誤案例,把該檔案的第17行"return greeting;“改為"return _greeting;”, 重新編譯,得到以下結果REMIXD編譯錯誤

如果編寫的Solidity程式存在語法錯誤,Remix編譯器會以粉紅色底色提示顯示錯誤原因,並在編輯器視窗提示位置。 編譯錯誤演示完後,恢復第17行程式碼為"return greeting;" ###2.1.3 詳情資訊 點選"Detail"按鈕,可以看到詳細資訊。其中WEB3DEPLOY部分的內容就是在案例

《第二課 如何實現以太坊最簡智慧合約“Hello World”的執行》中geth控制檯使用的編譯後代碼。DETAIL的內容

##2.2 智慧合約執行 1. 建立智慧合約 選擇“Run”的頁面,選擇Environment環境為Javascript VM,在“Create”按鈕前輸入框內輸入"Hello World!"[注意:輸入字串一定要有英文雙引號],點選“Create”按鈕。建立智慧合約 2. 執行greet函式 點選淺藍色函式"greet"按鈕,可以看到輸出結果為“Hello World!” 執行函式greet **說明:**淺藍色按鈕函式表示該交易函式執行時不需要消耗GAS的。

3. 執行setGreeting函式 在setGreeting函式按鈕的輸入框輸入內容"Hello Duncan!", 執行後在點選執行"greet"函式,發現該函式的輸出內容已變為"Hello Duncan!"了,說明setGreeting執行正常。 執行函式SetGreeting

**說明:**粉紅色按鈕函式表示該交易函式執行時是需要消耗GAS的。

#3. REMIX介面詳解 第2章以“Hello World”為例,介紹了REMIX整合環境的基本使用方法。本章介紹REMIX編輯器的詳細功能描述。 ##3.1 REMIX整合環境概述 REMIX是一個智慧合約程式語言Solidity的整合開發環境,它集成了一個偵錯程式和測試環境。 如果你對以下內容感興趣,REMIX是一個不錯的學習方式: 1,開發智慧合約(REMIX集成了SOLIDITY編輯器) 2,除錯智慧合約 3,獲取已執行合約的狀態和屬性 4,除錯已經提交的合約 5,分析SOLIDITY程式碼,以便減少編碼錯誤和加強最佳實踐 6,配合Mist(或者任何植入web3的工具),REMIX可用於測試和除錯DAPP分散式程式。(參考連結Debugging a Dapp using Remix - Mist - Geth ) 詳解介紹使用的程式案例為"ballot.sol"檔案的程式碼,完整程式碼如下:

pragma solidity ^0.4.0;
contract Ballot {

    struct Voter {
        uint weight;
        bool voted;
        uint8 vote;
        address delegate;
    }
    struct Proposal {
        uint voteCount;
    }

    address chairperson;
    mapping(address => Voter) voters;
    Proposal[] proposals;

    /// Create a new ballot with $(_numProposals) different proposals.
    function Ballot(uint8 _numProposals) public {
        chairperson = msg.sender;
        voters[chairperson].weight = 1;
        proposals.length = _numProposals;
    }

    /// Give $(toVoter) the right to vote on this ballot.
    /// May only be called by $(chairperson).
    function giveRightToVote(address toVoter) public {
        if (msg.sender != chairperson || voters[toVoter].voted) return;
        voters[toVoter].weight = 1;
    }

    /// Delegate your vote to the voter $(to).
    function delegate(address to) public {
        Voter storage sender = voters[msg.sender]; // assigns reference
        if (sender.voted) return;
        while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
            to = voters[to].delegate;
        if (to == msg.sender) return;
        sender.voted = true;
        sender.delegate = to;
        Voter storage delegateTo = voters[to];
        if (delegateTo.voted)
            proposals[delegateTo.vote].voteCount += sender.weight;
        else
            delegateTo.weight += sender.weight;
    }

    /// Give a single vote to proposal $(toProposal).
    function vote(uint8 toProposal) public {
        Voter storage sender = voters[msg.sender];
        if (sender.voted || toProposal >= proposals.length) return;
        sender.voted = true;
        sender.vote = toProposal;
        proposals[toProposal].voteCount += sender.weight;
    }

    function winningProposal() public constant returns (uint8 _winningProposal) {
        uint256 winningVoteCount = 0;
        for (uint8 prop = 0; prop < proposals.length; prop++)
            if (proposals[prop].voteCount > winningVoteCount) {
                winningVoteCount = proposals[prop].voteCount;
                _winningProposal = prop;
            }
    }
}

REMIX主介面截圖如下,具體說明參考各個子章節。REMIX主介面截圖 具體介面介紹章節分類如下: 3.2 檔案瀏覽器 3.3 Solidity語言編輯器 3.4 終端輸出器 3.5 分頁控制面板 3.5.1 編譯合同 3.5.2 執行 3.5.3 除錯 3.5.4 設定 3.5.5 分析 3.5.6 支援

##3.2 檔案瀏覽器 檔案瀏覽器 1)增加新檔案(Create new File) 點選在瀏覽器上增加一個新的智慧合約檔案 9.增加新檔案.png

2)開啟檔案(Add Local File) 開啟存在檔案 3) 匿名釋出到GitHub(Publish to Gist) 11. 匿名釋出到GitHub.png

4) 複製檔案列表到其他瀏覽器(Copy to another instance) 例如,把“http://remix2.ju3ban.net”的檔案列表複製到另一個瀏覽器“http://remix.ju3ban.net” 修改輸入目標瀏覽器的網址:12.複製到別的瀏覽器.png

開啟新的瀏覽器,檔案列表已複製過來了:13.別的瀏覽器的檔案列表.png

5)連結本地伺服器(Connect to Localhost) 在Remix檔案瀏覽器上的檔案並不會同步到本地檔案系統,對瀏覽器檔案列表的新增/修改/刪除並不會同步本地檔案。一般操作時,除錯成功的程式碼需要在本地檔案系統新建檔案儲存。Remix瀏覽器提供了一種方法,就是使用Remixd,允許儲存和同步瀏覽器檔案到你的本地計算機中。因為根據官網文件,筆者沒有能夠在Windows 10系統或者Ubuntu中安裝成功Remixd,本文不再詳細介紹該功能。有興趣的朋友歡迎根據官網文件嘗試使用REMIXD同步。成功者歡迎跟輝哥反饋交流,補充完整這個文件。

14. 連結本地檔案系統.png

Solidity語言編輯器重要的功能列表: 1,TAB頁面顯示開啟的檔案 2,編譯告警或者錯誤會顯示在編輯器最左側邊 3,Remix自動儲存當前檔案(修改後5秒內) 4,+/- 表示增加/減少編輯器的字型大小

##3.4 終端輸出器 終端輸出器視窗

終端輸出器功能說明: 1,點選1按鈕可隱藏終端輸出器 2,點選2按鈕可情況輸出器內容 3,點選3按鈕可複製地址資訊等到快取,便於貼上 4,點選Details按鈕可展開交易詳細內容 5, 點選Debug按鈕可除錯該交易合約 6, 點選複選框,可增加選擇顯示所有的交易還是隻顯示智慧合約相關的交易程式。預設只顯示後者。 17. 終端顯示內容.png 7,輸入關鍵字可搜尋定位輸出內容 例如輸入"Hello "關鍵字,相關的內容就顯示出來了。 18. 搜尋Hello關鍵字 8,監聽網路(Listen to network) 勾選後,REMIX不僅監聽REMIX編輯器中建立的交易,還監聽當前環境中所有的交易。

##3.5 分頁控制面板 ###3.5.1 編譯合約 20. Compile控制面板.png

1,釋出到Swarm網路(Publish on Swarm) 點選“Publish on Swarm”按鈕可把智慧合約原始碼和對應的ABI資訊釋出到網路上。這個合約智慧是非抽象類的才能釋出。 合約釋出後,你可以點選Detail按鈕,在彈出視窗的“SWARM LOCATION” 位置找到對應的MetaDATA資訊。 資訊中的SWARM LOCATION位置有對應網址,在能科學上網的計算機就可找到該合同的MetaData資訊 “bzzr://165fad4c3d8ead3a7fe28296777b4bedafb09bb57de2e9ba39c1547866437182”

###3.5.2 執行 21. Run控制面板.png

重點特性說明 1) 環境選擇 JavaScript VM: 所有交易在瀏覽器的沙盒中被執行。這以為著沒有結果是永久儲存的。當頁面過載後,一個新的區塊鏈會被從零開始執行,老的會被丟棄。 Injected Provider: Remix將連線被植入的Web3物件。例如Mist或者Metamask錢包是提供植入的Web3物件的例子。例如《第八課 如何除錯以太坊官網的智慧合約眾籌案例》就是使用Meta的賬號。 Web3 Provider: Remix將連線到一個遠端節點。你可以用這個地址來選擇錢包客戶端:geth, parity or any Ethereum client.

2) 初始化合約 1] 建立合約 “Create”按鈕用於建立合約。合約建立時,需要參考左邊構建函式定義(智慧合約的同名函式為構建函式)的型別來輸入引數。 25. 建立合約.png 注意:如果輸入引數為地址或者字串,都需要使用英文雙引號("")囊括起來,使用英文(",")表示輸入引數分割。

2] 執行合約 假設給出的地址是一個選擇合同的例項。通過這種方法就可以跟已經執行的合同進行互動。要特別謹慎使用該功能,因為系統不做驗證。執行時要確認信任這個地址的合同。

3] 等待(pending)合約 26,掛起合約.png

等待合約表示還沒有完成執行過程的合約。按鈕功能描述參考上述附件。

####3.5.1.1 Web3 Provider遠端節點配置 1) 啟動Ganache客戶端。不熟悉的,可參考該篇文章的對應關鍵字“在WINDOWS上安裝Ganache”安裝好客戶端。22. 啟動Ganache客戶端.png

2) 輸入Web3 Provider遠端節點,例如Ganache的籤寶地址為“HTTP://127.0.0.1:754523. 輸入WEB3 privider的伺服器地址.png

3) 輸入完成後,Remix的賬號列表更新為Ganache的賬號列表了。 24. 賬號為Ganache的賬號列表.png

###3.5.4 設定 27. Settiongs.png 重要特性說明: (1)Solidity version:編譯SOLIDITY版本,不調整的話系統會預設選擇最新正式釋出的版本。 (2)Always use Ethereum VM at Load:勾選此項會在重新載入時預設選擇JavaScript VM環境。 (3)Enable Optimization:勾選此項會節省執行GAS,JVM等測試環境可不用勾選。

###3.5.5 分析 分析面板顯示的是最後一次編譯的資訊,預設情況下每一次編譯都會產生一個新的分析。 這個分析面板顯示的是合約程式碼的詳細資訊,它可以幫助你避免程式碼錯誤或者增強編碼能力。28. Analysis頁面.png

Security: Transaction origin: 如果tx.origin被使用則會告警; Check effects: 避免潛在的可重入性BUG; Inline assembly: 使用植入彙編方式; Block timestamp: Semantics maybe unclear; Low level calls: Semantics maybe unclear; Block.blockhash usage: 自毀呼叫; Gas & Economy: Gas costs: 函式的GAS消耗太高會告警。 This on local calls: 勾選後本地函式會被喚醒; Miscellaneous: Constant functions: 檢查潛在的常量函式 Similar variable names: 檢查變數名是否太相似

Miscelllaneous下方顯示的是本次編譯的優化告警,供程式設計師優化程式碼使用。 28. Analysis頁面2.png

###3.5.6 支援 支援頁面,可點選需求技術支援和交流。 remix_supporttab

#4.典型錯誤介紹

4.1 REMIX編譯器官網連結打不開

**提示內容:**點選官網連結(http://remix.ethereum.org),如果打不開或者有錯誤提示“mock compiler: source not found” 原因分析: 這個主要是不能科學上網引起官網瀏覽器不能下載完全。 解決辦法: 1,參考歐陽哥哥的文章《【以太坊開發】Remix IDE本地部署與配置個性風格》完成本地REMIX的部署; 2,採用一個已國內部署的REMIX瀏覽器連結:http://remix2.ju3ban.net

4.2 引數轉換失敗

提示內容: 終端輸出器顯示為“transact to Donation.moveFund errored: Error encoding arguments: Error: Assertion failed ” 原因分析: Solidity函式定義為"function moveFund(address _to, uint _amount)" RUN面板的函式輸入引數如下,希望轉移5個ETH給目標賬號。

“0x14723a09acff6d2a60dcdf7aa4aff308fddc160c”,500000000000000

結果提示錯誤。 這個原因主要是因為”5 *10^18”的值超過了計算器的範圍,需要增加""來讓程式進行轉換。Solidity的預設單位為wei,1 ETH = 1*10^18 wei。 解決辦法: 輸入引數改為2個引數均有雙引號則不會有錯誤提示。

“0x14723a09acff6d2a60dcdf7aa4aff308fddc160c”,“500000000000000”

在remix中,任何輸入引數都可以帶""表示。

4.3 import 匯入依賴編譯失敗

提示內容: 編譯一個智慧合約,有以下依賴匯入程式碼

import "./SafeERC20.sol";
import "../../ownership/Ownable.sol";
import "../../math/SafeMath.sol";

REMIX編譯失敗,提示為“Unable to import “math/SafeMath.sol”: File not found”

原因分析: REMIX支援開啟本地檔案,目前還不支援本地檔案匯入。 解決辦法: 直接從GitHub上匯入檔案。改為如下程式碼即可編譯成功。

import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/ownership/Ownable.sol';

注意哦,import的地址為https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol,而不是瀏覽器能開啟的https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol地址。

尊重知識輸出,如需引用,敬請說明本文連結和作者-筆名輝哥。