一、初始化項目
mkdir helloworld cd helloworld truffle init
新建一個文件夾,使用truffle init進行初始化,有時候會連接不上,多試幾次就好了。
將文件夾使用ftp下載到本地,文件目錄如下:
文件目錄解釋如下:
- contract/ - Truffle默認的合約文件存放地址。
- migrations/ - 存放發布腳本文件
- test/ - 用來測試應用和合約的測試文件
- truffle-config.js - Truffle的配置文件
二、編寫智能合約
2.1.編寫智能合約
在contract下新建合約合約文件Greeter.sol
pragma solidity >=0.4.25 <0.7.0; contract Greeter { address creator; string greeting; constructor(string memory _greeting) public{ creator = msg.sender; greeting = _greeting; } function greet() public view returns(string memory) { return greeting; } function setGreeting(string memory _newgreeting) public{ greeting = _newgreeting; } }
這里有個需要注意的地方:truffle在編譯的時候,會有默認的solidity編譯版本,編寫智能合約的時候最好使用相同的版本。我這里的是0.5.16版本
2.2.新建發布腳本
在./migrations/目錄下新建一個文件:2_deploy_contracts.js,增加發布代碼。
var Greeter = artifacts.require("./Greeter.sol"); module.exports = function(deployer) { deployer.deploy(Greeter,"Hello, World!"); };
2.3.修改配置文件truffle-config.js
module.exports = { networks: { development: { host: "127.0.0.1", // Localhost (default: none) port: 8545, // Standard Ethereum port (default: none) network_id: "*", // Any network (default: none) } }, // Set default mocha options here, use special reporters etc. mocha: { // timeout: 100000 }, // Configure your compilers compilers: { solc: { // version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version) // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) // settings: { // See the solidity docs for advice about optimization and evmVersion // optimizer: { // enabled: false, // runs: 200 // }, // evmVersion: "byzantium" // } } } }
三、部署合約
3.1.啟動ganache-cli
ganache-cli
3.2.編譯合約
truffle compile
3.3.部署合約
truffle migrate
四、測試合約
truffle提供了一種更加簡單的方式,通過交互式控制台來與你的那些准備好的合約進行交互。
truffle console
一個基本的交互控制台,可以連接任何EVM客戶端。如果你已經有了自己的ganache或者geth等EVM的本地環境,那么就可以使用truffle console來交互,所以如果你已經有一個現成的小組共享的開發用EVM,那么使用這個沒錯。
truffle develop
一個交互控制台,啟動時會自動生成一個開發用區塊鏈環境(其實我認為它與ganache就是一個底層實現機制,都是默認生成10個賬戶)。如果你沒有自己的EVM環境的話,直接使用truffle develop非常方便。
進入基本的交互控制台
truffle console
輸入Greeter智能合約命令,顯示打印出一個json結構,展示了它的各種屬性內容。
在truffle5版本之后,使用原文的調用方式會出現異常,新版本調用合約方式如下:
Greeter.deployed().then((instance) => { greeter = instance } ) greeter.greet()
五、Geth環境運行合約
5.1.啟動Geth
這里可以看看之前的文章:https://www.cnblogs.com/fdzang/p/12699377.html
5.2.復制ABI
Geth 中是通過abi來注冊合約對象的。
首先我們找到./build/contracts/Greeter.json中的abi的value:
"abi": [ { "inputs": [ { "internalType": "string", "name": "_greeting", "type": "string" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "constant": true, "inputs": [], "name": "greet", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "internalType": "string", "name": "_newgreeting", "type": "string" } ], "name": "setGreeting", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ];
"abi": [{"inputs": [{"internalType": "string","name": "_greeting","type": "string"}],"payable": false,"stateMutability": "nonpayable","type": "constructor"},{"constant": true,"inputs": [],"name": "greet","outputs": [{"internalType": "string","name": "","type": "string"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": false,"inputs": [{"internalType": "string","name": "_newgreeting","type": "string"}],"name": "setGreeting","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"}];
5.3.重新部署合約到Geth
truffle migrate
這里在部署的時候可能會出現下面這個問題:
這個問題的原因是,部署合約的gas大於了geth開發鏈的gasLimit。
之前在網上找了辦法,有一個是說在啟動鏈的時候加入參數:--targetgaslimit value,這個我試驗之后發現無效。
另一個解決方案是修改 genesis.json中的參數: "gasLimit": value,由於我是啟動的 --dev 模式,暫時未試驗。
試驗有效的解決辦法:
修改 truffle-config.js,添加gas參數,限制部署的時候的gas,
這里的數值可以參考geth中打包的塊的gasLimit大小
再次部署:
部署成功,得到合約地址:0x98940A4b95D0462fC7D8928B24B087e27f8a7E48
5.4.切換Geth控制台
var abi = [{"inputs": [{"internalType": "string","name": "_greeting","type": "string"}],"payable": false,"stateMutability": "nonpayable","type": "constructor"},{"constant": true,"inputs": [],"name": "greet","outputs": [{"internalType": "string","name": "","type": "string"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": false,"inputs": [{"internalType": "string","name": "_newgreeting","type": "string"}],"name": "setGreeting","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"}] var hello = eth.contract(abi).at('0x98940A4b95D0462fC7D8928B24B087e27f8a7E48') hello.greet()
運行成功!
參考:https://www.jianshu.com/p/2e2b3b12eb0e