1、权限控制合约

核心: 

        嵌套映射 

功能:

        具有多种角色身份时,不同身份具有不同的权限

        角色=>账户=>权限

// SPDX-License-Identifier:MIT

pragma solidity ^0.8.7;

contract AccessControl{

event GrantRole(bytes32 indexed role, address indexed account);

event RevokeRole(bytes32 indexed role, address indexed account);

//使用bytes代替字符串能够降低消耗的gas

mapping(bytes32 => mapping(address => bool)) public roles;

//生成主键

// 0xdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42

bytes32 public constant ADMIN = keccak256(abi.encodePacked("ADMIN"));

//0x2db9fd3d099848027c2383d0a083396f6c41510d7acfd92adc99b6cffcf31e96

bytes32 public constant USER = keccak256(abi.encodePacked("USER"));

constructor(){

_grantrole(ADMIN,msg.sender);

}

modifier onlyRole(bytes32 _role){

require(roles[_role][msg.sender],"not authorized");

_;

}

function _grantrole(bytes32 _role,address _account) internal {

roles[_role][_account] = true;

emit GrantRole(_role,_account);

}

function grantRole(bytes32 _role,address _account) external onlyRole(ADMIN){

_grantrole(_role,_account);

}

function revokeRole(bytes32 _role,address _account) external onlyRole(ADMIN){

roles[_role][_account] = false;

emit RevokeRole(_role,_account);

}

}

2、自毁合约

selfdesctruct(address)

该函数能够强行发送主币 

// SPDX-License-Identifier:MIT

pragma solidity ^0.8.7;

contract Kill{

constructor() payable{}

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 kill(Kill _kill) external {

_kill.kill();

}

}

3、IERC20

ERC20代币标准:不是一套代码,而是一套具有目标功能的接口。

功能包括:

铸造代币、销毁代币

发行代币总额查询、记录并查询某地址代币余额;

向某地址发送一定数量代币;

A地址向B地址批准一定数量的代币、用户调用合约,从A地址向B地址发放一定数量的代币

// SPDX-License-Identifier:MIT

pragma solidity ^0.8.7;

interface IERC20{

//合约发布的代币总量

function totalSupply() external view returns (uint);

//某一个账户的当前余额

function balanceOf(address account) external view returns (uint);

//把当前账户一部分余额发送至另一个账户中

function transfer(address recipient, uint amount) external returns (bool);

//查询某个账户中批准了多少金额

function allowance(address owner, address spender) external view returns (uint);

//为某一个账户批准一定数量的资金

function apporve(address spender,uint amount) external returns (bool);

//从一个账户向另一个账户转移一定量资金

function transferFrom(address spender,address recipient,uint amount) external returns (bool);

event Transfer(address indexed from,address indexed to,uint amount);

event Approval(address indexed owner, address indexed spender, uint amount);

}

//合约ERC20继承IERC20,意味着ERC20用于实现相关接口

contract ERC20 is IERC20 {

uint public override totalSupply;

mapping(address => uint) public override balanceOf;

//allowance:一个地址向另一个地址映射的数字

mapping(address => mapping(address => uint )) public override allowance;

//token name

string public name="Test";

string public symbol = "TEST";

//1*10^8代表了一个整数1

uint public decimals = 18;

//把当前账户一部分余额发送至另一个账户中

function transfer(address recipient, uint amount) external override returns (bool){

balanceOf[msg.sender] -= amount;

balanceOf[recipient] += amount;

emit Transfer(msg.sender,recipient,amount);

return true;

}

//为某一个账户批准一定数量的资金

function apporve(address spender,uint amount) external override returns (bool){

allowance[msg.sender][spender] = amount;

emit Approval(msg.sender,spender,amount);

return true;

}

//合约调用者要求从一个账户向另一个账户转移一定量资金

function transferFrom(address spender,address recipient,uint amount) external override returns (bool){

//合约调用者向代币发送者的账户中批准的余额降低

allowance[spender][msg.sender] -= amount;

//合约调用者的代币账户余额降低

balanceOf[spender] += amount;

//代币接收者的账户余额增加

balanceOf[recipient] += amount;

emit Transfer(spender,recipient,amount);

return true;

}

//铸币

function mint(uint amount) external {

balanceOf[msg.sender] += amount;

totalSupply += amount;

emit Transfer(address(0),msg.sender,amount);

}

//销毁

function burn(uint amount) external{

balanceOf[msg.sender] -= amount;

totalSupply -= amount;

emit Transfer(msg.sender,address(0),amount);

}

}

