搭建
hardhat
环境
- 全局安装
solcjs
npm install -g solc
- 查看是否安装成功
solcjs --version
输出 0.8.21+commit.d9974bed.Emscripten.clang - 下载
remix
桌面版
https://github.com/ethereum/remix-desktop/releases
- 创建新文件夹并进入
-
npx hardhat
选择ts创建项目 -
npm i -g hardhat-shorthand
安装 缩写和自动补全
hh
相当于npx hardhat
-
ts
测试合约方法
const [owner, addr1] = await ethers.getSigners();
console.log('owner===',owner,addr1)
const testaa = await ethers.deployContract('Test')
await testaa.setOwner('0x70997970C51812dc3A010C7d01b50e0d17dc79C8')
const abc = await testaa.getOwner()
console.log('-=-=--=-',abc)
solidity 语法记录
selfdestruct
https://www.alchemy.com/overviews/selfdestruct-solidity
修饰符
pure 对于函数:不允许修改或访问状态。
view 对于函数:不允许修改状态。
payable 对于功能:允许他们在接到电话的同时接收乙醚。
constant 对于状态变量:不允许赋值(初始化除外),不占用存储槽。
immutable 对于状态变量:在构造时只允许一个赋值,之后是常量。存储在代码中。
anonymous 对于事件:不将事件签名存储为主题。
indexed 对于事件参数:将参数存储为主题。
virtual 对于函数和修饰符:允许在派生契约中更改函数或修饰符的行为。
library
https://www.geeksforgeeks.org/solidity-libraries/
通过创建库来部署通用代码可以降低gas成本
数据存储 memory storage calldata
https://docs.alchemy.com/docs/when-to-use-storage-vs-memory-vs-calldata-in-solidity
https://docs.alchemy.com/docs/what-is-the-difference-between-memory-and-calldata-in-solidity
https://dev.to/ratracegrad/storage-vs-memory-vs-calldata-understanding-data-locations-in-solidity-52ff
msg.sender
https://medium.com/upstate-interactive/what-you-need-to-know-about-msg-global-variables-in-solidity-566f1e83cc69
错误处理assert revert require error
https://medium.com/blockchannel/the-use-of-revert-assert-and-require-in-solidity-and-the-new-revert-opcode-in-the-evm-1a3a7990e06e
函数修饰符 public external internal private
https://blockchain-academy.hs-mittweida.de/courses/solidity-coding-beginners-to-intermediate/lessons/solidity-5-calling-other-contracts-visibility-state-access/topic/visibility-public-private-external-internal/
自定义值类型
type UFixed256x18 is uint256;
// 用户定义的值类型允许在基本值类型上创建零成本抽象。这类似于别名,但具有更严格的类型要求。
// 用户定义的值类型使用 type C is V ,在哪里 C 是新引入的类型的名称,并且 V 必须是内置值类型(“基础类型”)。
// 类型 C 没有任何运算符或绑定的成员函数。特别是,即使是操作员 == 未定义。不允许与其他类型进行显式和隐式转换。
type UFixed256x18 is uint256;
// 该函数 C.wrap 用于从基础类型转换为自定义类型。类似地,函数 C.unwrap 用于从自定义类型转换为基础类型。
function add(UFixed256x18 a, UFixed256x18 b) internal pure returns (UFixed256x18) {
return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));
}
创建外部合约对象
Test1 test1Contract = new Test1();
枚举
enum ActionType { cancel, comfirm, sure, end }
结构
struct UserInfo {
address addr;
uint256 balance;
bool isNote;
string name;
}
UserInfo userInfo = UserInfo({
addr:0xE4cdDab0Cf6d9Bf2231cd7CA3A8c82Ba24C74a1d,
balance: 1,
isNote:false,
name:"jack"
});
编译器自动为所有 public 状态变量 生成 getter 函数
// test1Contract.amount()
uint public amount;
映射
// 映射类型 映射的数据位置只能为 storage
mapping (address => uint256) public balanceInfo;
function updateBalance(address addr) public {
balanceInfo[addr] = uint256(100);
}
定义事件
// 定义事件,alreadyEnd 调用后调用该事件
event SendParams(address owner, uint amount);
function alreadyEnd() public {
uint amounts;
// 在此处发送事件
emit SendParams(msg.sender, amounts);
}
try catch
// try 外部合约方法 catch
// 这个 try 关键字后面必须跟一个表示外部函数调用或协定创建的表达式 (new ContractName() ).
// 不会捕获表达式内部的错误(例如,如果它是一个复杂的表达式,同时还涉及内部函数调用),
// 只会在外部调用本身内部发生还原。这个 returns 后面的部分(可选)声明与外部调用返回的类型匹配的返回变量
try test1Contract.testFun() returns (uint) {
} catch {
}