1. 下载
$ git clone https://github.com/ethereum/go-ethereum.git
2. 编译
$ cd go-ethereum
$ make geth
把./build/bin/geth
添加到可执行路径中
3. 配置初始状态
保存配置到genesis.json
文件
{
"config": {
"chainId": 7777,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"ethash": {}
},
"difficulty": "1",
"gasLimit": "8000000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" },
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" }
}
}
执行geth init --datadir data genesis.json
,初始化以太坊配置。
4. 运行以太坊节点
执行geth --datadir data --nodiscover --mine console
,节点启动。
5. 创建账户
在以太坊console执行如下命令
> personal.newAccount()
Passphrase:
Repeat passphrase:
INFO [03-15|17:46:52.995] Your new key was generated address=0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf
WARN [03-15|17:46:52.996] Please backup your key file! path=/Users/xuqizhong/tmp/eth/data/keystore/UTC--2022-03-15T09-46-51.983819000Z--45281eb7bbaa41fef62d40ae881378c14335c1cf
WARN [03-15|17:46:52.996] Please remember your password!
"0x45281eb7bbaa41fef62d40ae881378c14335c1cf"
执行如下命令,可以查询有哪些账户
> personal.listAccounts
["0x45281eb7bbaa41fef62d40ae881378c14335c1cf", "0x96b638097bb4dd40d9bca6f1197b8d24b1705cfa"]
6. 挖矿
执行挖矿命令
> miner.start()
暂停挖矿命令
> miner.stop()
查询钱包余额
> web3.fromWei(eth.getBalance("0x45281eb7bbaa41fef62d40ae881378c14335c1cf"),"ether")
196
7. 发送交易
首先需要解锁账户0
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x45281eb7bbaa41fef62d40ae881378c14335c1cf
Passphrase:
true
发起交易
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(10,'ether')})
INFO [03-15|18:29:11.590] Setting new local account address=0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf
INFO [03-15|18:29:11.591] Submitted transaction hash=0xef11db5b652c6402a2569843c7b364cda8628e84f86efe51d5b5b674cf6caa23 from=0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf nonce=0 recipient=0x96b638097Bb4dD40d9bca6f1197b8d24B1705cfa value=10,000,000,000,000,000,000
"0xef11db5b652c6402a2569843c7b364cda8628e84f86efe51d5b5b674cf6caa23"
查询账户1的余额
> web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')
10
8. 编写智能合约
实现一个简单的智能合约demo.sol
pragma solidity >=0.7.0 <0.9.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}
编译智能合约
> solc --optimize --combined-json abi,bin demo.sol
solc --optimize --combined-json abi,bin demo.sol
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> demo.sol
{"contracts":{"demo.sol:SimpleStorage":{"abi":[{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bin":"6080604052348015600f57600080fd5b5060ac8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146049575b600080fd5b60476042366004605e565b600055565b005b60005460405190815260200160405180910390f35b600060208284031215606f57600080fd5b503591905056fea264697066735822122026c14d5b811591c48b9fef3864b4577cbbc2ebd0e5ebc07b7d54847f206eb69564736f6c634300080c0033"}},"version":"0.8.12+commit.f00d7308.Darwin.appleclang"}
9. 部署智能合约
解锁账户
> personal.unlockAccount("0x45281eb7bbaa41fef62d40ae881378c14335c1cf")
Unlock account 0x45281eb7bbaa41fef62d40ae881378c14335c1cf
Passphrase:
true
通过web3.eth.contract的new方法发起部署合约的交易
> var storageContractJson = {"contracts":{"demo.sol:SimpleStorage":{"abi":[{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bin":"6080604052348015600f57600080fd5b5060ac8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146049575b600080fd5b60476042366004605e565b600055565b005b60005460405190815260200160405180910390f35b600060208284031215606f57600080fd5b503591905056fea264697066735822122026c14d5b811591c48b9fef3864b4577cbbc2ebd0e5ebc07b7d54847f206eb69564736f6c634300080c0033"}},"version":"0.8.12+commit.f00d7308.Darwin.appleclang"}
undefined
> var storageContract = eth.contract(storageContractJson.contracts["demo.sol:SimpleStorage"].abi)
undefined
> var storageContractObj = {from:eth.accounts[0],data:"0x"+storageContractJson.contracts["demo.sol:SimpleStorage"].bin,gas:1000000}
undefined
> > var storageContractIns = storageContract.new(storageContractObj)
INFO [03-16|11:37:55.925] Setting new local account address=0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf
INFO [03-16|11:37:55.926] Submitted contract creation hash=0xa8c86633956bea5f8532734bd76a3125ee2f81c0ddf5308762651c94c99cd957 from=0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf nonce=1 contract=0xf00a6AAA995c8adcC7b0A6d2A044827c58b6cdb3 value=0
undefined
查看交易池状态
> txpool.status
{
pending: 1,
queued: 0
}
> txpool.inspect.pending
{
0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf: {
1: "contract creation: 0 wei + 1000000 gas × 1000000000 wei"
}
}
可以看到有一个交易待处理,开始挖矿
> miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [03-16|11:40:45.910] Updated mining threads threads=1
INFO [03-16|11:40:49.606] Successfully sealed new block number=104 sealhash=b80b30..539c7f hash=8fe8f6..e601c7 elapsed=2m50.695s
INFO [03-16|11:40:49.606] 🔨 mined potential block number=104 hash=8fe8f6..e601c7
INFO [03-16|11:40:49.607] Commit new sealing work number=105 sealhash=d85721..564878 uncles=0 txs=0 gas=0 fees=0 elapsed="126.458µs"
INFO [03-16|11:40:49.607] Commit new sealing work number=105 sealhash=d85721..564878 uncles=0 txs=0 gas=0 fees=0 elapsed="245.25µs"
null
> txpool.status
{
pending: 0,
queued: 0
}
查看合约地址
> storageContractIns
{
abi: [{
inputs: [],
name: "get",
outputs: [{...}],
stateMutability: "view",
type: "function"
}, {
inputs: [{...}],
name: "set",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}],
address: "0xf00a6aaa995c8adcc7b0a6d2a044827c58b6cdb3",
transactionHash: "0xa8c86633956bea5f8532734bd76a3125ee2f81c0ddf5308762651c94c99cd957",
allEvents: function bound(),
get: function bound(),
set: function bound()
}
查看部署合约交易详情
> eth.getTransactionReceipt(storageContractIns.transactionHash)
{
blockHash: "0x8fe8f6dc26b38c87287de5fab28b1b3983dd7b2b47ebb59eb69f60c8b4e601c7",
blockNumber: 104,
contractAddress: "0xf00a6aaa995c8adcc7b0a6d2a044827c58b6cdb3",
cumulativeGasUsed: 100327,
effectiveGasPrice: 1000000000,
from: "0x45281eb7bbaa41fef62d40ae881378c14335c1cf",
gasUsed: 100327,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
status: "0x1",
to: null,
transactionHash: "0xa8c86633956bea5f8532734bd76a3125ee2f81c0ddf5308762651c94c99cd957",
transactionIndex: 0,
type: "0x0"
}
获取合约地址
> var storageContractInsAddress = eth.getTransactionReceipt(storageContractIns.transactionHash).contractAddress
undefined
> storageContractInsAddress
"0xf00a6aaa995c8adcc7b0a6d2a044827c58b6cdb3"
获取合约实例
> var storageContractIns = storageContract.at(storageContractInsAddress)
undefined
> storageContractIns
{
abi: [{
inputs: [],
name: "get",
outputs: [{...}],
stateMutability: "view",
type: "function"
}, {
inputs: [{...}],
name: "set",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}],
address: "0xf00a6aaa995c8adcc7b0a6d2a044827c58b6cdb3",
transactionHash: null,
allEvents: function bound(),
get: function bound(),
set: function bound()
}
调用合约get方法
> storageContractIns.get.call()
0
调用合约set方法
> storageContractIns.set.sendTransaction(77,{from:eth.accounts[0],gas:1000000})
INFO [03-16|11:51:41.077] Submitted transaction hash=0xf431e2d1e2dbf042dca26570d213415c2ccf72a0272a89c028db7a802b38a9f0 from=0x45281eb7BBaA41FeF62D40aE881378c14335C1Cf nonce=2 recipient=0xf00a6AAA995c8adcC7b0A6d2A044827c58b6cdb3 value=0
"0xf431e2d1e2dbf042dca26570d213415c2ccf72a0272a89c028db7a802b38a9f0"
> txpool.status
{
pending: 1,
queued: 0
}
> miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [03-16|11:52:18.540] Updated mining threads threads=1
INFO [03-16|11:52:18.540] Transaction pool price threshold updated price=1,000,000,000
INFO [03-16|11:52:18.540] Commit new sealing work number=105 sealhash=67a38b..47fa30 uncles=0 txs=0 gas=0 fees=0 elapsed="265.708µs"
INFO [03-16|11:52:18.541] Commit new sealing work number=105 sealhash=e82e4a..e120c7 uncles=0 txs=1 gas=41654 fees=4.1654e-05 elapsed="688.625µs"
INFO [03-16|11:52:20.048] Successfully sealed new block number=105 sealhash=e82e4a..e120c7 hash=5300e6..eced57 elapsed=1.507s
INFO [03-16|11:52:20.048] 🔨 mined potential block number=105 hash=5300e6..eced57
INFO [03-16|11:52:20.048] Commit new sealing work number=106 sealhash=cf5725..46077d uncles=0 txs=0 gas=0 fees=0 elapsed="76.375µs"
INFO [03-16|11:52:20.048] Commit new sealing work number=106 sealhash=cf5725..46077d uncles=0 txs=0 gas=0 fees=0 elapsed="126.084µs"
null
> txpool.status
{
pending: 0,
queued: 0
}
获取存储结果
> storageContractIns.get.call()
77