范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Web3割韭菜王牌发币到底是什么?教你基于ERC20开发发币DApp

  互联网的技术日新月异,互联网不断深入人们的生活;
  web3.0将是彻底改变人们生活的互联网形式;
  web3.0使所有网上公民不再受到现有资源积累的限制;
  具有更加平等地获得财富和声誉的机会。
  web3.0会从哪里开始呢?
  本合集文章,授权转载,侵权必究。
  Web 3.0世界系列文章
  来源 : 代码与野兽
  【 Web3 系列文章 】
  NO.1 遇见Web3: 在 Web3 的世界中写下第一行 HelloWorld
  NO.2 全面系统的 Web3 学习路线,助你成为 Web3 开发专家
  NO.3 Web3世界:区块链、比特币、以太坊和智能合约
  NO.4 Remix IDE 使用与 VSCode 搭建 Solidity 开发环境
  NO.5 深入聊聊 Web3 世界中的协议和硬盘:IPFS
  NO.6 一文聊透 Solidity 语法:助你成为智能合约专家
  NO.7 Web3世界:使用 React+ethers.js 开发简单加密钱包
  NO.8 Web3世界:Web3为什么能赚钱?为什么不要All in Web3?
  本文会讲解代币、ERC20 的基本概念,并完成一个包含智能合约、前端、测试、部署的完整 DApp 设计与实现。
  非常适合 Web3 初学者朋友进行学习。
  文中用到的一些主要的工具、框架及技术:solidity:智能合约编程语言。MetaMask:加密钱包。truffle:智能合约开发套件。ganache:本地区块链。react、nextjs:前端UI库/框架。chakra、tailwindcss:组件库/CSS框架。wagmi、ethersjs:JS 与智能合约交互 SDK。
  注意:文中不会涉及这些工具、框架、技术的基本安装及使用。
  完成效果如下:
  基本概念什么是Token/代币/通证?
  这里指的代币是以太坊平台的代币,其他平台的代币在概念上可能略有出入。
  除了以太坊平台有代币的概念外,很多模仿以太坊的平台也都有代币的概念,比如 BSC 和 polygon 等。
  代币,英文是 Token,顾名思义就是代表某种东西的货币。它可以表示任何东西:
  像人民币一样的法币。黄金。石油。股份资产。游戏道具。积分。门票。以及更多的东西...
  代币唯一不能代表的东西就是 gas 费。
  代币除了代币以外,还有另一个名字,叫做通证。所谓通证,也就是通用的证明。你持有这个通证,就可以证明你拥有某件东西或者某项权益。这和中国成立初期的粮票、布票是一个道理。
  现在我们明白了,虽然它有三种称呼,但其实是一个意思,文中通称为代币。
  在代码的角度上,代币就是一份智能合约,它负责提供查账、转账、记账等功能,没有什么特殊。
  最后扩展一点儿小知识。
  比特币和以太币是代币吗?可以说是,但和通常意义上的代币还是有些区别。我们一般会称呼为比特币和以太坊这种自己拥有区块链的代币为「币」。而除了比特币以外的币,我们还会称为「替代币」。没有自己的区块链,依赖其他区块链的币,我们称为「代币」。这些名词是每一个玩币的人都应该清楚的。什么是 ERC、EIP 和 ERC20?
  ERC 是 Ethereum Request for Comment 的缩写,也就是以太坊改进建议。提交 ERC 后,以太坊社区会对这个草案进行评估,最终会接受或者拒绝该建议。
  如果接受的话,ERC 会被确认为 EIP。
  EIP 是 Ethereum Improvement Proposals 的缩写,也就是被接纳的以太坊改进建议。
  ERC 是按照时间顺序从 1 开始递增的,ERC 20 就是第 20 个建议。
  在讲 ERC20 之前,我们先来看下发行代币过程中存在的问题。
  我们上面讲过,代币就是智能合约,智能合约就是代码。虽然代币合约都是做查账、转账、记账这几件主要的事情的,但在没有规范约束的情况下,每种代币的实现可能都是不同的。
  比如 Pig 币的转账函数是 t,参数顺序是余额、收款人;Cat 币的转账函数是 tr,参数顺序是收款人、余额。虽然各自都是没问题的,但那这样很多应用来集成他们就变得非常麻烦了,这会导致有多少种代币就要集成多少次。特别是交易所和钱包这类应用。
  ERC20 是关于代币的建议,由以太坊联合创始人 Vitalik 在 2015 年 6 月提出。它是一个简单的接口,允许开发者在以太坊区块链上发行自己的代币,并可以与第三方应用集成。
  EIP 20 的地址:eips.ethereum.org/EIPS/eip-20
  既然是接口,那就是一种规范约束。所有人都应该按照这个接口去实现自己的代币合约。
  如果你不按照这个规范实现你的代币合约,那么你的代币在集成到第三方应用时就会无法识别,比如在 MetaMask 中不能正常显示代币名称、余额等。
  代币的价值很依赖流通性,如果你的代币不能通用、不能流通的话,那么基本上就失去了代币的价值。
  所以发行代币,要按照 ERC20 接口去实现合约。
  截至本文写作时间(2023/1/4),以太坊上的 ERC20 代币有将近 74 万种,BSC 上的 ERC20 代币有将近 300 万种。从这些数字上足以看出 ERC20 对促进代币发展的过程中提供的重要作用。
  插一句,BSC 就是币安智能链,因为以太坊交易的 gas 费太贵,BSC 就模仿以太坊做了它们自己的平台,但 gas 相比以太坊少很多,所以吸引了很多用户,后面顺理成章地发展起来了。ERC20 接口介绍
  ERC20 接口规定了 9 个方法和 2 个事件。
  方法:function name() public view returns (string) function symbol() public view returns (string) function decimals() public view returns (uint8) function totalSupply() public view returns (uint256) function balanceOf(address _owner) public view returns (uint256 balance) function transfer(address _to, uint256 _value) public returns (bool success) function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) function approve(address _spender, uint256 _value) public returns (bool success) function allowance(address _owner, address _spender) public view returns (uint256 remaining)
  事件:event Transfer(address indexed _from, address indexed _to, uint256 _value) event Approval(address indexed _owner, address indexed _spender, uint256 _value)
  我们详细讲解一下它们的作用。name:返回代币名称,比如我创建一个 Noah 币,那么就返回 "Noah"。symbol:返回代币符号,比如 Noah 币的符号是 NH,那么就返回 "NH"。也可以叫做代币代号。decimals:返回代币使用的小数点位数,代币会以代币数量除以这个值给用户展示。也就是精度。通常都会使用 18。totalSupply:返回代币发行总量,比如 Noah 币只发行 10000 个,那就返回 10000。balanceOf:返回指定账户的余额。transfer:将指定数量的代币转入指定的地址中,并需要触发 Transfer 事件。transferFrom:将指定数量的代币从一个指定的地址转到另一个指定的地址。这通常被称为提币,但依赖授权。approve:允许指定地址可以分多次从你的账户中提取代币,最多不超过指定的金额。并需要触发 Approval 事件,这也就是授权。allowance:查询指定地址给另一个指定地址的授权代币额度。
  我们可以将它们分为三类,查询、转账、授权:查询
  查询类方法有:name、symbol、decimals、totalSupply、balanceOf。
  其中 name、symbol 和 decimals 都是可选的,因为它们没有具体的功能。但建议是要全部实现。
  totalSupply 和 balanceOf 分别是发行总量和查余额,很容易理解。转账
  转账方法有:transfer。
  它可以将你账户上的代币转给另一个账户,也很容易理解。授权
  授权方法有:transferFrom、approve 和 allowance。
  这三个函数可能比较难理解。
  我再举个例子来详细讲一下授权这块内容。
  假设我是一家游戏平台(游戏平台也是一个地址,和用户没区别),玩家张三完成了我的任务,我奖励他 50 个代币。但我并不会直接转账到他的账户,而是在授权账本上记下来,玩家张三可以使用我的 50 个代币。
  李四是个游戏商人,贩卖游戏道具。张三要在李四手里买一个价值 30 个代币的道具,就可以使用平台的代币支付给李四。而这个代币可能也不会直接打到李四的账户上,和上面的玩法一样,我也在授权账本上记下,允许李四使用我的 30 个代币,同时把张三原来那 50 个代币的账户改为 20 个代币。
  这就是授权的玩法,对应的实现就是:
  游戏平台给玩家授权代币:approve。
  查询玩家在游戏平台的授权代币余额:allowance。
  玩家使用平台授权的代币进行交易:transferFrom。
  当然这只是我举例的一个场景,授权的玩法可以应用在更多的场景中。代码实现实现 ERC20 接口的智能合约
  实现 ERC20 是很多刚接触智能合约的小伙伴都需要学习的内容。
  你可能需要使用 VSCode 或者 Remix 作为编辑器来写 Solidity 代码。这部分内容就不多讲了。
  因为一些特殊的原因,这里我选择 VSCode。
  我会使用 truffle 来创建项目。
  它可以帮我们对合约进行编译和部署。
  运行命令创建项目:mkdir noth-token-contract cd noth-token-contract truffle init
  创建 contracts/IERC20.sol 文件,定义 IERC20 接口。// SPDX-License-Identifier: MIT  pragma solidity ^0.8.0;  interface IERC20 {     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);      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);      event Transfer(address indexed _from, address indexed _to, uint256 _value);      event Approval(         address indexed _owner,         address indexed _spender,         uint256 _value     ); }
  再创建 contracts/NoahToken.sol 文件,实现 IERC20 接口。// SPDX-License-Identifier: MIT  pragma solidity ^0.8.0;  import "./IERC20.sol";  contract NoahToken is IERC20 {     string private _name; // 代币名称     string private _symbol; // 代币代号     uint8 private _decimals; // 代币精度     uint256 private _totalSupply; // 代币发行总量     mapping(address => uint256) private _balances; // 账本     mapping(address => mapping(address => uint256)) private _allowance; // 授权记录     address public owner; // 合约发布者      constructor(         string memory _initName,         string memory _initSymbol,         uint8 _initDecimals,         uint256 _initTotalSupply     ) {         // 发布合约时设置代币名称、代号、精度和发行总量         _name = _initName;         _symbol = _initSymbol;         _decimals = _initDecimals;         _totalSupply = _initTotalSupply;         owner = msg.sender;         // 在合约部署时把所有的代币发行给合约发布者         _balances[owner] = _initTotalSupply;     }      function name() external view override returns (string memory) {         return _name;     }      function symbol() external view override returns (string memory) {         return _symbol;     }      function decimals() external view override returns (uint8) {         return _decimals;     }      function totalSupply() external view override returns (uint256) {         return _totalSupply;     }      function balanceOf(address _owner)         external         view         override         returns (uint256 balance)     {         return _balances[_owner];     }      function transfer(address _to, uint256 _value)         external         override         returns (bool success)     {         // 检查发送者余额是否足够         require(_balances[msg.sender] >= _value, "Insufficient balance");         // 扣除发送者余额         _balances[msg.sender] -= _value;         // 增加接收者余额         _balances[_to] += _value;         // 触发转账事件         emit Transfer(msg.sender, _to, _value);         return true;     }      function transferFrom(         address _from,         address _to,         uint256 _value     ) external override returns (bool success) {         // 检查发送者余额是否足够         require(_balances[_from] >= _value, "Insufficient balance");         // 检查授权额度是否足够         require(             _allowance[_from][msg.sender] >= _value,             "Insufficient allowance"         );         // 扣除发送者余额         _balances[_from] -= _value;         // 增加接收者余额         _balances[_to] += _value;         // 扣除授权额度         _allowance[_from][msg.sender] -= _value;         // 触发转账事件         emit Transfer(_from, _to, _value);         return true;     }      function approve(address _spender, uint256 _value)         external         override         returns (bool success)     {         // 设置授权额度         _allowance[msg.sender][_spender] = _value;         // 触发授权事件         emit Approval(msg.sender, _spender, _value);         return true;     }      function allowance(address _owner, address _spender)         external         view         override         returns (uint256 remaining)     {         return _allowance[_owner][_spender];     } }
  具体代码的作用我都加到注释中了,就不再多赘述。
  在合约编写完成之后,我们需要在本地进行测试、编译、部署。使用 truffle 测试智能合约
  truffle 支持通过代码对智能合约进行测试。目前支持 JavaScript 和 Solidity 两种语言,但 JavaScript 更灵活,也更流行。这里选择 JavaScript 进行测试。
  创建 test/token.js 文件,该文件是测试文件。测试 balanceOf 与 transfer 函数
  truffle 使用 Mocha 和 Chai 这两个库作为断言库,但略有不同。
  首先应该使用 contract 函数而不是 describe 函数。
  contract 函数会传递一个默认参数,它会提供一组可用的账户。const NoahToken = artifacts.require("NoahToken");  contract("Token", (accounts) => {   const [alice, bob] = accounts;    it("balanceOf", async () => {     // 发 Noah 币,发行 1024 个     const noahTokenInstance = await NoahToken.new("noah", "NOAH", 0, "1024", { from: alice });     // 查看 alice 的余额是否是 1024     const result = await noahTokenInstance.balanceOf(alice);     assert.equal(result.valueOf().words[0], 1024, "1024 wasn"t in alice");   });    it("transfer", async () => {     // 发 Noah 币,发行 1024 个     const noahTokenInstance = await NoahToken.new("noah", "NOAH", 0, "1024", { from: alice });     // alice 将 1 个 Noah 币转给 bob     await noahTokenInstance.transfer(bob, 1, { from: alice });     // 查看 alice 的余额是否是 1023     let aliceBalanceResult = await noahTokenInstance.balanceOf(alice);     assert.equal(aliceBalanceResult.valueOf().words[0], 1023, "1023 wasn"t in alice");     // 查看 bob 的余额是否是 1     let bobBalanceResult = await noahTokenInstance.balanceOf(bob);     assert.equal(bobBalanceResult.valueOf().words[0], 1, "1 wasn"t in bob");      // bob 将 1 个 Noah 币转给 alice     await noahTokenInstance.transfer(alice, 1, { from: bob });     // 查看 alice 的余额是否是 1024     aliceBalanceResult = await noahTokenInstance.balanceOf(alice);     assert.equal(aliceBalanceResult.valueOf().words[0], 1024, "1024 wasn"t in alice");     // 查看 bob 的余额是否是 0     bobBalanceResult = await noahTokenInstance.balanceOf(bob);     assert.equal(bobBalanceResult.valueOf().words[0], 0, "0 wasn"t in bob");   }); });
  代码中有详尽的注释,就不多赘述了。其他 function 也可以用这种方式进行测试。
  编写完成后运行命令:truffle test ./test/token.js
  全部 pass 即可通过。
  使用 ganache 本地部署智能合约
  除了代码测试外,我们通常还需要将合约部署到开发环境,和前端代码进行集成联调。
  我使用 ganache 部署智能合约,它会在本地运行一个区块链。配置 truffle-config.js 和 migration 文件
  首先在项目中对 truffle-config.js 文件进行修改,添加 development 环境的相关配置。{   "network": {     development: {      host: "127.0.0.1",     // Localhost (default: none)      port: 7545,            // Standard Ethereum port (default: none)      network_id: "*",       // Any network (default: none)     },   } }
  同时创建一个 migrations/1_NoahToken_migration.js 文件,用于部署。
  内容如下:const NoahToken = artifacts.require("NoahToken");  module.exports = function (deployer) {   deployer.deploy(NoahToken, "noah", "NOAH", 18, "1024000000000000000000"); }
  deployer.deploy 的第一个参数是合约,其余的参数是部署合约传递的参数。部署到 ganache
  最后运行 truffle 的编译部署脚本:truffle migrate --network development --f 1
  network 参数是指定的网络环境,truffle 会将合约部署到指定的网络。
  f 参数是指定的部署文件名前缀,truffle 会从这个文件开始迁移。
  稍等片刻就可以在 ganache 的 contracts 中就可以看到这个合约的地址了。
  点进去就可以看到合约的详细信息。
  不过需要注意,ganache 中数字是以十六进制形式进行展示,所以 decimals 和 totalSupply 和我们传入的十进制数字不匹配。
  另一个注意事项是:ganache 中的 mapping 一直存在显示问题,永远都显示 0 items。这个 Bug 存在时间超过了一年。记得我刚用 Ganache 的时候,一度怀疑是我的合约写得有问题,在这个问题上折腾了一天,记忆犹新。遗憾的是,一年多过去了,ganache 还没有修复这个 Bug。配置 MetaMask 网络
  在测试之前,我们先要配置网络。
  配置信息如下图所示:
  在 MetaMask 中添加代币
  接下来我们要把代币添加到 MetaMask 中。
  在这一步就可以看到代币余额了。
  不过本地的链在 MetaMask 中不能正常显示,部署到链上时是正常的。实现前端 DApp
  前端使用了很多库,我们先来安装这些库。创建 Nextjs 项目
  运行命令创建项目:npx create-next-app
  项目名看你的喜好;编程语言选择 TypeScript。安装 wagmi 和 ethersjs
  与智能合约交互的 SDK 使用 wagmi 和 ethersjs,安装依赖:npm i wagmi ethers安装 chakra
  UI 组件库选择 chakra,安装依赖:npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion安装配置 tailwindcss
  CSS 框架选择 tailwindcss,安装依赖:npm install -D tailwindcss postcss autoprefixer
  初始化配置。npx tailwindcss init -p
  修改 tailwind.config.js 的内容。/** @type {import("tailwindcss").Config} */ module.exports = {   content: [     "./pages/**/*.{js,ts,jsx,tsx}",     "./components/**/*.{js,ts,jsx,tsx}",   ],   theme: {     extend: {},   },   plugins: [], }
  修改 styles/globals.css 的内容。@tailwind base; @tailwind components; @tailwind utilities;
  这些配置比较烦琐,更多内容可以参考官方文档。关闭 React 严格模式
  nextjs 会默认打开 React 的严格模式,但我们用不到,需要关闭。/** @type {import("next").NextConfig} */ const nextConfig = {   reactStrictMode: false, }  module.exports = nextConfig创建 pages/noah-token.tsx 文件
  这是我们代币的操作页面。export default function NoahToken() {   return hello, noah token! }关闭服务端渲染
  接下来我们需要配置 wagmi 的相关配置。但在那之前我们需要关闭 SSR。
  nextjs 的页面默认都是开启 SSR 的,这会导致下面这个 Error。
  触发这个 Error 的原因是服务端的 UI 和客户端不一致。
  关闭服务端渲染很简单。import dynamic from "next/dynamic";  export default dynamic(() => Promise.resolve(NoahToken), { ssr: false });开发功能
  代码分为几个组件:Profile:个人信息。Detail:代币信息。BalanceOf:查余额。Transfer:转账。Allowance:查授权余额。Approve:授权。TransferFrom:通过授权转账。
  代码量较多,不在这里做更多分析。后续考虑单独写一篇专门介绍 wagmi 的文章。
  部署上线将合约部署到 Goeril
  Goeril 是目前最流行的测试网络之一,接下来我们会把 Noah 币部署到这个网络上。
  要部署到 Goeril 首先需要在app.infura.io/ 上面创建一个项目。
  然后可以获取到 API Key。
  回到合约项目中。
  安装两个包:npm i @truffle/hdwallet-provider dotenv
  dotenv 用于读取环境变量。
  创建 .env 文件,写入以下内容:PRIVATE_KEY="xxx" PROJECT_ID="xxx"
  回到 truffle-config.js 文件,添加 goerli 相关配置:require("dotenv").config();  const { PRIVATE_KEY, PROJECT_ID } = process.env;  const HDWalletProvider = require("@truffle/hdwallet-provider");   module.exports = {   // ...   networks: {     // ...     goerli: {       provider: () => new HDWalletProvider(PRIVATE_KEY, `https://goerli.infura.io/v3/${PROJECT_ID}`),       network_id: 5,       // Goerli"s id       confirmations: 2,    // # of confirmations to wait between deployments. (default: 0)       timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)       skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )     }   } }
  最后运行命令:truffle migrate --network goerli --f 1
  稍等片刻,部署成功。
  将 DApp 部署到 Vercel
  部署之前需要将合约地址配置到 vercel 的环境变量中。
  由于之前我就配置好了 Vercel,而且这部分不是重点,就不展开讲了。
  当然,在实际工作中,并不会真正从零实现一个 ERC20 的代币合约,通常会使用 OpenZepplin 这种库来一键发币。本文教学目的是以学习为主。
  只懂得如何发行代币还不够,我们还需要知道如何推广币。推广币最简单的方式就是发布一个免费领币的网站,因为互联网上最不缺的就是羊毛党。
  后面我也会写一篇文章介绍如何开发免费领币网站,也就是水龙头网站。
  Web3 是未来世界一大变数,我们想帮助更多人了解并加入 Web3,如果你对 Web3 感兴趣,记得关注我~
  一起沉淀、一起成长、一起拥抱未来。
  #头条创作挑战赛# #web3#

2月4日手机新爆料第一弹微博知名博主智慧皮卡丘于1月31日下午发表,荣耀此前已经入网了66w快充,只是不清楚会不会是荣耀magic4。如果是荣耀magic4,上一代荣耀magic3也是66w,也算是传承了红米k50系列包揽联发科和高通共四款芯片,卢伟冰你选吧Redmik50宇宙即将发布,它包括标准版电竞版Pro版Pro版,四个版本。标准版使用的是和上一代k40标准版一样的骁龙870处理器,电竞版则使用的是新骁龙8处理器,Pro版使用的孕期孕妇长多少斤才正常?想要长胎不长肉,孕妇要牢记这5点导语怀胎十月,是准妈妈身份转变的过程,准妈妈既有怀孕的欣喜,又有孕期的烦恼,除了浮肿,小腿抽筋等等,她们比较头疼的要数体重的增长了。同事小敏怀孕后,就过上了饭来张口的日子,婆婆每天新生儿臀背部的淤青是怎么造成的?我想你有必要仔细了解一下导语孩子生下来先别扔,养养就好了,这是前段时间在各大社交平台比较火的一句话,因为大多数人的宝宝在刚出生时长得都不尽如人意,皮肤基本都皱成一团,肤色也很黑,还出现了有个宝宝由于刚出生春节假期进入公园景区游玩时这些措施要记牢春节假期日报妹提醒广大市民朋友进入公园景区游玩时防控措施要记牢尽量选择空旷的郊外旅游方式,避开热门景点,实行网上预约错峰出行。提前做好行程规划,准备充足的口罩免洗手消毒剂等防护物资让巧克力变成彩虹色,靠的不是色素,而是物理说起彩虹色的巧克力,你心里想那又有什么好稀奇的。现在有了色素和其他添加剂,想做什么样的巧克力不简单?说起彩虹巧克力,你脑子里出现的是彩虹形状的巧克力(上)还是彩色的巧克力(下)?P地球大气的氮气占比78,氧气仅有21,氮气是氧气的3。7倍地球是一个有着美丽生态的岩质行星,不仅有数百万种生命存在,更是有着智慧生命人类的存在。地球能够诞生生命,演化出人类,跟地球大气层有着密切的关系。大气层的存在可以有效保护地球表面的环3年半亏242亿,烧出70多个世界冠军,成为中国第一的人工智能龙头文JING审核子扬校正知秋2016年,韩国传奇棋手李在石败于谷歌AlphaGo,AI技术获得越来越多关注,并逐渐成为投资风口。得益于资本助力,国内AI企业迅速崛起。而商汤科技无疑是美媒建议火箭跟雄鹿合作,74新星或加盟,休城两将重返老东家?即将到来的截止日,是联盟各支球队本赛季最后一次大规模调整阵容的机会,处于重建期的休斯顿火箭,仍然在积极兜售几名主力和老将,希望借此收获更多未来资产作为回报。火箭雄鹿方案美媒也闲不住塞尔维亚总统低调预言德约将包揽今年法网温网与美网冠军德约受到总统会见近日,德约科维奇在家乡接受了塞尔维亚总统武契奇的亲切会见。武契奇总统表示塞尔维亚以德约科维奇为荣,感谢他在网球取得无比荣光的荣耀,表示他的成就也代表着塞尔维亚。德约辽宁最新消息!众将已开启恢复训练,高诗岩也在场,势必要夺冠目前各个球队应该都还在放假,不过差不多初三都要开始训练了。而对于辽宁的各个球员来说,他们在初二的时候已经开始了训练。根据曝光的照片来看,我们明显可以看到张镇麟已经出现在了辽宁的训练
Vm虚拟机安装Linux系统教程软件介绍Linux,全称GNULinux,是一套免费使用和自由传播的类UNIX操作系统,是一个基于POSIX和Unix的多用户多任务支持多线程和多CPU的操作系统。它能运行主要的U无苹果设备更新AirPods耳机新选项预约零售店授权服务商IT之家4月12日消息,苹果AirPodsAirPodsPro以及AirPodsMax耳机用户如果想要更新固件,需要连接到iPhoneiPad或者Mac设备进行操作。而对于那些没有新业态吸引年轻人线下消费类岗位增速快央视网消息在今年春风行动中,很多新业态新岗位成为年轻求职者关注的热点,并且随着经济活跃度提高,3月线下消费类岗位的招聘职位数环比增速较高。在成都金牛区的一场招聘会上,互联网公司吸引康利谈最后三罚命中幸好是我来罚球让我旁观我可能都受不了直播吧4月12日讯森林狼今日102108惜败于湖人,赛后,森林狼老将康利接受了媒体采访。谈及自己在常规时间最后一刻,利用三次罚球,扳平比分,将比赛拖入加时赛,康利说道我是这样想的,CBA最丑陋的附加赛!王哲林回来了!上海队真在下一盘大棋打假球,没有职业道德,退钱上海队附加赛第二场客场90比97不敌江苏队,赛后远道而来支持上海队的球迷,个个口吐芬芳,很是不爽。因为上海队有故意输球的嫌疑,打出一场无比丑陋比赛,无形中10款裙子搭配示范,从甜酷风到优雅感,再到浪漫假日风,又美又仙头条创作挑战赛4月就是要穿美美的裙子啊,今天我要为大家分享的就是10款不同的裙子款式,可以适合日常上班时刻的优雅或干练,也能拥有假日风格的女人味,来一起发现好看的裙子款式吧。先为自澳门真正的女首富,脖子戴2亿祖母绿项链,外孙女生日花费上百万在香港一个珠宝展会上,林青霞刘嘉玲何超琼一起出借了自己的部分藏品,引起了市场的关注。其中何超琼一件镶嵌祖母绿翡翠的皇冠,引起了很多人的注意。这件皇冠在2019年拍卖会上出现过,当时36氪独家京东零售开启5年来最大组织变革取消事业群制,全面打通自营与POP一场5年来最大的组织变革正在京东零售内部拉开。36氪独家获悉,在4月9日的经营管理会上,京东零售确立了最新的组织架构变革框架,主要包含以下内容取消事业群制,变为事业部制,原事业群负维密4年后宣布回归?天使下半场成为首富退圈养鸡惨遭封杀。时隔4年,维密大秀又要重开了?!短短8个词,充满了回忆杀。那些惊艳时光的维密天使,毕业后的她们现在都如何?脑海里首先闪过,当年手持权杖,如女王般霸气巡游的泰妈。这一幕,霸屏了十余年当人参遇上海鲜,通化市与台州市开启舌尖上的山海互动4月9日,烹然心动以食为媒通化台州美食交流会在通化市举办,交流推介两地各具特色的地域美食和丰富多元的美食文化等,共赴一场舌尖上的山海互动。活动现场播放了通化旅游宣传片通化人参宣传片再增一条烧烤专线!淄博火车站博山老颜神美食古街坐上公交去博山吃小串烧烤喽!近日,细心的市民发现,淄博火车站出现了一趟去往博山的烧烤专车淄博火车站博山老颜神美食古街。据悉,这条线是公交公司新近开通的烧烤专线之一,每天上午9点50