以太坊代币标准解读及相关Dapp的搭建

文章目录

  • 什么是以太坊代币标准
    • 1、什么是以太坊
    • 2、以太坊代币标准
  • 同质化代币 Dapp 搭建
    • 1、MetaMask 的安装
    • 2、Ganache 的安装
    • 3、实现 ERC-20 代币协议
    • 4、前端页面的编写
    • 5、部署流程及操作演示

什么是以太坊代币标准

1、什么是以太坊

以太坊(Ethereum)是一个去中心化的开源的有智能合约功能的公共区块链平台。以太币(ETH 或 Ξ)是以太坊的原生加密货币。截至2021年12月,以太币是市值第二高的加密货币,仅次于比特币。以太坊是使用最多的区块链。
以太坊的概念首次在2013至2014年间由程序员维塔利克·布特林受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。以太坊亦被称为“第二代的区块链平台”,仅次于比特币。(维基百科)

以太坊官网
在这里插入图片描述
以太坊作为区块链技术的一个开源平台,允许任何人在区块链上构建和使用去中心化的应用程序和加密货币。

以太坊的主要特点包括:

  • 智能合约 - 以太坊提供了智能合约的功能,可以在区块链上实现自动化的数字合约。这使得在区块链上进行可信交易成为可能。
  • 去中心化应用(Dapp) - 在以太坊上可以构建各种去中心化应用,以避免单一实体控制的风险。这些DApp可以实现很多创新的功能。
  • 加密货币 - 以太坊有自己的加密货币以太币,可以在以太坊区块链上进行交易。以太币是仅次于比特币的第二大数字货币。
  • 挖矿 - 以太坊也采用了工作证明机制,允许通过挖矿来维护网络安全和达成共识。挖矿可以获得以太币奖励。
  • 联盟链 - 以太坊支持创建私有或联盟链,在许可的网络内执行交易。这扩大了以太坊的应用范围。
    在这里插入图片描述

2、以太坊代币标准

以太坊代币标准是指在以太坊上发行代币需要遵循的一系列技术规范,以方便以太坊开发者在以太坊区块链上发行和交易加密数字资产,常见的代币标准有 ERC-20、ERC-721、ERC-777、ERC-1155、ERC-4626等。代币标准的实施有助于在项目的不同实现中保持统一的兼容性(例如以太坊客户和钱包),并确保智能合约和 dapps 仍保持兼容。(参考以太坊文档)

在这里插入图片描述
(图片来自以太坊官方网站)

同质化代币 Dapp 搭建

本文介绍基于 MetaMask + Ganache + Web3.js同质化代币 Dapp 搭建。

1、MetaMask 的安装

MetaMask 官网

MetaMask(小狐狸钱包),是用于与以太坊区块链进行交互的软件加密货币钱包。它可以通过浏览器扩展程序或移动应用程序让用户访问其以太坊钱包,与去中心化应用进行交互。
MetaMask 由 ConsenSys Software Inc. 开发运营,主要专注于以太坊为基础的工具及基础设施。(维基百科)

进入 MetaMask 官网直接点击下载 MetaMask 的浏览器扩展,第一次使用需要自己注册账号(注意保存好私钥)。
在这里插入图片描述
在这里插入图片描述

2、Ganache 的安装

Ganache 官网

Ganache 是一个能够在本地快速部署以太坊私有链的模拟应用。能够帮助开发者快速、简单、安全地测试和调试他们的去中心化应用(DApp),并在发布到生产环境之前预览其性能和功能。通过 Ganache,开发者可以快速查看所有账户的当前状态,包括他们的地址、私钥、交易和余额。

同样的,可以在 Ganache 官网点击下载 windows 版本的 Ganache ,操作简单,开箱即用。
在这里插入图片描述
在这里插入图片描述

3、实现 ERC-20 代币协议

ERC-20 代币标准

ERC-20(以太坊意见征求 20)由 Fabian Vogelsteller 提出于 2015 年 11 月。这是一个能实现智能合约中代币的应用程序接口标准。

