18-函数返回值
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract FunctionOutputs {
function returnMany() public pure returns (uint , bool) {
return (1, true);
}
function named() public pure returns (uint x, bool b) {
return (1, true);
}
function assigned() public pure returns (uint x, bool b) {
x = 1;
b = true;
}
uint public _x;
bool public _b1;
bool public _b2;
function destructingAssigments() public{
(uint x, bool b1) = returnMany();
(, bool b2) = returnMany();
_x = x;
_b1 = b1;
_b2 = b2;
}
}
19-数组
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Array {
// Array - dynamic or fixed size
// Initialization
uint[] public nums = [1, 2, 3];
uint[3] public numsFixed = [4, 5, 6];
// Insert(push) get update delete pop length
function examples() external {
nums.push(4); // [1, 2, 3, 4]
uint x = nums[1];
nums[2] = 777; // [1, 2, 777, 4]
delete nums[1]; // [1, 0, 777, 4]
nums.pop(); // [1, 0, 777]
uint len = nums.length;
// create array in memory
uint[] memory a = new uint[](5);
a[1] = 123;
}
// returning array from function
function returnArray() external view returns (uint[] memory) {
return nums;
}
}
20-数组删除元素通过移动位置
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract ArrayShift {
uint[] public arr;
function example() public {
arr = [1, 2, 3];
delete arr[1]; // [1, 0, 3] => [1, 3]
}
function remove(uint _index) public {
require(_index < arr.length, "index out of bound");
for (uint i = _index; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}
arr.pop();
}
function test() external {
arr = [1, 2, 3, 4, 5];
remove(2);
assert(arr[0] == 1);
assert(arr[1] == 2);
assert(arr[2] == 4);
assert(arr[3] == 5);
assert(arr.length == 4);
arr = [1];
remove(0);
assert(arr.length == 0);
}
}
21-删除数组中元素通过替换
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract ArrayReplaceLast {
uint[] public arr;
// 优点:消耗较少的gas,缺点:会打乱数组顺序
function example() public {
arr = [1, 2, 3, 4];
remove(1);
assert(arr[0] == 1);
assert(arr[1] == 4);
assert(arr[2] == 3);
}
function remove(uint _index) public {
arr[_index] = arr[arr.length - 1];
arr.pop();
}
}
22-映射
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Mapping {
mapping(address => uint) public balances;
mapping(address => mapping(address => bool)) public isFriend;
uint public bal1;
uint public bal2;
function examples() external {
balances[msg.sender] = 123;
bal1 = balances[msg.sender];
bal2 = balances[address(1)];
balances[msg.sender] += 456;
// 删除并不会真的删除,而是变成初始值
delete balances[msg.sender];
// 嵌套映射
isFriend[msg.sender][msg.sender] = true;
}
}
23-映射迭代
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
// 由于映射不能遍历
contract IterableMapping {
mapping(address => uint) public balances;
mapping(address => bool) public inserted;
address[] public keys;
function set (address _key, uint _val) external {
balances[_key] = _val;
if (!inserted[_key]) {
inserted[_key] = true;
keys.push(_key);
}
}
function getSize() external view returns (uint) {
return keys.length;
}
function first() external view returns (uint) {
return balances[keys[0]];
}
function last() external view returns (uint) {
return balances[keys[keys.length - 1]];
}
function get(uint _i) external view returns (uint) {
return balances[keys[_i]];
}
}
24-结构体
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Structs {
struct Car {
string model;
uint year;
address owner;
}
Car public car;
Car[] public cars;
mapping (address => Car[]) public carsByOwner;
function examples() external {
Car memory toyota = Car("Toyota", 1990, msg.sender);
Car memory lambo = Car({model: "Lamborhini", owner: msg.sender, year: 1980});
Car memory tesla;
tesla.model = "Tesla";
tesla.year = 2015;
tesla.owner = msg.sender;
cars.push(toyota);
cars.push(lambo);
cars.push(tesla);
Car memory _car = cars[0];
_car.owner;
_car.year = 1969;
// 可以删除结构体数组中的某一个结构体,也可以删除结构体中的一个参数
delete _car.model;
delete cars[1];
}
}
25-枚举
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Enum {
enum Status {
None,
Pending,
Shipped,
Completed,
Rejected,
Canceled
}
Status public status;
struct Order {
address buyer;
Status status;
}
Order[] public orders;
function get() external view returns (Status) {
return status;
}
function set(Status _status) external {
status = _status;
}
function ship() external {
status = Status.Shipped;
}
function reset() external {
delete status;
}
}
26-部署合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract TestContract1 {
address public owner = msg.sender;
function setOwner(address _owner) public {
require(msg.sender == owner, "not owner");
owner = _owner;
}
}
contract TestContract2 {
address public owner = msg.sender;
uint public value = msg.value;
uint public x;
uint public y;
constructor(uint _x, uint _y) payable {
x = _x;
y = _y;
}
}
contract Proxy {
event Deploy(address);
fallback() external payable { }
function deploy(bytes memory _code) external payable returns (address addr) {
assembly {
// create(v, p, n)
// v = amount of ETH to send
// p = pointer in memory to start of code
// n = size of code
addr := create(callvalue(), add(_code, 0x20), mload(_code))
}
require(addr != address(0), "deploy failed");
emit Deploy(addr);
}
function execute(address _target, bytes memory _data) external payable {
(bool success, ) = _target.call{value: msg.value}(_data);
require(success, "failed");
}
}
contract Helper {
function getBytecode1() external pure returns (bytes memory) {
// 得到部署合约的机器码
bytes memory bytecode = type(TestContract1).creationCode;
return bytecode;
}
function getBytecode2(uint _x, uint _y) external pure returns (bytes memory) {
bytes memory bytecode = type(TestContract2).creationCode;
// 将传入的参数通过的打包的方式形成新的bytecode
return abi.encodePacked(bytecode, abi.encode(_x, _y));
}
function getCalldata(address _owner) external pure returns (bytes memory) {
return abi.encodeWithSignature("setOwner(address)", _owner);
}
}