一、初始化项目
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