4、多签钱包

必须有多个人同意的情况下才能把钱包里的钱转出。

// SPDX-License-Identifier:MIT

pragma solidity ^0.8.7;

contract MultiSigWallet{

event Deposit(address indexed sender,uint amount); //存款

event Submit(uint indexed txID); //提交一个交易申请

event Apporve(address indexed owner,uint indexed txId); //合约签名人进行批准

event Revoke(address indexed owner,uint indexed txID); //撤销批准

event Execute(uint indexed txID); //执行批准

address[] public owners; //合约的拥有者

mapping(address => bool) public isOwner; //用于查找某用户是否是签名人

uint public required; //确认数,最少同意进行交易的人数

struct Transaction {

address to;//发送的地址

uint value;//发送的主币数量

bytes data; //如果地址为合约地址,那么还能够执行一些合约中的函数

bool executed; // 标记交易是否执行成功

}

Transaction[] public transactions;//构建一个交易数组,索引值即为ID号

mapping(uint => mapping(address => bool)) public approved; //某一个交易ID下,某一个地址是否批准了该交易

modifier onlyOwner{

require(isOwner[msg.sender],"only owner!");

_;

}

//判断交易id是否存在,由于id即索引,只要交易id小于数组长度,那么判断该交易存在

modifier txExists(uint _txId){

require(0<_txId && _txId< transactions.length,"tx does not exist");

_;

}

//判断签字者是否已经同意

modifier notApproved(uint _txId){

require(!approved[_txId][msg.sender],"tx already approved");

_;

}

//判断是否已经执行交易

modifier notExecuted(uint _txId){

require(!transactions[_txId].executed,"tx already executed");

_;

}

//建立构造函数,用于添加管理者和最小批准人数

constructor(address[] memory _owners,uint _required){

require(_owners.length >0 ,"owner required");//要求管理者数量大于0

require( _required <= _owners.length,//要求最小批准人数大于0且小于等于管理者数量

"invaled required num"

);

//判断地址是否有效:无效地址判断:1、0地址;2、重复地址

for (uint i;i <_owners.length;i++){

address owner = _owners[i];

require(owner != address(0),"invaled owner");

require(!isOwner[owner],"owner is not unique"); //如果地址已经存在过,那么判断为无效地址

isOwner[owner] = true;

owners.push(owner);

}

required=_required;

}

receive() external payable{

emit Deposit(msg.sender,msg.value);

}

//构建交易事件提交函数

function submit(address _to, uint _value, bytes calldata _data) external onlyOwner{

transactions.push(Transaction({

to: _to,

value: _value,

data: _data,

executed: false

}));

emit Submit(transactions.length - 1);//交易it为数组-1

}

//构建交易事件批准函数

function approve(uint _txId)

external

onlyOwner

txExists(_txId)

notApproved(_txId)

notExecuted(_txId)

{

approved[_txId][msg.sender] = true;

emit Apporve(msg.sender,_txId);

}

//计算事件有多少人批准了,获取事件批准数量

function _getApprocalCount(uint _txId) private view returns(uint count){

for(uint i;i

if(approved[_txId][owners[i]]){

count += 1;

}

}

}

function execute(uint _txId) external txExists(_txId) notExecuted(_txId){

require(_getApprocalCount(_txId)>required,"approvals < required");

Transaction storage transaction = transactions[_txId];

transaction.executed = true;

(bool success,) = transaction.to.call{value:transaction.value}(

transaction.data

);

require(success,"tx failed");

emit Execute(_txId);

}

function revoke(uint _txId)

external

onlyOwner

txExists(_txId)

notExecuted(_txId)

{

require(approved[_txId][msg.sender],"tx not approved");

approved[_txId][msg.sender] = false;

emit Revoke(msg.sender,_txId);

}

}

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: