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)进行配置。它具有高度的灵活性和并行处理能力,广泛应用于通信、计算、…...
告别C盘爆满!手把手教你配置Miniforge,让所有虚拟环境乖乖待在D盘
彻底解放C盘空间:Miniforge虚拟环境全迁移至D盘实战指南 每次打开资源管理器看到C盘飘红的存储条,心跳都会漏半拍——这大概是Windows开发者最熟悉的焦虑场景。特别是当你发现conda创建的虚拟环境正悄无声息吞噬着宝贵的系统盘空间时,那种无…...
Cursor Pro免费激活终极指南:如何突破试用限制重新获得AI编程体验
Cursor Pro免费激活终极指南:如何突破试用限制重新获得AI编程体验 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reach…...
多宽带联网(五) OpenWrt中MWAN3高级策略分流实战(游戏加速、视频优化场景)
1. MWAN3策略分流的核心价值 家里拉了两条宽带却发现刷视频卡、打游戏延迟高?这种情况我遇到过太多次了。去年给朋友家调试网络时,他同时接了电信和联通两条200M宽带,但看4K视频还是缓冲,玩外服游戏延迟总在200ms以上。后来用Open…...
资源处理效率工具RePKG:从问题解决到场景创新的实战指南
资源处理效率工具RePKG:从问题解决到场景创新的实战指南 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg 在数字创意和开发工作中,我们经常遇到各种专用格式的…...
告别混乱!用PyQt5模块化设计打造你的工业上位机(附完整源码与两种传值方式详解)
工业级PyQt5模块化开发实战:从架构设计到数据交互的完整指南 在工业自动化与测控领域,上位机软件往往需要集成数据采集、实时监控、设备控制等复杂功能。传统开发方式容易导致代码臃肿、维护困难——按钮事件与业务逻辑纠缠不清,数据流向如迷…...
MedGemma 1.5新手必看:从安装到问诊,完整使用流程详解
MedGemma 1.5新手必看:从安装到问诊,完整使用流程详解 你是否曾面对一份复杂的化验单,需要快速理解其临床意义?是否在深夜值班时,想快速确认某个药物的相互作用?或者,作为一名医学生࿰…...
springboot+vue基于web的演唱会音乐会购票管理系统设计系统
目录同行可拿货,招校园代理 ,本人源头供货商系统功能模块分析技术架构设计核心业务流程安全防护措施项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 系统功能模块分析 用户模块 注册登…...
FlexRay帧格式拆解:从Header到Trailer,手把手教你读懂汽车总线的‘数据包’
FlexRay帧格式实战解析:像拆解网络包一样掌握汽车总线通信 在汽车电子系统开发中,理解总线协议就像网络工程师需要精通TCP/IP一样重要。FlexRay作为高性能车载网络的核心协议,其帧格式设计既体现了汽车电子对确定性的严苛要求,又融…...
用VSCode+PlatformIO给ESP32做个简易手表:基于LVGL和1.3寸屏的UI实战
基于LVGL的ESP32智能手表开发实战:从硬件驱动到UI设计全流程 在创客圈里,ESP32凭借其出色的性价比和丰富的功能接口,一直是物联网项目的热门选择。而当我们把目光投向更直观的人机交互领域时,LVGL(Light and Versatile…...
ESP32-S3离线语音唤醒实战:从单元测试到自定义指令集
1. ESP32-S3离线语音唤醒开发环境搭建 第一次接触ESP32-S3的语音识别功能时,我花了两天时间才把开发环境配置好。这里分享下我的踩坑经验,帮你节省时间。ESP-IDF的环境配置其实不难,但有几个关键点容易出错。 首先需要安装ESP-IDF v4.4或更高…...
