solidity智能合约如何实现跨合约调用函数
背景
比如现在有一个需求、我需要通过外部合约获取BRC20 token的总交易量。那么我需要在brc20的转账函数里面做一些调整,主要是两个函数内统计转移量。然后再提供外部获取函数。
/*** @dev Sets `amount` as the allowance of `spender` over the caller's tokens.** Returns a boolean value indicating whether the operation succeeded.** IMPORTANT: Beware that changing an allowance with this method brings the risk* that someone may use both the old and the new allowance by unfortunate* transaction ordering. One possible solution to mitigate this race* condition is to first reduce the spender's allowance to 0 and set the* desired value afterwards:* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729** Emits an {Approval} event.*/function approve(address spender, uint256 amount) external returns (bool);/*** @dev Moves `amount` tokens from `sender` to `recipient` using the* allowance mechanism. `amount` is then deducted from the caller's* allowance.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.*/function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
实操
1、定义了一个函数接口
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;interface Iquery{function getTotalTransferAmount() external view returns (uint256);
}
2、BRC20 token实现目标函数
// SPDX-License-Identifier: MIT
pragma solidity >0.4.0 <= 0.9.0;interface IBEP20 {/*** @dev Returns the amount of tokens in existence.*/function totalSupply() external view returns (uint256);/*** @dev Returns the token decimals.*/function decimals() external view returns (uint8);/*** @dev Returns the token symbol.*/function symbol() external view returns (string memory);/*** @dev Returns the token name.*/function name() external view returns (string memory);/*** @dev Returns the bep token owner.*/function getOwner() external view returns (address);/*** @dev Returns the amount of tokens owned by `account`.*/function balanceOf(address account) external view returns (uint256);/*** @dev Moves `amount` tokens from the caller's account to `recipient`.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.*/function transfer(address recipient, uint256 amount) external returns (bool);/*** @dev Returns the remaining number of tokens that `spender` will be* allowed to spend on behalf of `owner` through {transferFrom}. This is* zero by default.** This value changes when {approve} or {transferFrom} are called.*/function allowance(address _owner, address spender) external view returns (uint256);/*** @dev Sets `amount` as the allowance of `spender` over the caller's tokens.** Returns a boolean value indicating whether the operation succeeded.** IMPORTANT: Beware that changing an allowance with this method brings the risk* that someone may use both the old and the new allowance by unfortunate* transaction ordering. One possible solution to mitigate this race* condition is to first reduce the spender's allowance to 0 and set the* desired value afterwards:* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729** Emits an {Approval} event.*/function approve(address spender, uint256 amount) external returns (bool);/*** @dev Moves `amount` tokens from `sender` to `recipient` using the* allowance mechanism. `amount` is then deducted from the caller's* allowance.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.*/function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);/*** @dev Emitted when `value` tokens are moved from one account (`from`) to* another (`to`).** Note that `value` may be zero.*/event Transfer(address indexed from, address indexed to, uint256 value);/*** @dev Emitted when the allowance of a `spender` for an `owner` is set by* a call to {approve}. `value` is the new allowance.*/event Approval(address indexed owner, address indexed spender, uint256 value);
}/** @dev Provides information about the current execution context, including the* sender of the transaction and its data. While these are generally available* via msg.sender and msg.data, they should not be accessed in such a direct* manner, since when dealing with GSN meta-transactions the account sending and* paying for execution may not be the actual sender (as far as an application* is concerned).** This contract is only required for intermediate, library-like contracts.*/
contract Context {// Empty internal constructor, to prevent people from mistakenly deploying// an instance of this contract, which should be used via inheritance.constructor () { }function _msgSender() internal view returns (address) {return msg.sender;}function _msgData() internal view returns (bytes memory) {this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691return msg.data;}
}/*** @dev Wrappers over Solidity's arithmetic operations with added overflow* checks.** Arithmetic operations in Solidity wrap on overflow. This can easily result* in bugs, because programmers usually assume that an overflow raises an* error, which is the standard behavior in high level programming languages.* `SafeMath` restores this intuition by reverting the transaction when an* operation overflows.** Using this library instead of the unchecked operations eliminates an entire* class of bugs, so it's recommended to use it always.*/
library SafeMath {/*** @dev Returns the addition of two unsigned integers, reverting on* overflow.** Counterpart to Solidity's `+` operator.** Requirements:* - Addition cannot overflow.*/function add(uint256 a, uint256 b) internal pure returns (uint256) {uint256 c = a + b;require(c >= a, "SafeMath: addition overflow");return c;}/*** @dev Returns the subtraction of two unsigned integers, reverting on* overflow (when the result is negative).** Counterpart to Solidity's `-` operator.** Requirements:* - Subtraction cannot overflow.*/function sub(uint256 a, uint256 b) internal pure returns (uint256) {return sub(a, b, "SafeMath: subtraction overflow");}/*** @dev Returns the subtraction of two unsigned integers, reverting with custom message on* overflow (when the result is negative).** Counterpart to Solidity's `-` operator.** Requirements:* - Subtraction cannot overflow.*/function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {require(b <= a, errorMessage);uint256 c = a - b;return c;}/*** @dev Returns the multiplication of two unsigned integers, reverting on* overflow.** Counterpart to Solidity's `*` operator.** Requirements:* - Multiplication cannot overflow.*/function mul(uint256 a, uint256 b) internal pure returns (uint256) {// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a == 0) {return 0;}uint256 c = a * b;require(c / a == b, "SafeMath: multiplication overflow");return c;}/*** @dev Returns the integer division of two unsigned integers. Reverts on* division by zero. The result is rounded towards zero.** Counterpart to Solidity's `/` operator. Note: this function uses a* `revert` opcode (which leaves remaining gas untouched) while Solidity* uses an invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function div(uint256 a, uint256 b) internal pure returns (uint256) {return div(a, b, "SafeMath: division by zero");}/*** @dev Returns the integer division of two unsigned integers. Reverts with custom message on* division by zero. The result is rounded towards zero.** Counterpart to Solidity's `/` operator. Note: this function uses a* `revert` opcode (which leaves remaining gas untouched) while Solidity* uses an invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {// Solidity only automatically asserts when dividing by 0require(b > 0, errorMessage);uint256 c = a / b;// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;}/*** @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),* Reverts when dividing by zero.** Counterpart to Solidity's `%` operator. This function uses a `revert`* opcode (which leaves remaining gas untouched) while Solidity uses an* invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function mod(uint256 a, uint256 b) internal pure returns (uint256) {return mod(a, b, "SafeMath: modulo by zero");}/*** @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),* Reverts with custom message when dividing by zero.** Counterpart to Solidity's `%` operator. This function uses a `revert`* opcode (which leaves remaining gas untouched) while Solidity uses an* invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {require(b != 0, errorMessage);return a % b;}
}/*** @dev Contract module which provides a basic access control mechanism, where* there is an account (an owner) that can be granted exclusive access to* specific functions.** By default, the owner account will be the one that deploys the contract. This* can later be changed with {transferOwnership}.** This module is used through inheritance. It will make available the modifier* `onlyOwner`, which can be applied to your functions to restrict their use to* the owner.*/
contract Ownable is Context {address private _owner;event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);/*** @dev Initializes the contract setting the deployer as the initial owner.*/constructor () {address msgSender = _msgSender();_owner = msgSender;emit OwnershipTransferred(address(0), msgSender);}/*** @dev Returns the address of the current owner.*/function owner() public view returns (address) {return _owner;}/*** @dev Throws if called by any account other than the owner.*/modifier onlyOwner() {require(_owner == _msgSender(), "Ownable: caller is not the owner");_;}/*** @dev Leaves the contract without owner. It will not be possible to call* `onlyOwner` functions anymore. Can only be called by the current owner.** NOTE: Renouncing ownership will leave the contract without an owner,* thereby removing any functionality that is only available to the owner.*/function renounceOwnership() public onlyOwner {emit OwnershipTransferred(_owner, address(0));_owner = address(0);}/*** @dev Transfers ownership of the contract to a new account (`newOwner`).* Can only be called by the current owner.*/function transferOwnership(address newOwner) public onlyOwner {_transferOwnership(newOwner);}/*** @dev Transfers ownership of the contract to a new account (`newOwner`).*/function _transferOwnership(address newOwner) internal {require(newOwner != address(0), "Ownable: new owner is the zero address");emit OwnershipTransferred(_owner, newOwner);_owner = newOwner;}
}
import "contracts/test/testQuery/Iqery.sol";
contract BEP20Token is Context, IBEP20, Ownable,Iquery {using SafeMath for uint256;uint256 public totalTransferAmount ;mapping (address => uint256) private _balances;mapping (address => mapping (address => uint256)) private _allowances;uint256 private _totalSupply;uint8 private _decimals;string private _symbol;string private _name;constructor() public {_name = "cor4 tokne";_symbol ="cor4" ;_decimals = 18;_totalSupply = 1000000000000000 *10**18;_balances[msg.sender] = _totalSupply;emit Transfer(address(0), msg.sender, _totalSupply);}// 添加一个视图函数,允许其他合约读取totalTransferAmountfunction getTotalTransferAmount() public view returns (uint256) {return totalTransferAmount;}/*** @dev Returns the bep token owner.*/function getOwner() external view returns (address) {return owner();}/*** @dev Returns the token decimals.*/function decimals() external view returns (uint8) {return _decimals;}/*** @dev Returns the token symbol.*/function symbol() external view returns (string memory) {return _symbol;}/*** @dev Returns the token name.*/function name() external view returns (string memory) {return _name;}/*** @dev See {BEP20-totalSupply}.*/function totalSupply() external view returns (uint256) {return _totalSupply;}/*** @dev See {BEP20-balanceOf}.*/function balanceOf(address account) external view returns (uint256) {return _balances[account];}/*** @dev See {BEP20-transfer}.** Requirements:** - `recipient` cannot be the zero address.* - the caller must have a balance of at least `amount`.*/function transfer(address recipient, uint256 amount) external returns (bool) {_transfer(_msgSender(), recipient, amount);totalTransferAmount += amount;return true;}/*** @dev See {BEP20-allowance}.*/function allowance(address owner, address spender) external view returns (uint256) {return _allowances[owner][spender];}/*** @dev See {BEP20-approve}.** Requirements:** - `spender` cannot be the zero address.*/function approve(address spender, uint256 amount) external returns (bool) {_approve(_msgSender(), spender, amount);return true;}/*** @dev See {BEP20-transferFrom}.** Emits an {Approval} event indicating the updated allowance. This is not* required by the EIP. See the note at the beginning of {BEP20};** Requirements:* - `sender` and `recipient` cannot be the zero address.* - `sender` must have a balance of at least `amount`.* - the caller must have allowance for `sender`'s tokens of at least* `amount`.*/function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {_transfer(sender, recipient, amount);_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));totalTransferAmount += amount;return true;}/*** @dev Atomically increases the allowance granted to `spender` by the caller.** This is an alternative to {approve} that can be used as a mitigation for* problems described in {BEP20-approve}.** Emits an {Approval} event indicating the updated allowance.** Requirements:** - `spender` cannot be the zero address.*/function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));return true;}/*** @dev Atomically decreases the allowance granted to `spender` by the caller.** This is an alternative to {approve} that can be used as a mitigation for* problems described in {BEP20-approve}.** Emits an {Approval} event indicating the updated allowance.** Requirements:** - `spender` cannot be the zero address.* - `spender` must have allowance for the caller of at least* `subtractedValue`.*/function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: decreased allowance below zero"));return true;}/*** @dev Creates `amount` tokens and assigns them to `msg.sender`, increasing* the total supply.** Requirements** - `msg.sender` must be the token owner*/function mint(uint256 amount) public onlyOwner returns (bool) {_mint(_msgSender(), amount);return true;}/*** @dev Moves tokens `amount` from `sender` to `recipient`.** This is internal function is equivalent to {transfer}, and can be used to* e.g. implement automatic token fees, slashing mechanisms, etc.** Emits a {Transfer} event.** Requirements:** - `sender` cannot be the zero address.* - `recipient` cannot be the zero address.* - `sender` must have a balance of at least `amount`.*/function _transfer(address sender, address recipient, uint256 amount) internal {require(sender != address(0), "BEP20: transfer from the zero address");require(recipient != address(0), "BEP20: transfer to the zero address");_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");_balances[recipient] = _balances[recipient].add(amount);emit Transfer(sender, recipient, amount);}/** @dev Creates `amount` tokens and assigns them to `account`, increasing* the total supply.** Emits a {Transfer} event with `from` set to the zero address.** Requirements** - `to` cannot be the zero address.*/function _mint(address account, uint256 amount) internal {require(account != address(0), "BEP20: mint to the zero address");_totalSupply = _totalSupply.add(amount);_balances[account] = _balances[account].add(amount);emit Transfer(address(0), account, amount);}/*** @dev Destroys `amount` tokens from `account`, reducing the* total supply.** Emits a {Transfer} event with `to` set to the zero address.** Requirements** - `account` cannot be the zero address.* - `account` must have at least `amount` tokens.*/function _burn(address account, uint256 amount) internal {require(account != address(0), "BEP20: burn from the zero address");_balances[account] = _balances[account].sub(amount, "BEP20: burn amount exceeds balance");_totalSupply = _totalSupply.sub(amount);emit Transfer(account, address(0), amount);}/*** @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.** This is internal function is equivalent to `approve`, and can be used to* e.g. set automatic allowances for certain subsystems, etc.** Emits an {Approval} event.** Requirements:** - `owner` cannot be the zero address.* - `spender` cannot be the zero address.*/function _approve(address owner, address spender, uint256 amount) internal {require(owner != address(0), "BEP20: approve from the zero address");require(spender != address(0), "BEP20: approve to the zero address");_allowances[owner][spender] = amount;emit Approval(owner, spender, amount);}/*** @dev Destroys `amount` tokens from `account`.`amount` is then deducted* from the caller's allowance.** See {_burn} and {_approve}.*/function _burnFrom(address account, uint256 amount) internal {_burn(account, amount);_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "BEP20: burn amount exceeds allowance"));}
}
3、外部合约调用示例
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;interface Iquery{//声明需要调用的函数function getTotalTransferAmount() external view returns (uint256);
}contract queryErc20 {Iquery public factory;//注入合约constructor (Iquery _factory) {factory= _factory;}function getTotalTransferAmount2() public view returns (uint256) {return factory.getTotalTransferAmount();}}
4、输出

相关文章:
solidity智能合约如何实现跨合约调用函数
背景 比如现在有一个需求、我需要通过外部合约获取BRC20 token的总交易量。那么我需要在brc20的转账函数里面做一些调整,主要是两个函数内统计转移量。然后再提供外部获取函数。 /*** dev Sets amount as the allowance of spender over the callers tokens.** Ret…...
关于Vue2的生命周期会问到哪些面试题?
在Vue2的面试中,关于生命周期的问题通常会涉及以下几个方面: 一、Vue2的生命周期概述 Vue2的生命周期是什么? Vue2的生命周期是指从Vue实例的创建、初始化数据、编译模板、挂载Dom、渲染、更新、卸载等一系列过程。 二、生命周期钩子函数 …...
尚品汇-(七)
(1)在网关中实现跨域 全局配置类实现 包名:com.atguigu.gmall.gateway.config 创建CorsConfig类 Configuration public class CorsConfig {Beanpublic CorsWebFilter corsWebFilter(){// cors跨域配置对象CorsConfiguration configuration…...
【Python datetime模块精讲】:时间旅行者的日志,精准操控日期与时间
文章目录 前言一、datetime模块简介二、常用类和方法三、date类四、time类五、datetime类六、timedelta类七、常用的函数和属性八、代码及其演示 前言 Python的datetime模块提供了日期和时间的类,用于处理日期和时间的算术运算。这个模块包括date、time、datetime和…...
keepalived 服务高可用(简约版)
本文基于centos 7记述如何使用keepalived 背景 为生产环境准备一台备机是极其必要的,防止主机宕掉无服务可用的情况出现。但是同一局域网内每台主机都分配了一个唯一IP,这些IP既然相互不同,那么服务请求的时候岂不是要切换IP地址?…...
【前端】Vue项目和微信小程序生成二维码和条形码
前言:哈喽,大家好,我是前端菜鸟的自我修养!今天给大家分享Vue项目和微信小程序如何生成二维码和条形码,介绍了JsBarcode、wxbarcode等插件,并提供具体代码帮助大家深入理解,彻底掌握!…...
同时使用接口文档swagger和knife4j
项目场景: springboot项目中同时使用接口文档swagger和knife4j 问题描述 在实体类中设置了字段必填的属性,在访问接口文档时出现异常 实体类关键代码片段 /*** 部门表 sys_dept*/ public class SysDept extends BaseEntity {private static final lo…...
Compose - 权限申请
官方介绍 一、概念 二、使用 Accompanist Permissions 官方介绍 不同版本中,权限状态(如PermissionState)中获取属性的方法不同,例如在“0.23.1”中,通过 PermissionState.hasPermission 属性拿到是否通过的 Boole…...
第十九条:要么为继承而设计并提供文档说明,要么就禁止继承
在前面一条中,我们已经知道了David写了A类被Tom拿去继承了,导致了A类的封装性遭到了破坏,那么有没有可能做点事情避免此事发生呢?第十九条孕育而生!David在创建A类的时候写上文档说明,说Al类不允许任何类来…...
Node.js全栈指南:浏览器显示一个网页
上一章,我们了解到,如何通过第二章的极简 Web 的例子来演示如何查看官方文档。为什么要把查阅官方文档放在前面的章节说明呢?因为查看文档是一个很重要的能力,就跟查字典一样。 回想一下,我们读小学,初中的…...
Linux远程桌面(Ubuntu/Deepin)——安装和使用 VNC 及通过 noVNC 实现浏览器实现远程桌面访问教程
在 Linux 上安装和使用 VNC 及通过 noVNC 实现浏览器远程访问教程 Windows上通常会自带xrdp远程桌面,但是当我们使用 Deepin 或 Ubuntu 系统作为开发机器且需要图形化界面的时候,就需要安装和配置 VNC(Virtual Network Computing)…...
2024年最新通信安全员考试题库
61.架设架空光缆,可使用吊板作业的情况是()。 A.在2.2/7规格的电杆与墙壁之间的吊线上,吊线高度5m B.在2.2/7规格的墙壁与墙壁之间的吊线上,吊线高度6m C.在2.2/7规格的电杆与电杆之间的吊线上,吊线高度…...
SpringMVC系列八: 手动实现SpringMVC底层机制-下
手动实现SpringMVC底层机制-下 实现任务阶段五🍍完成Spring容器对象的自动装配-Autowired 实现任务阶段六🍍完成控制器方法获取参数-RequestParam1.🥦将 方法的 HttpServletRequest 和 HttpServletResponse 参数封装到数组, 进行反射调用2.&a…...
【昇思初学入门】第八天打卡-模型保存与加载
模型保存与加载 学习心得 保存 CheckPoint 格式文件,在模型训练过程中,可以添加检查点(CheckPoint)用于保存模型的参数,以便进行推理及再训练使用。如果想继续在不同硬件平台上做推理,可通过网络和CheckPoint格式文件生成对应的…...
喜报!极限科技新获得一项国家发明专利授权:“搜索数据库的正排索引处理方法、装置、介质和设备”
近日,极限数据(北京)科技有限公司(简称:极限科技)新获得一项国家发明专利授权,专利名为 “搜索数据库的正排索引处理方法、装置、介质和设备”,专利号:ZL 2024 1 0479400…...
深入探讨:UART与USART在单片机中串口的实际应用与实现技巧
单片机(Microcontroller Unit, MCU)是一种集成了处理器、存储器和输入输出接口的微型计算机。它广泛应用于嵌入式系统中,用于控制各类电子设备。UART和USART是单片机中常见的通信接口,负责串行数据传输。下面我们详细介绍它们在单…...
Windows上PyTorch3D安装踩坑记录
直入正题,打开命令行,直接通过 pip 安装 PyTorch3D : (python11) F:\study\2021-07\python>pip install pytorch3d Looking in indexes: http://mirrors.aliyun.com/pypi/simple/ ERROR: Could not find a version that satisfies the requirement p…...
操作符详解(上) (C语言)
操作符详解(上) 一. 进制转换1. 二进制2. 二进制的转换 二. 原码 补码 反码三. 操作符的分类四. 结构成员访问操作符1. 结构体的声明2. 结构体成员访问操作符 一. 进制转换 1. 二进制 在学习操作符之前,我们先了解一些2进制、8进制、10进制…...
使用 audit2allow 工具添加SELinux权限的方法
1. audit2allow工具的使用 audit2allow 命令的作用是分析日志,并提供允许的建议规则或拒绝的建议规则。 1.1 audit2allow的安装 sudo apt-get install policycoreutilssudo apt install policycoreutils-python-utils 1.2 auditallow的命令 命令含义用法-v--ve…...
一文弄懂FPGA
一、FPGA简介 什么是FPGA? FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,可以在现场通过硬件描述语言(HDL)进行配置。它具有高度的灵活性和并行处理能力,广泛应用于通信、计算、…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
