https://solidity-by-example.org 中的第二个练习, 并添加了注释
习题
https://solidity-by-example.org/first-app/
注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Ex002FirstApplication {
//1.
// external - 外部函数是用来被其他合约调用的。它们不能用于内部调用。要在合约中调用外部函数,需要调用this.function_name()。状态变量不能被标记为外部变量。
// public - 公共函数/变量可以在外部和内部使用。对于公共状态变量,Solidity自动创建一个getter函数。
// internal - 内部函数/变量只能由内部或派生合约使用。
// private - 私有函数/变量只能在内部使用,甚至不能被派生合约使用。
//这个例子中有了get()函数, 可能count设置为private 或 internal 更恰当
//类型 参考这里 https://docs.soliditylang.org/en/v0.8.14/types.html
// 或 https://solidity-cn.readthedocs.io/zh/develop/types.html
uint public count;
//2.
// solidity 中函数可以用作变量赋值,参数传递等
// 函数分为内部/外部函数, 也就是external和internal, 默认是internal可以不写
// pure 不读数据, 也不写数据 不改变虚拟机状态
// view 读数据, 但不写数据 不改变虚拟机状态
// payable 支付, 写数据 改变虚拟机状态
// 参考这里 https://yinhui1984.github.io/对智能合约的读方法和写方法的调用/
function get() public view returns (uint){
return count;
}
//3.
//与参数类型相比,返回类型不能为空——如果函数类型不应该返回任何内容,则整个返回 (<return types> ) 部分必须省略。
//没有明确指明 pure view payable 则默认要改变虚拟机状态
function inc() public {
count += 1;
}
function dec() public {
count -= 1;
}
}
|
合约调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
import Web3 from "web3"
import net from "net"
import * as fs from "fs"
const web3 = new Web3(new Web3.providers.IpcProvider("../mychain/data/geth.ipc", net))
const contractName = "Ex002FirstApplication"
const abi = JSON.parse(fs.readFileSync("../contracts/build/"+contractName+".abi").toString())
const address = fs.readFileSync("../contracts/"+contractName+".address").toString()
const contract = new web3.eth.Contract(abi,address)
async function test(){
let accounts = await web3.eth.getAccounts()
let account = accounts[0]
await contract.methods.get().call().then(x => console.log("current value:" + x))
//对inc调用call(), 并不会生效
await contract.methods.inc().call().then(()=>{
contract.methods.get().call().then(x => console.log("after call inc(), current value:" + x))
})
//对于改变状态机的函数, 要调用send()
await contract.methods.inc().send({from:account, gas:3000000}).then(()=>{
contract.methods.get().call().then(x => console.log("after send inc(), current value:" + x))
})
//如果值为0,再调用inc()会报错
await contract.methods.dec().send({from:account, gas:3000000}).then(()=>{
contract.methods.get().call().then(x => console.log("after send dec(), current value:" + x))
}).catch(e => console.log("\n\ncatch an error : \n "+e))
return new Promise((resolve) => {
setTimeout(()=>{
resolve()
} , 5000)
})
}
test().then(()=>{
process.exit(0)
})
|
输出
1
2
3
4
|
current value:0
after call inc(), current value:0
after send inc(), current value:1
after send dec(), current value:0
|
github
https://github.com/yinhui1984/Explain-of-Solidity-by-Example