主要参考文档
https://www.jianshu.com/p/e978535b1002
默认操作目录为 /opt/module
准备步骤
- 虚拟机安装Ubuntu(省略. 建议分配2G以上内存, 以下以Ubuntu 14.04.6 LTS 为例)
更换更新源(省略, 可选, 加速安装过程)
设置静态IP, 安装sshd
sudo apt-get update
sudo apt-get install openssh-server
- 安装nodejs, npm
参考nodejs官网 https://nodejs.org/en/download/
配置环境变量
ubuntu@ubuntu:~$ node -v
v8.16.0
ubuntu@ubuntu:~$ npm -v
6.4.1
- 安装go-ethererum
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum - 创建私有链genesis.json
创建Ethererum目录
mdkir Ethererum
cd Ethererum
vim genesis.json
{
"nonce":"0x0000000000000042",
"mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x4000",
"alloc": {},
"coinbase":"0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"config":{
"chainId":15,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0
},
"gasLimit":"0xffffffff"
}
- 初始化
geth --datadir /opt/module/Ethererum/ init genesis.json
geth --datadir /opt/module/Ethererum/ --identity "YXEtherum" --rpc --rpcport "8545" --rpccorsdomain "*" --port 30303 --rpcapi db,eth,net,web3,miner,personal --networkid 10 --nodiscover console
- 挖矿
INFO [01-27|11:48:34] IPC endpoint opened: ~/Ethererum/yx_data/geth.ipc
INFO [01-27|11:48:34] HTTP endpoint opened: http://127.0.0.1:8545
Welcome to the Geth JavaScript console!
instance: Geth/YXEtherum/v1.7.3-stable/darwin-amd64/go1.9.3
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
> INFO [01-27|11:48:37] Mapped network port proto=tcp extport=30303 intport=30303 interface="UPNP IGDv1-IP1"
> eth.accounts // 查看当前账户
[]
> personal.newAccount() // 创建新账户
Passphrase: // 输入密码
Repeat passphrase: // 确认密码
"0x77a4ee7daca8faecec59c52786dcac639dd6ab91"
> eth.accounts
["0x77a4ee7daca8faecec59c52786dcac639dd6ab91"] // 账户已创建
> eth.getBalance(eth.accounts[0]) // 查看余额
0
> miner.start() // 开始挖矿
INFO [01-27|11:53:37] Updated mining threads threads=0
INFO [01-27|11:53:37] Transaction pool price threshold updated price=18000000000
INFO [01-27|11:53:39] Generating DAG in progress epoch=0 percentage=0 elapsed=1.691s
INFO [01-27|11:53:41] Generating DAG in progress epoch=0 percentage=1 elapsed=3.465s
INFO [01-27|11:53:43] Generating DAG in progress epoch=0 percentage=2 elapsed=5.187s
...
...
INFO [01-27|12:00:55] mined potential block number=3 hash=856ca2…60597c
INFO [01-27|12:00:55] Commit new mining work number=4 txs=0 uncles=0 elapsed=209.521µs
> miner.stop() // 挖出矿的时候,就可以停止了
true
> eth.getBalance(eth.accounts[0])
15000000000000000000
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether");
15 // 账号已经有15个以太了,有以太我们就可以做交易了。
> exit 退出
部署合约
- 搭建环境, 安装ganache-cli
alias cnpm="npm --registry=http://registry.npm.taobao.org \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=http://dist.cnpmjs.org \
--userconfig=$HOME/.cnpmrc" # 使用淘宝镜像加快安装速度
cnpm install -g ganache-cli
2.运行ganache-cli
>ganache-cli
Ganache CLI v6.0.3 (ganache-core: 2.0.2)
Available Accounts
==================
(0) 0x54a2d27c4b30139b538bf887982aae64cfa3c7a3
(1) 0x2d221a7ca36bcbb30ccd574104812539721ceed8
...
Private Keys
==================
(0) 930186bf51b9d503e82cc6e9a1f8adaea58b249278fcf4ca42d7635b3195057f
(1) e769615ea9103ec9f13a7bfe2f0e56b3337e0123298c78404d18c721abde3025
...
HD Wallet
==================
Mnemonic: bar quit tobacco ring process twice kangaroo eye verify badge lazy phrase
Base HD Path: m/44'/60'/0'/0/{account_index}
Listening on localhost:8545 // 注意这里的地址和端口号,默认8545,和 geth 一样,如果 geth 开启着,要关闭 geth,或者启用不同的端口号。
- 安装truffle(以下面为准, 不要参考开头的文档, 会出现版本问题)
tree工具也是要单独安装, 没有也不影响
>cnpm install -g [email protected]
//如果出现错误, 可以直接clone他给出的github地址
>mkdir solidity-experiments
>cd solidity-experiments/
>truffle init
>tree
.
├── contracts
│ └── Migrations.sol
├── migrations
│ └── 1_initial_migration.js
├── test
├── truffle-config.js
合约编译, 合并过程会以truffle-config.js为准, 修改该文件指定处:
- 编译发布
>truffle compile # 编译合约
>truffle migrate # 确保 ganache-cli 已开启
Using network 'development'.
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0x2a658b01d6...7ff
Migrations: 0x38f1873ed43e7c6ce8a4eb78116c2bd186f6d3b0
Saving successful migration to network... # migration 发布成功
... 0x6451ee5b....be4
发布成功,然后我们就可以开始编写 solidity 合约,这里以 greeter demo 为例,运行
truffle create contract Greeter
- 编写合约
pragma solidity ^0.4.24; // 指定 solidity 版本
contract Greeter // The contract definition. A constructor of the same name will be automatically called on contract creation.
{
address creator; // At first, an empty "address"-type variable of the name "creator". Will be set in the constructor.
string greeting; // At first, an empty "string"-type variable of the name "greeting". Will be set in constructor and can be changed.
// 构造函数
function Greeter(string _greeting) public
{
creator = msg.sender;
greeting = _greeting;
}
// 只读函数
function greet() constant public returns (string)
{
return greeting;
}
function getBlockNumber() constant public returns (uint) // this doesn't have anything to do with the act of greeting
{ // just demonstrating return of some global variable
return block.number;
}
// 非只读函数
function setGreeting(string _newgreeting) public
{
greeting = _newgreeting;
}
// 自毁函数
function kill() public
{
if (msg.sender == creator) // only allow this action if the account sending the signal is the creator
selfdestruct(creator); // kills this contract and sends remaining funds back to creator
}
}
保存之后,编辑文件 migrations/2_deploy_contracts.js,如果没有则新建一个,文件内容如下:
var Greeter = artifacts.require("./Greeter.sol");
module.exports = function(deployer) {
deployer.deploy(Greeter,"Hello World");
};
然后重新编译、部署:
>truffle compile # 编译
Compiling ./contracts/Greeter.sol...
Compiling ./contracts/greeter.sol...
Writing artifacts to ./build/contracts // 编译后的 json 文件存放在此目录下。
>truffle migrate --reset # 发布
Compiling ./contracts/Greeter.sol...
Writing artifacts to ./build/contracts
Using network 'development'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0x9eca7628a5a47....c4e
Migrations: 0xfae368dec758a241f610333cdbd2944009fe23be
Saving successful migration to network...
... 0x74406ca1....ce5
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing Greeter...
... 0x081c7a46529....3dd
Greeter: 0xb0d9df51125b0b7d58ec06f1af9e957dff7314ac # Greeter 合约地址
Saving successful migration to network...
... 0x2e2396da9....764
Saving artifacts...
Greeter 合约部署完成,Greeter 的地址为 0xb0d9df51125b0b7d58ec06f1af9e957dff7314ac,可通过这个地址和合约进行交互,运行 truffle console
:
>truffle console
truffle(development)> var greeter = Greeter.at(Greeter.address)
undefined
truffle(development)> greeter.address
'0x52e4b9ecd911843e5c2550df6458374480e5483d'
truffle(development)> greeter.greet()
'Hello World!'
truffle(development)> greeter.setGreeting('Hello World!!!')
{ tx: '0xa6e0c1f376c005647d1e522740085979d710fceb3bb73883e8452c79274826d7',
receipt:
{ transactionHash: '0xa6e0c1f376c005647d1e522740085979d710fceb3bb73883e8452c79274826d7',
transactionIndex: 0,
blockHash: '0x9c0ccff9d47c894ef79fb13a507d37bbdd5f49d8ef7858c8b6dc20f34c7ed166',
blockNumber: 9,
from: '0x091127ffb8ecb383b80caca87f17dbfba7fed05c',
to: '0x52e4b9ecd911843e5c2550df6458374480e5483d',
gasUsed: 33688,
cumulativeGasUsed: 33688,
contractAddress: null,
logs: [],
status: '0x1',
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
v: '0x1b',
r: '0xa4c72524e7d107e6a04cd6f55c4988f1d1a191cc1d05c0f72c43eb035fa0efb0',
s: '0x25151b7fbfc30636ee1c96f45d7b288efdecb8fa3ccf318d2c3f377b7919836d' },
logs: [] }
truffle(development)> greeter.greet()
'Hello World!!!'
- 发布合约到私有链
退出ganache-cli
,运行
geth --datadir /opt/module/Ethererum/ --identity "YXEtherum" --rpc --rpcport "8545" --rpccorsdomain "*" --port 30303 --rpcapi "db,eth,net,web3" --networkid 10 --nodiscover --ethash.dagdir /opt/module/Ethererum/Ethash console
// 解锁账号
> personal.unlockAccount(eth.accounts[0], "yourpassword", 24*3600)
true
// 必须开启挖矿,否则合约无法提交、保存到区块链中。因为我们创建的私链中并没有其他节点处理交易。
> miner.start()
然后在另一个窗口中运行 truffle migrate --reset
,看到以下类似信息说明合约已成功部署。(要等到挖到矿以后才能部署, 耐心等待 :-D )
Running migration: 2_deploy_contracts.js
Deploying Greeter...
... 0xcafdaaf58....f70
Greeter: 0x53410cc....69e # 合约地址
Saving successful migration to network...
... 0x63026be34589....eea
如何在私有链中查看合约? 拷贝 truffle compile
编译后的 build/contracts/Greeter.json
文件中的 abi 串,
可以去https://www.json.cn/# 将json串压缩一下
然后在 geth console 窗口中,执行以下命令
> var abi = JSON.parse('[{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBlockNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newgreeting","type":"string"}],"name":"setGreeting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]')
undefined
> var greeter = eth.contract(abi).at('0xb0d9df51125b0b7d58ec06f1af9e957dff7314ac')//这里的0xb0d9df51125b0b7d58ec06f1af9e957dff7314ac是合约发布的地址
undefined
> greeter.greet()
"Hello World!"
运行截图:
其他参考文档
- go-ethererum Installation Instructions for Ubuntu
https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Ubuntu - 在线合约IDE: remix
http://remix.ethereum.org/#optimize=true&version=soljson-v0.4.24+commit.e67f0147.js - 以太坊智能合约 Hello World 示例程序
https://blog.csdn.net/CSDN_AF/article/details/77963841 - 以太坊 Truffle 框架如何修改 solidity 版本
https://yq.aliyun.com/articles/703235 - Truffle Smart Contract Error: Invalid number of parameter
https://stackoverflow.com/questions/54304214/truffle-smart-contract-error-invalid-number-of-parameter - 以太坊智能合约 Solidity 的 0.5版本介绍
https://blog.csdn.net/u012310362/article/details/83058198 - Full Stack Hello World Voting Ethereum Dapp Tutorial — Part 1
https://medium.com/@mvmurthy/full-stack-hello-world-voting-ethereum-dapp-tutorial-part-1-40d2d0d807c2