ERC-20 的功能示例包括:

  • 将代币从一个帐户转到另一个帐户
  • 获取帐户的当前代币余额
  • 获取网络上可用代币的总供应量
  • 批准一个帐户中一定的代币金额由第三方帐户使用

如果智能合约实施了下列方法和事件,它可以被称为 ERC-20 代币合约,一旦部署,将负责跟踪以太坊上创建的代币。(以太坊官方文档)

在这里我们用 solidity 实现 ERC-20 代币协议:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;//  ERC-20 代币合约接口 
interface IERC20 {// 转账事件 event Transfer(address indexed _from, address indexed _to, uint256 _value);// 授权事件 event Approval(address indexed _owner, address indexed _spender, uint256 _value);// 代币名称function name() external view returns (string memory);// 代币符号 function symbol() external view returns (string memory);// 小数位数function decimals() external view returns (uint8);// 总供给量 function totalSupply() external view returns (uint256);// 余额查询function balanceOf(address _owner) external view returns (uint256 balance);// 转账function transfer(address _to, uint256 _value) external returns (bool success);// 从 from 账户转账function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);// 授权转账function approve(address _spender, uint256 _value) external returns (bool success);// 查询授权余额 function allowance(address _owner, address _spender) external view returns (uint256 remaining);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;import "./IERC-20.sol";// ERC-20 代币实现
contract ERC20Token is IERC20 { event Forge(address indexed account, uint256 amount);       // 锻造代币事件event Destroy(address indexed account, uint amount);        // 销毁代币事件 mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256))  public  allowance;uint256 public totalSupply;     string public name;             string public symbol;           uint8 public decimals;         // 构造函数 constructor(string memory name_, string memory symbol_, uint8 decimals_) {name = name_;                  symbol = symbol_; decimals = decimals_; }// 锻造代币 function forgeToken(address account, uint amount) external {require(amount > 0, "ERC-20: amount less than or equal to 0.");require(account != address(0), "ERC-20: forge to zero address.");balanceOf[account] += amount; totalSupply += amount; emit Forge(account, amount);}// 销毁代币 function destroyToken(address account, uint amount) external {require(amount > 0, "ERC-20: amount less than or equal to 0.");require(account != address(0), "ERC-20: destroy to zero address.");uint256 accountBalance = balanceOf[account]; require(accountBalance >= amount, "ERC-20: destroy amount exceeds balance.");balanceOf[account] = accountBalance - amount;totalSupply -= amount; emit Destroy(account, amount);}// 转账function transfer(address _to, uint256 _value) external returns (bool success){_transfer(msg.sender, _to, _value);return true; }// 从 _from 账户转账 _value 到 _to 账户function transferFrom(address _from, address _to, uint256 _value) external returns (bool success) {uint256 currentAllowance = allowance[_from][msg.sender];                        // 查询授权额度require(currentAllowance >= _value, "ERC-20: transfer amount exceeds allowances.");           // 是否超过授权额度 _transfer(_from, _to, _value);_approve(_from, msg.sender, currentAllowance - _value);return true;}function _transfer(address _from, address _to, uint256 _value) internal  {require(_value > 0, "ERC-20: value less than or equal to 0.");require(_from != address(0), "ERC-20: transfer from the zero address.");require(_to != address(0), "ERC-20: transfer to zero address.");uint256 senderBalance = balanceOf[_from];require(senderBalance >= _value, "ERC-20: sender amount exceeds balance.");balanceOf[_from] = senderBalance - _value; balanceOf[_to] += _value;emit Transfer(_from, _to, _value); }// 进行授权 function approve(address _spender, uint256 _value) external returns (bool success){_approve(msg.sender, _spender, _value); return true;}function _approve(address _from, address _to, uint256 _value) internal {require(_value >= 0, "ERC-20: value less than or equal to 0.");require(_from != address(0), "ERC-20: approve from the zero address.");    require(_to != address(0), "ERC-20: approve to the zero address.");allowance[_from][_to] = _value; emit Approval(_from, _to, _value);}
}

4、前端页面的编写

使用 bootstrap3.3.7 框架编写一个简单的前端界面
在这里插入图片描述

index.html 源码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>同质化代币Dapp</title><link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'><style>.jumbotron{background-color: #EDF0F5;}</style>
</head>
<body><div class="container"><div class="row clearfix"><div class="col-md-12 column"><h1 style="text-align: center;">💱同质化代币 Dapp 搭建</h1><div class="jumbotron" ><div class="row clearfix"><div class="col-md-3 column"><h3 id="tokenName"></h3></div><div class="col-md-3 column"><h3 id="tokenSymbol"></h3></div><div class="col-md-3 column"><h3 id="tokenDecimals"></h3></div><div class="col-md-3 column"><h3 id="totalSupply"></h3></div></div></div><div class="row clearfix"><div class="col-md-4 column"><span style="font-size: 20px;"><b>授权</b></span><form class="form-horizontal" role="form"><div class="form-group"><label for="approveSpender" class="col-sm-3 control-label">_spender:</label><div class="col-sm-9"><input type="text" class="form-control" id="approveSpender" placeholder="address"/></div></div><div class="form-group"><label for="approveValue" class="col-sm-3 control-label">_value:</label><div class="col-sm-9"><input type="text" class="form-control" id="approveValue" placeholder="uint256"/></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><a class="btn btn-primary" onclick="homoTokens('approve')">确定</a><font id="approveResult" style="float: right; font-size:medium;"></font></div></div></form></div><div class="col-md-4 column"><span style="font-size: 20px;"><b>允许</b></span><form class="form-horizontal" role="form"><div class="form-group"><label for="allowanceOwner" class="col-sm-3 control-label">_owner:</label><div class="col-sm-9"><input type="text" class="form-control" id="allowanceOwner" placeholder="address" /></div></div><div class="form-group"><label for="allowanceSpender" class="col-sm-3 control-label">_spender:</label><div class="col-sm-9"><input type="text" class="form-control" id="allowanceSpender" placeholder="address" /></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><a class="btn btn-success" onclick="homoTokens('allownace')">查询</a><font id="allownaceResult" style="float: right; font-size:medium;"></font></div></div></form></div><div class="col-md-4 column"><span style="font-size: 20px;"><b>转账</b></span><form class="form-horizontal" role="form"><div class="form-group"><label for="transferTo" class="col-sm-3 control-label">_to:</label><div class="col-sm-9"><input type="text" class="form-control" id="transferTo" placeholder="address" /></div></div><div class="form-group"><label for="transferValue" class="col-sm-3 control-label">_value:</label><div class="col-sm-9"><input type="text" class="form-control" id="transferValue" placeholder="uint256" /></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><a class="btn btn-primary" onclick="homoTokens('transfer')">确定</a><font id="transferResult" style="float: right; font-size:medium;"></font></div></div></form></div></div> <div class="row clearfix"><div class="col-md-4 column"><span style="font-size: 20px;"><b>从...转账</b></span><form class="form-horizontal" role="form"><div class="form-group"><label for="transferFromFrom" class="col-sm-3 control-label">_from:</label><div class="col-sm-9"><input type="text" class="form-control" id="transferFromFrom" placeholder="address" /></div></div><div class="form-group"><label for="transferFromTo" class="col-sm-3 control-label">_to:</label><div class="col-sm-9"><input type="text" class="form-control" id="transferFromTo" placeholder="address" /></div></div><div class="form-group"><label for="transferFromValue" class="col-sm-3 control-label">_value:</label><div class="col-sm-9"><input type="text" class="form-control" id="transferFromValue" placeholder="uint256" /></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><a class="btn btn-primary" onclick="homoTokens('transferFrom')">确定</a><font id="transferFromResult" style="float: right; font-size:medium;"></font></div></div></form></div><div class="col-md-4 column"><span style="font-size: 20px;"><b>余额</b></span><form class="form-horizontal" role="form"><div class="form-group"><label for="balanceOfOwner" class="col-sm-3 control-label">_owner:</label><div class="col-sm-9"><input type="text" class="form-control" id="balanceOfOwner" placeholder="address" /></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><a  class="btn btn-success" onclick="homoTokens('balanceOf')">查询</a><font id="balanceOfResult" style="float: right; font-size:medium;"></font></div></div></form></div></div> <hr/></div></div></div>
</body>
<script src="https://cdn.jsdelivr.net/npm/web3@0.20.1/dist/web3.js"></script>
<script src="./index.js"></script>
</html>

index.js 源码

const web3 = new Web3(new Web3.providers.HttpProvider("HTTP://127.0.0.1:7545"));   
const abi = JSON.parse('[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Destroy","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"destroyToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Forge","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"forgeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]')
const token20Contract = web3.eth.contract(abi);
const contractInstance = token20Contract.at('0xe95D98B5975B4D54Fe6d6F555A55009F1AEec13B');        //部署的合约地址
const fromAccount = web3.eth.accounts[0]; 
console.log(web3.eth.accounts); // 页面加载完执行 
window.onload = function () {const name = contractInstance.name.call().toString();const symbol = contractInstance.symbol.call().toString();const decimals = contractInstance.decimals.call().toString();const totalSupply = contractInstance.totalSupply.call().toString();setElementText('tokenName', "名称: " + name);setElementText('tokenSymbol', "符号: " + symbol);setElementText('tokenDecimals', "小数位: " + decimals);setElementText('totalSupply', "总供给量: " + totalSupply);
};// 设置元素文本 
function setElementText(eleId, text) {const element = document.getElementById(eleId);element.innerHTML = text;
}// 获取元素值 
function getElementValues(eleIds) {const result = []; for (const id of eleIds) {const inputValue = document.getElementById(id).value;if (!inputValue) {alert("缺少必要的参数。");return;} result.push(inputValue);}return result; 
}// 同质化代币 
function homoTokens(id) {if (id == "approve") {const argument = getElementValues(['approveSpender', 'approveValue']);if (argument) {// 返回交易的哈希值const transactionHash = contractInstance.approve(argument[0], argument[1], { from: fromAccount });if (transactionHash) setElementText("approveResult", 'true');else setElementText("approveResult", 'error');} } else if (id == "allownace") {const argument = getElementValues(['allowanceOwner', 'allowanceSpender']);if (argument) {const result = contractInstance.allowance.call(argument[0], argument[1]).toString();setElementText("allownaceResult", result);}} else if (id == "transfer") {const argument = getElementValues(['transferTo', 'transferValue']);if (argument) {const transactionHash = contractInstance.transfer(argument[0], argument[1], { from: fromAccount });if (transactionHash) setElementText("transferResult", 'true');else setElementText("transferResult", 'error');} } else if (id == "transferFrom") {const argument = getElementValues(['transferFromFrom', 'transferFromTo', 'transferFromValue']);if (argument) {const transactionHash = contractInstance.transferFrom(argument[0], argument[1],argument[2], { from: web3.eth.accounts[1] });if (transactionHash) setElementText("transferFromResult", 'true');else setElementText("transferFromResult", 'error');} } else {const argument = getElementValues(['balanceOfOwner']);if (argument) {const result = contractInstance.balanceOf.call(argument[0]).toString(); setElementText("balanceOfResult", result);}}
}

5、部署流程及操作演示

首先需要在 MetaMask 中导入 Ganache 私有链上的账户,以第一个为例,
在这里插入图片描述
复制第一个地址的私钥导入 MetaMask 中。
在这里插入图片描述
在这里还需要在 MetaMask 的设置中手动添加 Ganache 的私有链网络,基本的信息都可以在 Ganache 首界面找到,添加好切换至新添加的网络。
在这里插入图片描述
在这里插入图片描述
打开在线版的 Remix 导入前面示例的 solidity 代码, 连接刚刚创建好的 MetaMask 账户
在这里插入图片描述
需要在 Remix 的编译选项中把 Advanced Configurations 中的 EVM VERSION 改为跟 Ganache 的配置一致才能运行智能合约。
在这里插入图片描述
在这里插入图片描述
否则会报错(Gas estimation errored with the following message (see below). The transactionexecution will likely fail. Do you want to force sending?
在这里插入图片描述
输入初始化信息进行部署
在这里插入图片描述
复制部署好的合约地址 和 abi 到 web3.js 的代码中, 如下所示
在这里插入图片描述
在这里插入图片描述
给 fromAccount 账户锻造 200 个代币用于功能的正常运行
在这里插入图片描述
在前端页面输入 fromAccount 账户地址可以看到显示刚才锻造的 200 个代币。
在这里插入图片描述
至此一个简单的 Dapp 的搭建和相关操作就完成了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/587641.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea构建maven项目报错的解决

使用idea创建了一个新的spring项目&#xff0c;maven配置完毕后&#xff0c;报错&#xff0c;引用的依赖不存在。 控制台报错信息如下&#xff1a; 通过查询资料&#xff0c;发现是阿里云的maven仓库中没有这个版本的jar包&#xff0c;导入无法引用到对应的依赖。 解决方法就是…

01 HAL库点亮LED灯

引言&#xff1a;本专题采取的开发平台是stm32cubeIDE&#xff0c; 文章后面会后提供 一 、 LED简介 LED&#xff08;Light Emitting Diode&#xff09;是一种半导体发光器件&#xff0c;能够将电能直接转化为光能的电子元件。它具有体积小、功耗低、寿命长等特点&#xff0c;广…

接入Cloudflare后Nginx和Django获取用户真实IP的办法

可以用Nginx的real_ip的相关命令来实现这个需求。 01-real_ip命令集详解 real_ip命令的使用分为两个步骤: 01-1-设置从哪些代理IP获取真实IP 第1个步骤&#xff1a;通过set_real_ip_from命令设置从哪些代理IP请求获取真实的IP,比如下面的命令&#xff1a; set_real_ip_from…

Navicat for MySQL 创建函数——报错1418

解决方法 1查看是否开启了创建函数的功能 输入下面语句查看是否开启了创建函数的功能 show variables like %func%; 下面为创建函数功能为开启的查询结果 如果不是上面的结果可以用下面的语句修改为开启 set GLOBAL log_bin_trust_function_creatorstrue; //或 set GLOBAL …

【一分钟】ThinkPHP v6.0 (poc-yaml-thinkphp-v6-file-write)环境复现及poc解析

写在前面 一分钟表示是非常短的文章&#xff0c;只会做简单的描述。旨在用较短的时间获取有用的信息 环境下载 官方环境下载器&#xff1a;https://getcomposer.org/Composer-Setup.exe 下载文档时可以设置代理&#xff0c;不然下载不上&#xff0c;你懂的 下载成功 cmd cd…

Redis经典五大类型源码及底层实现(二)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

数据结构:第7章:查找(复习)

顺序查找&#xff1a; ASL 折半查找&#xff1a; 这里 j 表示 二叉查找树的第 j 层 二叉排序树&#xff1a; 二叉排序树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;是一种特殊的二叉树&#xff0c;定义&#xff1a; 对于二叉排序树的每个节点&#xff0c;…

全球电商平台API数据稳定接入

API是什么&#xff1f; API就是接口&#xff0c;就是通道&#xff0c;负责一个程序和其他软件的沟通&#xff0c;本质是预先定义的函数。”比如&#xff1a;电脑需要调用手机里面的信息&#xff0c;这时候你会拿一根数据线将电脑手机连接起来&#xff0c;电脑和手机上连接数据…

Linux学习笔记(一)

如果有自己的物理服务器请先查看[这篇文章](https://blog.csdn.net/yasinawolaopo/article/details/132391128)文章目录 网卡配置Linux基础指令ls:列出目录内容cd(mkdir.rmkdir): 切换文件夹(创建,删除操作)cp:复制文件或目录mv:文件/文件夹移动cat:查看文件vi:文件查看编辑man…

二进制文件分割器

二进制文件分割器 时间: 2023.12.29 作者: FlameCyclone 自己写的一个能方便分割文件的小工具 使用说明 输出文件名 输出文件名规则前缀文件名开始固定名称序号(10/16进制显示, 宽度以输出最大序号为准)分割范围(16进制显示, 宽度以输出最大范围为准)CRC32校验码8字符组成…

touchHLE实战之游戏

前面推荐了touchHLE&#xff0c;号称可以玩旧的IOS游戏&#xff0c;但是国外还是管理的很严格的&#xff0c;一直没有找到合适的游戏文件测试。最近&#xff0c;发现官网上公布了开发者赠送的一款游戏&#xff0c;试了下完美运行。 看到国外贴吧reddit上有人推荐可用的ipa资源&…

蓝桥杯C/C++程序设计——成绩统计

题目描述 小蓝给学生们组织了一场考试&#xff0c;卷面总分为 100 分&#xff0c;每个学生的得分都是一个 0 到 100 的整数。 如果得分至少是 60 分&#xff0c;则称为及格。如果得分至少为 85 分&#xff0c;则称为优秀。 请计算及格率和优秀率&#xff0c;用百分数表示&am…

不同语言告别2023,迎接2024

一、序言 1.一名合格的程序员&#xff0c;始于Hello World&#xff0c;终于Hello World&#xff0c;用不同语言表达2023最后一天。 2.在这一年里&#xff0c;博主新接触了VUE、Python、人工智能、JAVA的框架SprinBoot、微服务等&#xff0c;然后一路来感谢大家的支持&#xf…

ClickHouse基础知识(一):ClickHouse 入门

1. ClickHouse 入门 ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库&#xff08;DBMS&#xff09;&#xff0c;使用 C 语言编写&#xff0c;主要用于在线分析处理查询&#xff08;OLAP&#xff09;&#xff0c;能够使用 SQL 查询实时生成分析数据报告。 2. Cl…

python使用selenium控制浏览器进行爬虫

这里以谷歌浏览器为例&#xff0c;需要安装一下chromedriver&#xff0c;其他浏览器也有相对应的driver&#xff0c;chromedriver下载地址&#xff1a;https://googlechromelabs.github.io/chrome-for-testing/ 然后是打开python环境安装一下依赖pip install selenium&#xf…

【低代码平台】10个开源免费Airtable 的替代方案

Airtable是一个易于使用的简单低代码平台&#xff0c;有助于团队协作管理复杂的数据表&#xff0c;并创建定制的工作流程。把它想象成一个类固醇上的云电子表格。 Airtable还简化了数据输入过程&#xff0c;连接和集成第三方服务和应用程序&#xff0c;并提供了许多数据导入/导…

毅速:3D打印技术传统模具行业影响深远

随着3D打印技术的不断发展和完善&#xff0c;一系列的优势使其在模具制造领域的应用越来越广泛&#xff0c;这一技术在模具行业的应用将为整个行业带来变革。 首先&#xff0c;3D打印技术将大幅提高模具制造的精度和效率。传统的模具制造过程中&#xff0c;由于加工设备的限制和…

gitee(码云)仓库内容更新,使用TortoiseGit同步本地仓库和远程仓库

前言&#xff1a; 网上有很多同步仓库教程&#xff0c;但都是git命令行操作。这篇使用TortoiseGit可视化操作同步本地仓库和远程仓库 克隆本地仓库&#xff0c;上传远程仓库&#xff0c;下载TortoiseGit可以看这篇使用gitee&#xff08;码云&#xff09;上传自己的代码&#xf…

Altium Designer20中遇到的问题和解决办法记录

最近二战考完研了&#xff0c;重新拾起之前学的一些项目&#xff0c;最近在优化以前话的四层PCB版的时候发现了在使用AD使碰到一些问题现在记录如下&#xff1a; 1.Altium Designer 中的 Clearance Constraint 错误如何修改 &#xff1a; 我遇到的报错如下&#xff1a;  这…

Vue模板编译

Vue模板编译 Vue生命周期中&#xff0c;在初始化阶段各项工作做完之后调用了vm.$mount方法&#xff0c;该方法的调用标志着初始化阶段的结束和进入下一个阶段&#xff0c;从官方文档给出的生命周期流程图中可以看到&#xff0c;下一个阶段就进入了模板编译阶段(created和befor…