Solidity8.0-03
对应崔棉大师 41-50课程
https://www.bilibili.com/video/BV1yS4y1N7yu/?spm_id_from=333.788&vd_source=c81b130b6f8bb3082bdb42226729d69c
调用其他合约 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; contract Callee {
uint public x;
uint public value; function setX(uint _x) public returns (uint) {
x = _x;
return x;
} function setXandSendEther(uint _x) public payable returns (uint, uint) {
x = _x;
value = msg.value; return (x, value);
}
} contract Caller {
function setX(Callee _callee, uint _x) public {
uint x = _callee.setX(_x);
} function setXFromAddress(address _addr, uint _x) public {
Callee callee = Callee(_addr);
callee.setX(_x);
} function setXandSendEther(Callee _callee, uint _x) public payable {
(uint x, uint value) = _callee.setXandSendEther{value: msg.value}(_x);
}
} 接口合约 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; contract Counter {
uint public count; function increment() external {
count += 1;
}
} interface ICounter {
function count() external view returns (uint); function increment() external;
} contract MyContract {
function incrementCounter(address _counter) external {
ICounter(_counter).increment();
} function getCount(address _counter) external view returns (uint) {
return ICounter(_counter).count();
}
} // Uniswap example
interface UniswapV2Factory {
function getPair(address tokenA, address tokenB)
external
view
returns (address pair);
} interface UniswapV2Pair {
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
} contract UniswapExample {
address private factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
address private dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address private weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; function getTokenReserves() external view returns (uint, uint) {
address pair = UniswapV2Factory(factory).getPair(dai, weth);
(uint reserve0, uint reserve1, ) = UniswapV2Pair(pair).getReserves();
return (reserve0, reserve1);
}
} 低级call // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; contract Receiver {
event Received(address caller, uint amount, string message); fallback() external payable {
emit Received(msg.sender, msg.value, "Fallback was called");
} function foo(string memory _message, uint _x) public payable returns (uint) {
emit Received(msg.sender, msg.value, _message); return _x + 1;
}
} contract Caller {
event Response(bool success, bytes data); // Let's imagine that contract B does not have the source code for
// contract A, but we do know the address of A and the function to call.
function testCallFoo(address payable _addr) public payable {
// You can send ether and specify a custom gas amount
//uint要写成uint256 特殊 ,不指定gas 会带全部gas发送交易
(bool success, bytes memory data) = _addr.call{value: msg.value, gas: 5000}(
abi.encodeWithSignature("foo(string,uint256)", "call foo", 123)
); emit Response(success, data);
} // Calling a function that does not exist triggers the fallback function.
function testCallDoesNotExist(address _addr) public {
(bool success, bytes memory data) = _addr.call(
abi.encodeWithSignature("doesNotExist()")
); emit Response(success, data);
}
} 委托调用
http://www.theblockbeats.info/en/news/31694
https://learnblockchain.cn/article/4125
工厂合约 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Account{
address public bank;
address public owner; constructor(address _owner) payable{
bank = msg.sender;
owner = _owner;
} } contract Factory{ Account[] public Accounts; function createAccount(address _owner) external payable{
Account acc = new Account{value:111}(_owner);
Accounts.push(acc);
} } 库合约 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; library SafeMath {
function add(uint x, uint y) internal pure returns (uint) {
uint z = x + y;
require(z >= x, "uint overflow"); return z;
}
} library Math {
function sqrt(uint y) internal pure returns (uint z) {
if (y > 3) {
z = y;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
// else z = 0 (default value)
}
} contract TestSafeMath {
using SafeMath for uint; uint public MAX_UINT = 2**256 - 1; function testAdd(uint x, uint y) public pure returns (uint) {
return x.add(y);
} function testSquareRoot(uint x) public pure returns (uint) {
return Math.sqrt(x);
}
} // Array function to delete element at index and re-organize the array
// so that their are no gaps between the elements.
library Array {
function remove(uint[] storage arr, uint index) public {
// Move the last element into the place to delete
require(arr.length > 0, "Can't remove from empty array");
arr[index] = arr[arr.length - 1];
arr.pop();
}
} contract TestArray {
using Array for uint[]; uint[] public arr; function testArrayRemove() public {
for (uint i = 0; i < 3; i++) {
arr.push(i);
} arr.remove(1); assert(arr.length == 2);
assert(arr[0] == 0);
assert(arr[1] == 2);
}
} 哈希运算 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; contract HashFunction {
function hash(string memory _text,uint _num,address _addr) public pure returns (bytes32) {
return keccak256(abi.encodePacked(_text, _num, _addr));
}
function encode_keccak256(string memory _text, string memory _text2) public pure returns (bytes32){
{
return keccak256(abi.encode(_text, _text2));
}
}
function encode(string memory _text, string memory _text2) public pure returns (bytes memory){
{
return abi.encode(_text, _text2);
}
}
/*
encode 将数据转为16进制并补0到长度64
encodePacked将数据转为16进制拼接
当两个字符串使用encodePacked "AAA","BBB" 和 "AA","ABBB"结果相同 特别注意
当返回非定长数组时 返回类型为 bytes
*/
function encodePacked(string memory _text,string memory _text2) public pure returns (bytes32) {
return keccak256(abi.encodePacked(_text, _text2));
} function collision(string memory _text,uint _num,string memory _text2) public pure returns (bytes32) {
return keccak256(abi.encodePacked(_text, _num, _text2));
}
} 验证签名
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10; /* Signature Verification How to Sign and Verify
# Signing
1. Create message to sign 创建签名
2. Hash the message 对签名hash
3. Sign the hash (off chain, keep your private key secret) 线下对签名hash用私钥加密 # Verify
1. Recreate hash from the original message 取椭圆加密 r s v
2. Recover signer from signature and hash ecrocver('签名hash',r,s,v) 解密签名的钱包地址
3. Compare recovered signer to claimed signer 比较解密后的地址和加密的钱包地址是否一致
*/ contract VerifySignature {
/* 1. Unlock MetaMask account
ethereum.enable()
*/ /* 2. Get message hash to sign
getMessageHash(
0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C,
123,
"coffee and donuts",
1
) hash = "0xcf36ac4f97dc10d91fc2cbb20d718e94a8cbfe0f82eaedc6a4aa38946fb797cd"
*/
function getMessageHash(
address _to,
uint _amount,
string memory _message,
uint _nonce
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(_to, _amount, _message, _nonce));
} /* 3. Sign message hash
# using browser
account = "copy paste account of signer here"
ethereum.request({ method: "personal_sign", params: [account, hash]}).then(console.log) # using web3
web3.personal.sign(hash, web3.eth.defaultAccount, console.log) Signature will be different for different accounts
0x993dab3dd91f5c6dc28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063e8f3f781b
*/
function getEthSignedMessageHash(bytes32 _messageHash)
public
pure
returns (bytes32)
{
/*
Signature is produced by signing a keccak256 hash with the following format:
"\x19Ethereum Signed Message\n" + len(msg) + msg
*/
return
keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash)
);
} /* 4. Verify signature
signer = 0xB273216C05A8c0D4F0a4Dd0d7Bae1D2EfFE636dd
to = 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C
amount = 123
message = "coffee and donuts"
nonce = 1
signature =
0x993dab3dd91f5c6dc28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063e8f3f781b
*/
function verify(
address _signer,
address _to,
uint _amount,
string memory _message,
uint _nonce,
bytes memory signature
) public pure returns (bool) {
bytes32 messageHash = getMessageHash(_to, _amount, _message, _nonce);
bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash); return recoverSigner(ethSignedMessageHash, signature) == _signer;
} function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature)
public
pure
returns (address)
{
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature); return ecrecover(_ethSignedMessageHash, v, r, s);
} function splitSignature(bytes memory sig)
public
pure
returns (
bytes32 r,
bytes32 s,
uint8 v
)
{
require(sig.length == 65, "invalid signature length"); assembly {
/*
First 32 bytes stores the length of the signature add(sig, 32) = pointer of sig + 32
effectively, skips first 32 bytes of signature mload(p) loads next 32 bytes starting at the memory address p into memory
*/ // first 32 bytes, after the length prefix
r := mload(add(sig, 32))
// second 32 bytes
s := mload(add(sig, 64))
// final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
} // implicitly return (r, s, v)
}
} 权限控制合约 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract AccessControl{
event GrantRole(bytes32 indexed role,address indexed account);
event RevokeRole(bytes32 indexed role,address indexed account);
constructor(){
_grantRole(ADMIN,msg.sender);
} mapping(bytes32 => mapping(address => bool)) public roles; bytes32 public constant ADMIN = keccak256(abi.encodePacked("ADMIN"));
bytes32 public constant USER = keccak256(abi.encodePacked("USER")); modifier onlyAdmin(bytes32 _role){
require(roles[_role][msg.sender],"not admin");
_;
} function _grantRole(bytes32 _role,address _account) internal {
roles[_role][_account] = true;
emit GrantRole(_role,_account);
}
function grantRole(bytes32 _role,address _account) external onlyAdmin(ADMIN){
_grantRole(_role,_account);
}
function revokeRole(bytes32 _role,address _account) external onlyAdmin(ADMIN){
roles[_role][_account] = false;
emit RevokeRole(_role,_account);
} } 自毁合约 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Kill{
constructor() payable {
}
/*
1.删除合约
2.强制发送主币 目标是合约地址没有fallback也可以发送主币
*/
function kill() external{
selfdestruct(payable(msg.sender));
}
function testCall() external pure returns(uint){
return 123;
}
} contract Helper{
function getBalance() external view returns (uint){
return address(this).balance;
} function Killer(Kill _kill) external {
_kill.kill();
}
}
Solidity8.0-03的更多相关文章
- 更新32位Spyder从3.0.0-> 3.2.3
https://stackoverflow.com/questions/51222550/how-to-update-spyder-3-3-0 It works!! 1. went to the An ...
- 集群架构03·MySQL初识,mysql8.0环境安装,mysql多实例
官方网址 https://dev.mysql.com/downloads/mysql/社区版本分析 MySQL5.5:默认存储引擎改为InnoDB,提高性能和可扩展性,增加半同步复制 MySQL5.6 ...
- Time.deltaTime 的平均值在0.1-0.2左右
Time.deltaTime 平均值在0.1-0.2左右 低的在0.03 高的在0.3
- Hdu 2955 Robberies 0/1背包
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- zabbix3.0安装部署文档
zabbix v3.0安装部署 摘要: 本文的安装过程摘自http://www.ttlsa.com/以及http://b.lifec-inc.com ,和站长凉白开的<ZABBIX从入门到精通v ...
- ASP.Net MVC3安全升级导致程序集从3.0.0.0变为3.0.0.1
开发环境一般引用的是本机 C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies下的System.Web.Mvc.dll,当 ...
- CentOS-6.5安装zabbix 3.0.4
关闭selinux [root@localhost /]# sed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux ...
- Hadoop 2.2.0 4结点集群安装 非HA
总体介绍 虚拟机4台,分布在1个物理机上,配置基于hadoop的集群中包括4个节点: 1个 Master, 3个 Salve,i p分布为: 10.10.96.33 hadoop1 (Master) ...
- Hadoop 2.2.0学习笔记20131209
1.下载java 7并安装 [root@server- ~]# rpm -ivh jdk-7u40-linux-x64.rpm Preparing... ####################### ...
- 【C#进阶系列】03 配置文件管理与程序集的引用版本重定向
先来点与标题不相关的: CLR支持两种程序集:弱命名程序集和强命名程序集. 两者的区别在于强命名程序集使用发布者的公钥和私钥进行签名.由于程序集被唯一性地标识,所以当应用程序绑定到强命名程序集时,CL ...
随机推荐
- 使用 sp_executesql 动态执行sql
参考: https://docs.microsoft.com/zh-cn/sql/relational-databases/system-stored-procedures/sp-executesql ...
- TypeScript 前端工程最佳实践
作者:王春雨 前言 随着前端工程化的快速发展, TypeScript 变得越来越受欢迎,它已经成为前端开发人员必备技能. TypeScript 最初是由微软开发并开源的一种编程语言,自2012年10月 ...
- CH32V307以太网(芯片内部10M)
用过WCH的CH579M或者CH563的话,就会发现CH32V307这个自带的10M以太网代码编写与前两颗芯片流程十分相似.部分区别就在于初始化方面. 代码流程依旧按照 初始化--->等待PHY ...
- [python] NetworkX实例
文章目录 NetworkX实例 1. 基础Basic 2. 绘图Drawing 3. 图标Graph NetworkX实例 代码下载地址 NetworkX 2.4版本的通用示例性示例.本教程介绍了约定 ...
- C语言指针常见问题
我们在学C语言时,指针是我们最头疼的问题之一,针对C语言指针,博主根据自己的实际学到的知识以及开发经验,总结了以下使用C语言指针时常见问题. 指针 指针做函数参数 学习函数的时候,讲了函数的参数都是值 ...
- 小白从零到AIoT之路(前言)
什么是AIoT 简单来说就是AI(人工智能)+IoT(物联网)= AIoT(人工智能物联网). AIoT融合AI技术和IoT技术,通过物联网产生.收集来自不同维度的.海量的数据存储于云端.边缘端,再通 ...
- php上传微信素材
private function HttpsUpdateFileServerRequest($url,$path_img){ $curl = curl_init (); if (class_exist ...
- Linux 常用命令(测试于CentOS8版本)
一.文件及文件夹操作 mkdir test #创建文件夹 默认在Home/test touch test.js #创建文件 默认Home/test.js touch test/test.js #创建文 ...
- 题解 P2602 [ZJOI2010] 数字计数
虽然说是数位 dp 入门题但是还是不是很会(悲 看了题解才做出来,中途因为各种 SB 问题调了很长时间(悲 聪明的你一定能看出来这是数位 dp,因此令 \(i\) 为当前填的位数,\(limit\) ...
- php pdo如何查询记录条数
转载php中文网:https://www.php.cn/php-ask-457710.html php pdo查询记录条数的方法:1.使用fetchAll函数查询,其语法如"$rows=$q ...