01. 以太坊-部署智能合约
创建合约
mkdir contracts
vi HelloETH.sol
pragma solidity ^0.8.7;
contract HelloETH {
function rate(uint a, uint b) public pure returns (uint){
return a * b;
}
}
安装 solc
前提安装 npm
apt-get install npm
npm install -g solc --registry=https://registry.npm.taobao.org
solcjs --version
0.8.7+commit.e28d00a7.Emscripten.clang
编译
solcjs --bin HelloETH.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.
cat HelloETH_sol_HelloETH.bin
code =
"608060405234801561001057600080fd5b506101da806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806343bebfbf14610030575b600080fd5b61004a6004803603810190610045919061008b565b610060565b60405161005791906100da565b60405180910390f35b6000818361006e91906100f5565b905092915050565b6000813590506100858161018d565b92915050565b600080604083850312156100a2576100a1610188565b5b60006100b085828601610076565b92505060206100c185828601610076565b9150509250929050565b6100d48161014f565b82525050565b60006020820190506100ef60008301846100cb565b92915050565b60006101008261014f565b915061010b8361014f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561014457610143610159565b5b828202905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b6101968161014f565b81146101a157600080fd5b5056fea2646970667358221220804031a2b65d03aa5e427000bcac278d3f8ff0e685b9703fcd7efc034fde062564736f6c63430008070033"
solcjs --abi HelloETH.sol
cat HelloETH_sol_HelloETH.abi
[{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]
记录
回到 Geth 控制台,使用 code
# 进入控制台
geth --nousb --identity "CreationNode" --rpc --rpcport "8548" --rpcapi eth,web3,persional --allow-insecure-unlock --datadir /root/appeth/data0 --port "30304" --nodiscover console
# 记录 code
code="0x608060405234801561001057600080fd5b506101da806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806343bebfbf14610030575b600080fd5b61004a6004803603810190610045919061008b565b610060565b60405161005791906100da565b60405180910390f35b6000818361006e91906100f5565b905092915050565b6000813590506100858161018d565b92915050565b600080604083850312156100a2576100a1610188565b5b60006100b085828601610076565b92505060206100c185828601610076565b9150509250929050565b6100d48161014f565b82525050565b60006020820190506100ef60008301846100cb565b92915050565b60006101008261014f565b915061010b8361014f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561014457610143610159565b5b828202905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b6101968161014f565b81146101a157600080fd5b5056fea2646970667358221220804031a2b65d03aa5e427000bcac278d3f8ff0e685b9703fcd7efc034fde062564736f6c63430008070033"
# 记录 abi
abi=[{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]
进入控制台
docker exec -it ethereum-node /bin/sh
geth --nousb --identity "CreationNode" --rpc --rpcport "8548" --rpcapi eth,web3,persional --allow-insecure-unlock --datadir /root/appeth/data0 --port "30304" --nodiscover console
部署智能合约
解锁账户
personal.unlockAccount(eth.accounts[0])
定义
code & abi
code="0x608060405234801561001057600080fd5b506101da806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806343bebfbf14610030575b600080fd5b61004a6004803603810190610045919061008b565b610060565b60405161005791906100da565b60405180910390f35b6000818361006e91906100f5565b905092915050565b6000813590506100858161018d565b92915050565b600080604083850312156100a2576100a1610188565b5b60006100b085828601610076565b92505060206100c185828601610076565b9150509250929050565b6100d48161014f565b82525050565b60006020820190506100ef60008301846100cb565b92915050565b60006101008261014f565b915061010b8361014f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561014457610143610159565b5b828202905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b6101968161014f565b81146101a157600080fd5b5056fea2646970667358221220804031a2b65d03aa5e427000bcac278d3f8ff0e685b9703fcd7efc034fde062564736f6c63430008070033"
abi=[{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]
定义合约
myContract = eth.contract(abi)
发布合约
> contract = myContract.new({from:eth.accounts[0], data:code, gas:1000000})
WARN [08-28|21:23:04.517] Served eth_sendTransaction reqid=82 t="52.563µs" err="invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field TransactionArgs.data of type hexutil.Bytes"
Error: invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field TransactionArgs.data of type hexutil.Bytes
at web3.js:6357:37(47)
at web3.js:5091:62(37)
at web3.js:3021:48(134)
at <eval>:1:26(14)
解决:code 需要之前加 0x
code="0x6080..."
正确发布后
> contract = myContract.new({from:eth.accounts[0], data:code, gas:1000000})
INFO [08-28|23:05:24.339] Setting new local account address=0xB68Edb8cC590706199c1ef498D53a235E985c2ee
INFO [08-28|23:05:24.340] Submitted contract creation hash=0x7d1d25b5948e0b47218cc62cc60c0f7b2f71f40755f7ee5f4717982c6fb91434 from=0xB68Edb8cC590706199c1ef498D53a235E985c2ee nonce=1 contract=0x18F6bA6c61d51502535E8cC53623Fa086B11902e value=0
{
abi: [{
inputs: [{...}, {...}],
name: "rate",
outputs: [{...}],
stateMutability: "pure",
type: "function"
}],
address: undefined,
transactionHash: "0x7d1d25b5948e0b47218cc62cc60c0f7b2f71f40755f7ee5f4717982c6fb91434"
}
# 待确认交易
> txpool.status
{
pending: 1,
queued: 0
}
开始挖矿
miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [08-28|23:07:16.069] Updated mining threads threads=1
INFO [08-28|23:07:16.069] Transaction pool price threshold updated price=1,000,000,000
INFO [08-28|23:07:16.070] Commit new mining work number=6 sealhash=7ed01e..2153ed uncles=0 txs=0 gas=0 fees=0 elapsed="604.074µs"
INFO [08-28|23:07:16.071] Commit new mining work number=6 sealhash=bbd0de..4079a7 uncles=0 txs=1 gas=155,161 fees=0.000155161 elapsed=1.647ms
INFO [08-28|23:07:22.857] Generating DAG in progress epoch=1 percentage=0 elapsed=5.864s
INFO [08-28|23:07:28.655] Generating DAG in progress epoch=1 percentage=1 elapsed=11.662s
INFO [08-28|23:07:33.681] Generating DAG in progress epoch=1 percentage=2 elapsed=16.689s
INFO [08-28|23:07:38.191] Generating DAG in progress epoch=1 percentage=3 elapsed=21.198s
INFO [08-28|23:07:39.098] Successfully sealed new block number=6 sealhash=bbd0de..4079a7 hash=a60d75..b15966 elapsed=23.027s
INFO [08-28|23:07:39.098] 🔨 mined potential block number=6 hash=a60d75..b15966
INFO [08-28|23:07:39.099] Commit new mining work number=7 sealhash=97be12..a879ee uncles=0 txs=0 gas=0 fees=0 elapsed="531.984µs"
INFO [08-28|23:07:39.100] Commit new mining work number=7 sealhash=97be12..a879ee uncles=0 txs=0 gas=0 fees=0 elapsed=1.765ms
null
>
# 已确认交易
> txpool.status
{
pending: 0,
queued: 0
}
# 查看智能合约
> contract.
contract._eth contract.address contract.constructor contract.transactionHash
contract.abi contract.allEvents
# 先前定义的函数
contract.rate
# 设置消费用户,测试
> web3.eth.defaultAccount = eth.accounts[0]
> contract.rate(2,3)
INFO [08-28|23:11:16.410] Submitted transaction hash=0x2cc56fbb7e39f1807be911ac17dccc573c07387d4d3546f3dd207f3abc6b9996 from=0xB68Edb8cC590706199c1ef498D53a235E985c2ee nonce=2 recipient=0x18F6bA6c61d51502535E8cC53623Fa086B11902e value=0
"0x2cc56fbb7e39f1807be911ac17dccc573c07387d4d3546f3dd207f3abc6b9996"
> contract.rate.sendTransaction(10,10,{from:eth.accounts[0]})
INFO [08-28|23:15:14.650] Submitted transaction hash=0x86d5e306e596fdb1ec89b0ceea68b5f9f425aba0e808da9c36bc481067078cfe from=0xB68Edb8cC590706199c1ef498D53a235E985c2ee nonce=3 recipient=0x18F6bA6c61d51502535E8cC53623Fa086B11902e value=0
"0x86d5e306e596fdb1ec89b0ceea68b5f9f425aba0e808da9c36bc481067078cfe"
# 待确认
> txpool.status
{
pending: 2,
queued: 0
}
# 余额
> eth.getBalance(eth.accounts[0])
7000000000000000000
> eth.getBalance(eth.accounts[1])
5000000000000000000
# 挖矿,确认交易
> miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [08-28|23:18:49.284] Updated mining threads threads=1
INFO [08-28|23:18:49.284] Transaction pool price threshold updated price=1,000,000,000
INFO [08-28|23:18:49.290] Commit new mining work number=7 sealhash=9cde5b..ce69df uncles=0 txs=0 gas=0 fees=0 elapsed=1.367ms
INFO [08-28|23:18:49.299] Commit new mining work number=7 sealhash=eea527..655a02 uncles=0 txs=2 gas=44614 fees=4.4614e-05 elapsed=10.363ms
INFO [08-28|23:18:56.452] Successfully sealed new block number=7 sealhash=eea527..655a02 hash=c7fed1..afca80 elapsed=7.152s
INFO [08-28|23:18:56.452] 🔨 mined potential block number=7 hash=c7fed1..afca80
INFO [08-28|23:18:56.453] Commit new mining work number=8 sealhash=8b750c..612c28 uncles=0 txs=0 gas=0 fees=0 elapsed="495.592µs"
null
> txpool.status
{
pending: 0,
queued: 0
}
> eth.getBalance(eth.accounts[0])
9000000000000000000
> eth.getBalance(eth.accounts[1])
5000000000000000000
使用账户 B 来消费
# 先解锁
> personal.unlockAccount(eth.accounts[1])
Unlock account 0xc2b037baad241b6b5fa0cf6a87f47cce7152bd1d
Passphrase:
true
# 消费 [账户A] 的服务
> contract.rate.sendTransaction(10,10,{from:eth.accounts[1]})
INFO [08-28|23:21:14.989] Setting new local account address=0xc2B037BaaD241B6B5fa0cF6a87f47cce7152bd1d
INFO [08-28|23:21:14.993] Submitted transaction hash=0xa49f3d96cd028955eae2800944f198150a656505c6cffd4bd711ee2227c8a33b from=0xc2B037BaaD241B6B5fa0cF6a87f47cce7152bd1d nonce=0 recipient=0x18F6bA6c61d51502535E8cC53623Fa086B11902e value=0
"0xa49f3d96cd028955eae2800944f198150a656505c6cffd4bd711ee2227c8a33b"
# 待确认交易
> txpool.status
{
pending: 1,
queued: 0
}
> eth.getBalance(eth.accounts[0])
9000000000000000000
> eth.getBalance(eth.accounts[1])
5000000000000000000
创建账户 C 来挖矿
> personal.newAccount();
Passphrase:
Repeat passphrase:
INFO [08-28|23:23:17.549] Your new key was generated address=0x35b522e7cD2f35eD214fbB2fe7553B7B4aBD4e32
WARN [08-28|23:23:17.549] Please backup your key file! path=/root/appeth/data0/keystore/UTC--2021-08-28T23-23-13.545692748Z--35b522e7cd2f35ed214fbb2fe7553b7b4abd4e32
WARN [08-28|23:23:17.549] Please remember your password!
"0x35b522e7cd2f35ed214fbb2fe7553b7b4abd4e32"
> eth.getBalance(eth.accounts[2])
0
# 设置挖矿者
web3.eth.defaultAccount = eth.accounts[2]
"0x35b522e7cd2f35ed214fbb2fe7553b7b4abd4e32"
# 开始挖矿
> miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [08-28|23:25:15.642] Updated mining threads threads=1
INFO [08-28|23:25:15.649] Transaction pool price threshold updated price=1,000,000,000
INFO [08-28|23:25:15.652] Commit new mining work number=8 sealhash=813631..58bdee uncles=0 txs=0 gas=0 fees=0 elapsed="373.939µs"
INFO [08-28|23:25:15.656] Commit new mining work number=8 sealhash=c0660e..8bd3e9 uncles=0 txs=1 gas=22307 fees=2.2307e-05 elapsed=4.161ms
INFO [08-28|23:25:36.400] Successfully sealed new block number=8 sealhash=c0660e..8bd3e9 hash=8596ab..9a968e elapsed=20.743s
INFO [08-28|23:25:36.400] 🔨 mined potential block number=8 hash=8596ab..9a968e
INFO [08-28|23:25:36.401] Commit new mining work number=9 sealhash=01cb07..2f7eb7 uncles=0 txs=0 gas=0 fees=0 elapsed="295.1µs"
null
> txpool.status
{
pending: 0,
queued: 0
}
> eth.getBalance(eth.accounts[2])
0
====由此可知,web3.eth.defaultAccount = eth.accounts[2] 并不不是 C 来确认交易,设置失败====
> eth.getBalance(eth.accounts[0])
11000022307000000000
> eth.getBalance(eth.accounts[1])
4999977693000000000
# 单位换算
> web3.fromWei(11000022307000000000)
"11.000022307"
> web3.fromWei(4999977693000000000)
"4.999977693"