以太坊学习路线——(三)Solidity常用IDE搭建、合约编译、部署、调用
這篇博客演示的基本操作系統環境是CentOS 7,參考書籍:以太坊開發實戰——以太坊關鍵技術與案例分析 第七、九章(吳壽鶴、馮翔、劉濤、周廣益?? 著)。
一、常用IDE
1.remix:是一個瀏覽器版的solidity開發 IDE,你可以使用在線版的https://remix.ethereum.org/,Remix使用方法,也可以下載下來 https://github.com/ethereum/remix-ide 安裝到本地。
2.IntelliJ IDEA也提供了solidity的插件如下:(點擊安裝即可)
但是安裝完畢后,是不能直接手動建立solidity項目的,需要建立一個java項目或者其他項目,然后右鍵項目名,在彈出的選項中選擇New,然后點擊New Solidity File選項,會彈出下面的對話框,輸入你的合約文件名,并選擇Smart contract。
此時可以編寫合約文件了,但還不能編譯合約,所以需要先下載solidity的編譯器:solc ,命令行可執行文件名為solcjs。
然后將編譯器連接到IntelliJ idea中,在設置中找到External Tools,可以看到如下圖右側區域,這是我已經創建的外部工具
如果你沒有創建過則為空,點擊“+”添加外部工具:
設置相關參數如下:
- Name:solidity
- Program:/usr/local/node/lib/node_modules/solc/solcjs(注意:這是你安裝的solc可執行文件路徑,注意核實)
- Arguments:--abi --bin $FileName$ -o $OutputPath$(--abi表示生成相關應用二進制接口、--bin表示生成二進制文件、$OutputPath$表示這些生成的文件的存儲路徑)
- Working directory:$FileDir$(代表在當前路徑)
然后編寫你的合約文件,要編譯時,右鍵你的合約文件,選擇External Tools -> solidity就開始編譯你的合約文件了。如下圖,左側為編譯輸出文件目錄,右側為合約代碼,下面是編譯輸出結果。
二、編輯并編譯合約
1.編寫合約
編寫Storage.sol合約文件如下:
pragma solidity >=0.4.21 <0.6.0;contract Storage {uint256 public storedData;function set(uint256 data) public {storedData = data;}function get() public returns (uint256) {return storedData;} }2.命令行編譯合約
由于solcjs的comandline選項與solc不兼容,而工具(如geth)希望solc的行為不適用于solcjs。我直接下載了solc的可執行文件solc-static-linux,然后執行下面的命令:
//把文件所屬改為root,也可以不改,因為我是以root用戶使用 $ chown root solc-static-linux//把文件名改為solc $ mv solc-static-linux solc//把你的solc可執行文件添加到/usr/bin/,就可以在任何目錄運行該程序 $ cp ./solc /usr/bin/ //查看命令行參數說明文檔 $ solc --help//然后就可以開始運行編譯solidity文件了 [root@localhost code]# solc --optimize --abi --bin Storage.sol -o ./out Compiler run successful. Artifact(s) can be found in directory ./out.//編譯成功后可以看到生成的兩個目標文件 out/ ├── Storage.abi └── Storage.bin其中bin文件是合約被編譯后的二進制內容,abi(Application Binary Interface,“應用二進制接口”)文件,可理解為合約接口說明。當合約被編譯后,那么它的abi也就確定了。編譯后的abi文件內容如下:
[{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"data","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"} ]可以看到這個合約abi解析后是一個數組,里面包含了三個對象,后兩個對象對應了合約中的set方法和get方法,而第一個則對應了狀態變量storedData,在solidity實現底層同樣是以方法對待了。其中相關關鍵字解釋如下:
- type:方法類型,包括function、constructor、fallback,默認為function。
- name:方法名。
- inputs:方法參數,它是一個對應數組,數組里的每個對象都是一個參數說明。name(參數名)、type(參數類型)。
- outputs:outputs是一個數組,數組內的參數可以參考上面的inputs,這兩個數組的格式是一樣的。
- constant:布爾值,如果為true指明方法,則不會修改合約的狀態變量。
- payable:布爾值,標明是否可以接收ether。
?三、部署合約
1.啟動以太坊私有鏈geth節點
2.部署
(1).Remix編譯部署
(2).命令行方式部署
打開終端到solidity文件同一路徑下執行:
$ echo "var storageOutput=`solc --optimize --combined-json abi,bin,interface Storage.sol`" > storage.js在geth控制臺加載生成的storage.js:
> loadScript('/opt/idea-IU-191.6183.87/code/storage.js') true > storageOutput {contracts: {Storage.sol:Storage: {abi: "[{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",bin: "608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80632a1afcd914604157806360fe47b11460595780636d4ce63c146075575b600080fd5b6047607b565b60408051918252519081900360200190f35b607360048036036020811015606d57600080fd5b50356081565b005b60476086565b60005481565b600055565b6000549056fea165627a7a723058202ba55d0448970a9d00978257eeaf760416330480cd5868a50d431999319480b30029"}},version: "0.5.7+commit.6da8b019.Linux.g++"在storageOutput對象中存儲了一個map對象,在storageOutput.contracts["Storage.sol:Storage"]中有兩個key,分別定義了合約地ABI和編譯后的二進制代碼。下面分別獲取這兩個對象并分別賦值給兩個變量,將使用ABI、bin來部署和調用智能合約。
???????????????
在正式開始部署之前,需要先解鎖賬戶:
> personal.unlockAccount(eth.accounts[0]) Unlock account 0x8c7ae59ab7e5d510ae3f09a9544978f50315b5f5 Passphrase: true然后開始部署,使用web3.eth.contract的new方法向網絡中發送部署合約的交易,返回一個web3js合約實例地址storageInstance.
> var deployTransationObject = {from: eth.accounts[0], data: storageBinCode, gas: 1000000}; undefined > var storageInstance = storageContract.new(deployTransationObject) undefined //此時網絡中有一個待處理的交易 > txpool.status {pending: 1,queued: 0 }//該交易信息 > txpool.inspect.pending {0x8c7Ae59Ab7E5D510AE3f09A9544978f50315b5F5: {1: "contract creation: 0 wei + 1000000 gas × 1000000000 wei"} }//開啟單線程挖礦、挖到第一個區塊后,停止挖礦 > miner.start(1);admin.sleepBlocks(1);miner.stop(); null//日志文件中的挖礦記錄 INFO [04-05|21:00:07.880] Successfully sealed new block number=29 sealhash=5dd54d…a8e99e hash=a4a582…0a5990 elapsed=650.523ms INFO [04-05|21:00:07.880] ? mined potential block number=29 hash=a4a582…0a5990 INFO [04-05|21:00:07.880] Commit new mining work number=30 sealhash=4bdbbc…714cad uncles=0 txs=0 gas=0 fees=0 elapsed=168.607μs交易被確認后,通過storageInstance對象可以看到部署成功后的合約地址,(命令:> storageInstance)
為"0x6cbab38836ef107315599b7ebbf682515b3e4f64",合約地址是獨一無二的,它是根據發送者的地址和交易的nonce的Hash計算得出的。在后續操作中通過這個合約地址與合約進行交互,部署合約的交易地址也可以看到為:
"0x5fab980e0c0196c6b5c0b6fcb0a6f6f29ee951e7cb8cbcca67bbb87c64a63a01"。
//根據部署合約的交易Hash查看交易詳情 > eth.getTransactionReceipt(storageInstance.transactionHash);//通過eth.getTransactionReceipt方法獲取合約地址: > var storageAddress = eth.getTransactionReceipt(storageInstance.transactionHash).contractAddress undefined > storageAddress "0x6cbab38836ef107315599b7ebbf682515b3e4f64"四、調用合約
通過獲取的合約地址與合約交互:
> var storage = storageContract.at(storageAddress); undefined > storagecall表示直接在本地EVM虛擬機調用合約的get()方法,并且call方式調用合約不會修改區塊鏈中的數據。
> storage.get.call() 0調用合約set()方法,向以太坊中發送一條調用交易:
> storage.set.sendTransaction(42,{from: eth.accounts[0], gas: 1000000}) "0x3f8f8edbdef4e643f1e1313fc0d8caa7d5c114c3af1a1db9a272a557c3dd3cc8" //網絡中有一個待處理的交易: > txpool.status {pending: 1,queued: 0 }//交易詳情 > txpool.inspect.pending {0x8c7Ae59Ab7E5D510AE3f09A9544978f50315b5F5: {2: "0x6cbAb38836eF107315599b7eBBF682515B3E4F64: 0 wei + 1000000 gas × 1000000000 wei"} }//開始挖礦 > miner.start(1);admin.sleepBlocks(1);miner.stop(); null//測試合約執行結果 > storage.get.call()?
總結
以上是生活随笔為你收集整理的以太坊学习路线——(三)Solidity常用IDE搭建、合约编译、部署、调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php经典实例博客管理,PHP经典项目案
- 下一篇: MOS管学习