ERC-3525 开发入门指南

ERC-3525 标准是以太坊社区批准通过的半匀质化通证(Semifungible Token, 亦称为半同质化通证,简称 SFT)标准,由 Solv Protocol 提出。

ERC-3525 标准定义了一类新型的数字资产,具有以下突出优势:

  • 与 ERC-721 标准兼容,具有唯一 ID 和可视化外观,可复用现有的大量 NFT 基础设施;
  • 可拆分、可合并、可计算;
  • 具有账户特征,可以容纳其他数字资产,如 ERC-20 通证、NFT 等,并支持在若干 SFT 之间的转账操作;
  • 可以对外观、功能、资产存储、锁定、转账等各方面进行编程,并且为元数据的结构化进行了特别的优化,以支持动态变化、复杂金融逻辑等高级功能的开发。

由于具有以上的优势,ERC-3525 特别适合用来描述金融工具、数字票证、数字合同等高级数字资产,同时也正在被试用于 Web3 虚拟物品、动态 NFT 艺术品、虚拟装备、真实世界资产(RWA)通证化等领域,得到了非常广泛的关注。

Solv Protocol 已经将 ERC-3525 参考实现开源,为有兴趣了解和快速尝试这一全新通证技术的开发者提供有力的支持。这一参考实现同时以开源代码库和 NPM 模块包的形式提供,开发者可以以此为起点,在这个参考实现代码的基础之上通过改写和扩展,开发自己的 ERC-3525 应用。

本文档引导读者安装、配置和部署 ERC-3525 官方参考实现,并引导读者在此基础上开发一个简单的 ERC-3525 通证合约。这个合约没有任何特别的功能,但开发、测试和部署这个合约的过程却是通用的。开发者如果了解和熟练掌握了这个开发过程,就能够在此基础上开发复杂的、具有业务功能的 ERC-3525 通证合约了。

本文档内容基于 ERC-3525 参考实现 1.1.0 版(2022 年 12 月发布)。

预备知识和技能

ERC-3525 参考实现是基于 Hardhat 框架、以 Solidity 语言为主开发的。我们推荐读者在学习 ERC-3525 开发之前,首先掌握以下知识和技能:

  • Solidity 语言和 EVM 智能合约开发的基本知识
  • Hardhat 智能合约开发框架的基本实用技能

当然,要使用 Hardhat 框架,也必须对于 JavaScript 或者 TypeScript 语言有基本的了解。本文档使用 TypeScript 进行介绍,但对于有经验的开发者来说,基于本文档介绍的内容,很容易可以用 JavaScript 完成相同的工作。

我们推荐对于 Hardhat 不熟悉的读者首先通过 Hardhat 的官方文档 (https://hardhat.org/docs) 来熟悉这一流行的智能合约开发框架。

快速入门

1. 开发环境

建议读者在 macOS 或 Linux 的命令行环境下进行 ERC-3525 开发。如果读者使用 Windows,我们强烈建议读者首先安装 Windows Subsystem for Linux (WSL),然后在 WSL 环境中进行如下操作。

读者可以选择自己喜欢的任何一种代码编辑工具来编写代码,但我们推荐使用 Visual Studio Code,因为 Hardhat 的开发者 Nomic Foundation 为 Visual Studio Code 开发了一款 Solidity 插件,可以帮助提升 Solidity 和 Hardhat 开发效率。

此外,Hardhat 开发中大量使用 JavaScript 或者 TypeScript 编写测试用例,Visual Studio Code 本身对于 JavaScript 和 TypeScript 就提供了良好的支持。

2. 创建 Hardhat TypeScript 项目

首先在命令行环境下通过如下命令准备项目目录。本示例项目名称为 erc3525-getting-started。

mkdir erc3525-getting-started
cd erc3525-getting-started
npm init -y
npm install --save-dev hardhat

在命令行输入以下命令(以MacOSX为例)

npx hardhat

将看到以下界面

选择“Create a TypeScript project”后,Hardhat 会提示若干问题,读者直接通过回车选择缺省选项即可。

全部选择完毕后,系统自动执行一系列安装和准备工作。结束后,使用 Visual Studio Code打开目录,你可以看到如下项目结构:

3.引入和安装 ERC-3525 参考实现模块包

下面,通过 npm 命令在当前目录安装 ERC-3525 参考实现


npm install @solvprotocol/erc-3525@latest

由于我们需要用到 OpenZeppelin 的 String 库,因此需要使用以下命令安装 OpenZepplin:


npm install @openzeppelin/contracts@latest

安装完毕之后,可打开 package.json 文件,应该能够看到 @solvprotocol/erc-3525 相关信息,表明已经成功安装。

4. 编写智能合约

为了简单起见,我们规避复杂的业务逻辑,以一个最简单的应用案例来讲解 ERC-3525 的代码开发过程。这个案例中,我们创建一个最简单的 ERC-3525 通证,它只具备 ERC-3525 的基本功能,没有额外的功能。不过我们将为它创建一个“外表”,使它可以用 SVG 动态图像来显示内部的状态。

在 Hardhat 项目创建过程中,自动添加了一个实例代码文件 Lock.sol。本范例中不需要这文件,因此首先请删除 contracts/Lock.sol,并在 contracts 目录中新建文件 ERC3525GettingStarted.sol,代码如下:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/utils/Strings.sol";
import "@solvprotocol/erc-3525/ERC3525.sol";


contract ERC3525GettingStarted is ERC3525 {
    using Strings for uint256;
    address public owner;


    constructor(address owner_) 

        ERC3525("ERC3525GettingStarted", "ERC3525GS", 18) {
        owner = owner_;

    }


   function mint(address to_, uint256 slot_, uint256 amount_) external {

        require(msg.sender == owner, 

            "ERC3525GettingStarted: only owner can mint");

        _mint(to_, slot_, amount_);

    }
}

在以上代码中,我们创建了一个新的合约 ERC3525GettingStarted。这个合约从 ERC3525 参考实现合约中派生,其构造函数直接调用 ERC3525 合约的构造函数,传入合约的全名、符号和小数位数,并为 owner 赋值。我们并且添加了一个 mint() 函数,确保只有 owner 能够铸造这个 ERC-3525 通证。具体的铸造过程,是通过调用 ERC3525 合约当中的 _mint() 实现的,这样我们就复用了 ERC3525 合约的参考实现,得到了一个最简单的 ERC-3525 通证合约。

有了 ERC-3525 的参考实现,很多基本功能都可以直接调用相应的函数实现,开发者可以只聚焦于业务逻辑和创新功能,这样就大大简化了相关的开发。

代码编写完毕之后,在命令行执行以下命令进行编译:


npx hardhat compile

编译成功结果如下:

5. 编写测试用例

使用 Hardhat 框架开发智能合约的主要好处之一是可以进行自动化测试。下面我们介绍如何使用 Hardhat 的测试框架对 ERC3525GettingStarted 合约进行自动化测试。

测试代码集中在 test 目录下。同样,我们首先删除 test/Lock.ts,然后在 test 目录下新建ERC3525GettingStarted.ts,代码如下:

import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import { ethers } from "hardhat";

describe("ERC3525GettingStarted", function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshot in every test.
  async function deployGettingStartedFixture() {

    // Contracts are deployed using the first signer/account by default
    const [owner, otherAccount] = await ethers.getSigners();

    const GettingStarted = await ethers.getContractFactory(

      "ERC3525GettingStarted");
    const gettingStarted = await GettingStarted.deploy(owner.address);

    return { gettingStarted, owner, otherAccount };
  }

  describe("Deployment", function () {
    it("Should set the right owner", async function () {
      const { gettingStarted, owner } = await loadFixture(

        deployGettingStartedFixture);
      expect(await gettingStarted.owner()).to.equal(owner.address);
    });
  });

  describe("Mintable", function () {
    describe("Validations", function () {
      it("Should revert with not owner", async function () {
        const { gettingStarted, owner, otherAccount } = 

          await loadFixture(deployGettingStartedFixture);
        const slot = 3525
        const value = ethers.utils.parseEther("9.5");
        await expect(

          gettingStarted.connect(otherAccount)

                        .mint(owner.address, slot, value))

                        .to.be.revertedWith(
          "ERC3525GettingStarted: only owner can mint"
        );
      });
    });

    describe("Mint", function () {
      it("Should mint to other account", async function () {
        const { gettingStarted, owner, otherAccount } = 

          await loadFixture(deployGettingStartedFixture);
        const slot = 3525
        const value = await ethers.utils.parseEther("9.5");

        await gettingStarted.mint(otherAccount.address, slot, value);
        expect(await gettingStarted["balanceOf(uint256)"](1)).to.eq(value);
        expect(await gettingStarted.slotOf(1)).to.eq(slot);
        expect(await gettingStarted.ownerOf(1))

                                   .to.eq(otherAccount.address);
      });
    });
  });
});

在上面的测试代码中,我们编写了一个测试夹具和三个测试用例,分别测试了 owner 的正确性、mint 的操作权限和 mint 操作的功能。这些用例遵循了 Hardhat 中编写智能合约测试代码的标准方式,读者可通过 Hardhat 官方文档学习,此处不再赘述。

6.运行测试

下面实际运行测试。方法是在项目主目录执行如下命令:

npx hardhat test

执行结果如下:

这表明我们的智能合约成功通过了所有三个测试用例。

7. 添加 SVG 图像

ERC-3525 最初的设计目标是表达复杂的金融资产,特别是数字票据。既然是数字资产,就必须支持可拆分、可合并,能够像 ERC-20 通证一样进行各种数学计算。另一方面,ERC-3525 超越 ERC-20 的重要一点,就是具有可视化的外在形象,唯有如此才能够向用户传达丰富的信息,使复杂数字资产的复杂性能够被表达出来。这是 ERC-3525 选择兼容 ERC-721 的主要动机。因此,ERC-3525 支持元数据,并且通过从 IERC721Metadata 接口继承而来的 tokenURI 函数返回资源的 URL,或者直接返回图片的内容数据。在 NFT 当中,普遍的做法是将图片放在链外的存储上,然后让 tokenURI 函数返回其 URL。这种设计其实有一个非常大的风险,就是在 NFT 出售以后,控制存储的人可以更换 URL 上的图片,这样买家手里的 NFT 实际上就被篡改了。为了解决这个问题,大多数 NFT 采用了 IPFS 存储,通过哈希值来确保图片资源的唯一性。即使如此,也难以防范一些破坏,比如将 IPFS 上存储的图片资源删除。

ERC-3525 的设计初衷是为了表达金融资产,金融资产的信息非常敏感和重要,决不能被更换和删除。因此,Solv 建议直接将展现层用 SVG 表达,并直接放在链上。具体方法就是让 tokenURI 函数直接返回 SVG 代码片段,而不是指向图像资源的链接。

在 ERC3525GettingStarted 合约中加入以下函数:

     function tokenURI(uint256 tokenId_) public view virtual override returns (string memory) {
        return string(
            abi.encodePacked(
                '<svg width="600" height="600" xmlns="http://www.w3.org/2000/svg">',
                ' <g> <title>Layer 1</title>',
                '  <rect id="svg_1" height="600" width="600" y="0" x="0" stroke="#000" fill="#000000"/>',
                '  <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_2" y="340" x="200" stroke-width="0" stroke="#000" fill="#ffffff">TokenId: ',
                tokenId_.toString(),
                '</text>',
                '  <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_3" y="410" x="200" stroke-width="0" stroke="#000" fill="#ffffff">Balance: ',
                balanceOf(tokenId_).toString(),
                '</text>',
                '  <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_3" y="270" x="200" stroke-width="0" stroke="#000" fill="#ffffff">Slot: ',
                slotOf(tokenId_).toString(),
                '</text>',
                '  <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_4" y="160" x="150" stroke-width="0" stroke="#000" fill="#ffffff">ERC3525 GETTING STARTED</text>',
                ' </g> </svg>'
            )
        );
     }

这将生成一张黑色背景的 SVG 图像,显示如下:

注意,其中 Slot、TokenId 和 Balance 的数值都是直接从 ERC-3525 通证的当前状态中提取的。

8. 部署到本地节点

Hardhat 框架自带一个以太坊本地节点的实现,特别针对开发过程中的需求做了不少优化。我们推荐在开发调试过程中将合约部署到这个节点上。

在deploy目录修改deploy.ts如以下内容:

import { ethers } from "hardhat";

async function main() {
  const GettingStarted = await ethers.getContractFactory("ERC3525GettingStarted");
  const gettingStarted = await GettingStarted.deploy();
  gettingStarted.deployed();

  console.log(`GettingStarted deployed to ${gettingStarted.address}`);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

打开一个新的 Terminal,运行hardhat 内建节点


npx hardhat node

运行结果如下(为节约篇幅,省略其它账号):

在项目主目录执行以下命令:

npx hardhat run --network localhost scripts/deploy.ts

执行成功后将看到如下结果。注意红框的地址部分,后面的交互会用到。

智能合约部署之后,可以通过 hardhat console 命令与之进行交互,这是 Hardhat 节点的一个重要优势,能够大大简化测试和调试阶段的工作。输入以下命令:

npx hardhat console --network localhost

交互指令及结果如下:


~/Sources/erc3525-getting-started$ npx hardhat console --network localhost


Welcome to Node.js v16.18.1.
Type ".help" for more information.
> const GettingStarted=await ethers.getContractFactory("ERC3525GettingStarted")
undefined
> const gettingStarted=await GettingStarted.attach('<此处替换成你部署的地址,也就是上一图的红框处的地址>')
undefined
> const [owner, otherAccount] = await ethers.getSigners()
undefined
> await gettingStarted.mint(otherAccount.address, 3525, 10000)
{
  hash: '0x94d428b32da7e66e8f0e2d48a37ddb9072dca54013130d95779495e1e443df2c',

...
}

读者可以自行输入一些 TypeScript 代码来尝试与智能合约进行交互。

9. 在 Sepolia 测试网络上部署

在开发环境下测试和调试完毕之后,就需要部署到测试链上了。测试链提供了基本等同于主链的运行环境,但在上面进行测试和调试无需缴纳高昂的 gas 费用。另一方面,有些智能合约的功能必须在测试链上才能运行,比如与 Oracle 的交互,在开发用的虚拟节点上是不支持的。我们这个案例非常简单,用不到 Oracle,但是作为一个原则,一个智能合约在上主链之前,一定是要在测试链上运行测试无误才可以。

以太坊已经于 2022 年 9 月 15 日升级到 POS,因此之前几个流行的测试链,如 Ropsten, Rinkeby, Kovan 等已经被废弃。现在主要的两个测试链是 Goerli 和 Sepolia。其中 Goerli 历史较长,完全开放,比较适合于测试复杂的智能合约,而 Sepolia 较新,由一组确定的验证者节点组成,不能随意加入,是当前进行 DApp 开发测试的首选测试链。在这个例子中,我们选择 Sepolia 测试链。

为了部署在 Sepolia 测试链,读者需要通过 https://www.infura.io/ 申请 infura API KEY。我们假定读者已经完成这项工作,下面直接介绍部署的过程。

修改 hardhat.config.ts 如下:

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
  solidity: "0.8.17",
  networks: {
    sepolia: {
      url: process.env.SEPOLIA_URL || `https://sepolia.infura.io/v3/${process.env.INFURA_KEY}`,
      accounts:
        process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
    },
  }
};

export default config;

然后在 Terminal 命令行环境中执行以下命令,设置 infura api key 和 private key:

export INFURA_KEY=<YOUR_INFURA_KEY>; export PRIVATE_KEY=<YOUR_PRIVATE_KEY>;

请注意,将<YOUR_INFURA_KEY> 替换成你申请的 infura API KEY,将 <YOUR_PRIVATE_KEY> 替换成私钥。强烈建议测试网和主网的私钥隔离,不要使用已有的主网私钥。

在 Sepolia 测试网中进行测试需要准备一些测试币,即 Sepolia FaucETH。读者可以到 https://faucet.sepolia.dev/ 去申领一些 FaucETH 以供测试之用。

这些准备工作做好之后,就可以执行脚本进行部署了:

npx hardhat run --network sepolia scripts/deploy.ts

执行成功后,结果如下。请注意红框中的地址,我们将在下一步中使用到。

10. 铸造 ERC3525GettingStarted 通证

下面我们来铸造一个 ERC3525GettingStarted 通证。我们采用的方法是使用 TypeScript 调用合约功能进行通证铸造,这与在 Web3 DApp 开发中的模式是一致的。

首先在 scripts 目录下新建文件 mint.ts ,代码如下:

import { ethers } from "hardhat";

async function main() {
  const [owner] = await ethers.getSigners();
  const GettingStarted = await ethers.getContractFactory("ERC3525GettingStarted");
  const gettingStarted = await GettingStarted.attach('<部署合约地址>');
  const tx = await gettingStarted.mint(owner.address, 3525, 20220905);
  await tx.wait();
  const uri = await gettingStarted.tokenURI(1);
  console.log(uri);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

请注意,将代码中 <部署合约地址> 替换成上一节红框中的地址。

最后,执行以下命令:


npx hardhat run --network sepolia scripts/mint.ts

这样,我们就成功的铸造了一张 ERC3525GettingStarted 通证。

怎么确认这一点呢?可以到 Sepolia Etherscan (https://sepolia.etherscan.io/) 上去查看铸造出来的 token。在浏览器地址栏里输入:

https://sepolia.etherscan.io/address/<部署合约地址>

请注意,将<部署合约地址> 替换成上一节红框中的地址。

恭喜你!如果一切顺利,你就成功的开发和部署第一个 ERC-3525 通证了,可以对它进行各种新的操作了,比如拆分、合并、在两个通证之间转账,等等,赶快尝试一下吧!

本文完整的示例代码参见 GitHub (https://github.com/solv-finance/erc3525-getting-started)。

进阶学习

本教程对于 ERC-3525 半匀质化通证(SFT)应用开发的过程进行了简明扼要的阐述。读者可以由此出发,开发具有丰富功能和高级外观的 SFT。当然,如果想要深入学习 ERC-3525 的知识和开发技术,这只是一个起点,我们推荐您从以下几个方面入手深入学习:

  • 阅读 ERC-3525 白皮书(https://whitepaper.sftlabs.io/SFT%20Whitepaper.pdf
  • 研究 ERC-3525 参考实现 (https://github.com/solv-finance/erc-3525
  • 研究 SFTLabs 官方提供的 Showroom 案例 (https://showroom.sftlabs.io/showroom/
  • 研究 ERC-3525 技术专家开发的以太币现金钞案例 Crypto Notes (https://cryptonotes.fun/)

我们也将继续发表一系列文章和教程来帮助开发者掌握 ERC-3525 技术。

本文转载于网络 如有侵权请联系删除

相关文章

  • 变量:影响2021年的14个科技应用趋势

    当今世界正经历百年未有之大变局,新一轮科技革命和产业变革深入发展。科技创新已经成为关键变量,是推动经济发展、社会进步和构建美好生活的重要引擎。即将过去的一年,新冠疫情突发,一系列的“黑天鹅”和“灰犀牛”事件,给全社会原有的运行轨道带来巨大挑战。我们要于危机中育先机、于变局中开新局,需要转向创新驱动的发展,进一步发挥科技创新的支撑引领作用。 腾讯研究院特别邀请业界众多权威专家给予指导,联合腾讯公司AILab、多媒体实验室、地图平台部、反病毒实验室、科恩实验室、量子实验室、RoboticsX实验室、腾讯CSIG市场部、腾讯CSIG公关部、腾讯云区块链、天衍实验室、未来网络实验室、希波实验室、云鼎实验室、优图实验室、自动驾驶实验室,将共同推出《变量——2021数字科技前沿应用趋势》报告。本文简要呈现了这14个趋势,报告全文将在1月9日正式发布,敬请关注。我们希望,通过年度观察科技创新对全社会经济生态每一步的推动,让科技点亮未来,去满足那些经济社会中的迫切需求,推动更高质量的发展。科技发展的目的和最终归宿是以人为本,这需要“科技向善”去划定科技的边界,从而让新技术的变量,成为帮助每一个普通用户

  • 当我们做后仿时我们究竟在仿些什么(三)

    最近又做了一些后仿debug的工作,有两点是之前两篇没有提到太多的,趁假期有点时间记录下来。标题也照旧,加个三吧。异步电路之间必须消除毛刺之前提到过,数字电路后仿的一个主要目的就是动态验证异步电路时序。异步电路的时序是目前STA工具无法覆盖的。例如异步复位的release是同步事件,其时序是可以靠STA保证的;但是reset是异步事件,它的时序只能靠设计来保证、动态仿真来检查。产生reset的逻辑可能来自多个时钟域,但是在送入异步复位电路的时候,还是需要在设计上做到最终是单独一个时钟域的触发器输出。这样才能保证异步复位信号本身无毛刺。话说回来,现在的代码静态检查工具,已经能够很好的检查出类似的CDC问题了。不过工具虽然强大,但决定工具发挥作用大小的还是站在工具背后的人。所以后仿成了最后一道关口。遗憾的是,在上面这个例子中,后仿这个关口也并不是百分百能截住所有问题。如果后仿侥幸发现了类似的设计问题,真是应该去买张彩票、改行去捞鱼了。为什么捞鱼呢?因为整个设计流程肯定漏洞很多,说不定是一张上好的渔网。X态的问题后仿中,难免会碰到X态的问题,而且波形工具还很贴心的用红色绘制出来,血淋淋的、吓

  • CMU发布船新「论文评审」Python程序,淘汰人工审核,自动给arXiv打分

    晓查发自凹非寺 量子位报道|公众号QbitAI什么?同行评审已经可以被AI程序取代了?就在4月1日,CMU提出了最新的评审标准算法——State-Of-the-ArtReview,SOAR,同时开源了它的Python程序代码。SOAR优化了过去同行评审多目标、大规模分布、延迟极高的缺陷。这篇颠覆现在同行评审制度的论文,已被“国际AI顶会”SIGBOVIK2020收录。SIGBOVIK是在每年4月1日举办的学术会议,只有一天的议程,但是接收的论文都是全球顶尖名校和科技巨头的顶级研究。今年在大会上发表的SOAR智能系统,必将把人工审核机制扫进历史垃圾堆。其他还靠人工审核论文的AI顶会表示瑟瑟发抖。不过大会评委们倒是很开心,因为以后不必做吃力不赚钱的活了。船新的论文评分系统目前同行评审系统存在着无法扩展、运行速度慢、结果不一致的问题。其中,审稿人看稿速度慢是主要问题,另外暴增的博士生数量也不可忽略。从1990年到2010年,授予博士学位的人数呈指数式增长,但是谷歌搜索收录的论文数量在过去几年中却没有太大变化,即使旋转坐标轴也无法保持上升趋势。以上证据表明,要么是现在博士的工作效率比其之前都要

  • setModel 的核心逻辑

    Sent:Friday,March20,20153:28PM为什么UIcontrolcall了setModel,传入了正确的json数据之后,控件在runtime时仍然没有显示任何东西?example:有一个table控件,items绑定如下:某个tablecell绑定信息如下:通过setModel将如下的数据绑定到table上,ProductId在json数据里的值为HT-1020:setModel的执行过程:处理最外层的items绑定,其path是xmlview里指定的/LineItemssPath提示该binding是table最外层的binding,oList为jsondata里table的两条行数据:依次处理tablerow里每个column的绑定:从这里能看出,setModel进行数据绑定的过程中,也是一个把Model里jsondata对应的字段的实际内容写入到bindingInfo这个抽象类的instance里的过程,setModel完全可以看成一个赋值过程:如何判断setModel是否成功执行setModel执行完后,检查调用setModel的controlinstan

  • 斯坦福CS230官方指南:CNN、RNN及使用技巧速查(打印收藏)

    来源:Github,新智元作为全球计算机四大名校之一,斯坦福大学的CS230《深度学习》课程一直受到全球计算机学子和从业人员的热烈欢迎。 CS230授课人为全球著名计算机科学家吴恩达和他的助教KianKatanforoosh。 日前,MIT的AfshineAmidi和斯坦福大学的ShervineAmidi在博客上整理了一份CS230课程知识点的归纳总结,在Reddit上引发热议。评论网友纷纷表示喜大普奔,对于没有条件上课或者没赶上授课时间的人来说,看看这份总结贴也能获益颇丰。这份总结提要基本遵循CS230的授课思路和流程,分三大方面由浅入深地介绍了深度学习的基本概念、网络模型、研究和实验操作方法等。三部分内容分别为:卷积神经网络、递归神经网络、提示与技巧。 本文主要介绍这份总结的第一部分,即CNN部分的内容,后两部分RNN、窍门与技巧部分,读者可自行参看Github上放出的资源:卷积神经网络(CNN)https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-convolutional-neural-networks递归神经网络(

  • 44天连发两次车祸:Waymo自动驾驶车又被撞

    新智元报道来源:ABC15编辑:克雷格【新智元导读】周六晚间,Waymo自动驾驶汽车发生车祸,被一辆私家车撞上。随后,私家车撞上另外3辆车,车祸没有造成人员死亡,但一名儿童受伤入院。跑的好好的,Waymo又被撞了。据ABC15报道,周六晚上10点左右,美国亚利桑那州梅萨(Mesa)发生交通事故,一辆汽车在乡村俱乐部大道南行时,遇红灯没有停车,直接撞上对向的Waymo,随后又撞上3辆私家车,一共5起车辆卷入这次车祸。车祸现场好在没有人在车祸中死亡,有一名儿童受伤入院,肇事司机也受伤并被警方逮捕,其他伤者拒绝入院。被撞的这辆Waymo是一辆自动驾驶货车,Mesa消防和医疗部门的一位发言人称,这辆自动驾驶的货车在事故发生时并未处于自动驾驶模式。自从Waymo将自驾车项目带到钱德勒(Chandler)以来,Waymo车辆在整个凤凰城地区和东南谷地区变得越来越普遍。Waymo的项目启动以来,其车辆已经发生多起事故,不过,警方已经确定车祸都是人为的。跟5月初的那次车祸一样,周六晚上Waymo自动驾驶车显然是“被”车祸。今年5月5日,亚利桑那州钱德勒发生了一起交通事故,Waymo的一辆自动驾驶测试车

  • 腾讯SDN/ODL的探索、创新与开源实践

    "鹅厂网事"由深圳市腾讯计算机系统有限公司技术工程事业群网络平台部运营,我们希望与业界各位志同道合的伙伴交流切磋最新的网络、服务器行业动态信息,同时分享腾讯在网络与服务器领域,规划、运营、研发、服务等层面的实战干货,期待与您的共同成长。 业务带来的挑战 互联网创建之初,以IP技术为核心,网络架构简洁高效,网络设备功能简单,在提供高效的计算机间信息交互的同时,也提供了很好的扩展能力,使得计算机网络迅速从实验室走向了世界。 计算工业迅猛发展,推进了互联网业务的创新繁荣。互联网已经从计算机间信息交互,发展为连接人与信息、人与商品、人与人、人与服务的纽带,已经溶于到我们日常工作、生活与生产中。 腾讯作为一家大型互联网公司,提供众多的互联网业务服务(微信、QQ、QQ空间、游戏、QZone、音乐、视频、新闻、互联网金融、公有云等),并且有着庞大的用户群体(QQ月活跃帐户数8.6亿、微信&Wechat月活跃用户数6.5亿、QQ空间月活跃用户数6.53亿,等)。数据引自《腾讯公布2015年第三季度业绩》。 腾讯快速的业务创新与日益庞大的用户群,对网络也提出了越来越来多的诉求,对底层基础网络设施

  • 腾讯云微服务平台TSF业务日志搜索api接口

    1.接口描述接口请求域名:tsf.tencentcloudapi.com。 业务日志搜索 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:SearchBusinessLog。 Version 是 String 公共参数,本接口取值:2018-03-26。 Region 是 String 公共参数,详见产品支持的地域列表。 ConfigId 是 String 日志配置项ID InstanceIds.N 否 ArrayofString 机器实例ID,不传表示全部实例 StartTime 否 Timestamp 开始时间 EndTime 否 Timestamp 结束时间 Offset 否 Integer 请求偏移量,取值

  • python之字典

    #dict字典,键值对列表,类似java的map集合 dict1={"name":"张三","age":18,"sex":"男"} print(dict1["name"]) #如果访问一个不存在的键 #print(dict1["height"])#会报错 #如果不确定键是否存在,可以用get来获取 print(dict1.get("height"))#返回None #如果我们不想返回None,可以设定一个默认值 print(dict1.get("height","140")) #增 dict1['address']="北京" print(dict1) #修改 dict1['name']="李四" print(dict1['name']) #删除 deldict1["age"]#del是吧这个键值对都删除了 print(dict1)#没有age了 #清空字典 dict1.clear() print(dict1) #查询 dict2={"name":"张三","age":18,"sex":"男"} print(dict2.keys())#所有的键 print(dict2.

  • 007_Orcad运用Excel表格创建复杂元器件

    007_Orcad运用Excel表格创建复杂元器件 以AD9135为例,有88个引脚,如果一个一个输入引脚名,比较慢.用Excel做出引脚列表,比较快捷. 首先需要查询datasheet,用Solidconverterpdf工具把pdf转换成word,然后翻到引脚图那一页,分别复制每边的22个引脚到Excel表格.在excel表格里,去掉引脚号,只保留引脚名. 在Orcad里新建一个元件,画出元件符号,这里引脚序号是逆时针排序的,在用Pinarray添加引脚时,注意+1,-1和起始引脚号. 然后在Orcad里选择所有的引脚,右击,EditProperties.单击引脚属性窗口左上角的方块,就能全部选择,用Ctrl+Insert复制,在Excel里新页面粘贴。 把之前修改好的每组22个引脚名称复制到上一步对应的位置,这里,每修改一组引脚名,替换一组,不容易出错。替换完成,复制替换好的引脚表格,在Orcad的引脚属性页面,单击左上角的方块,用Shift+Inster粘贴。 保存,根据错误提示,把重名的引脚属性作修改,电源类或不连接的DNC加上数字序号。

  • 控制台输出乱码问题

    之前utf-8输出控制台的,只要用"chcp65001"命令即可显示,突然发现显示的还是乱码。 后来发现是因为cmd控制台用了点阵字体,具体原因未知,切换下字体即可。 详细操作步骤: 1cmd.exechcp65001     2字体选择consolas    确定之后再运行程序即可。 另附代码改变本地字符集和字体(c/c++) 1#ifdef_WIN32 2SetConsoleOutputCP(65001); 3CONSOLE_FONT_INFOEXinfo={0};//以下设置字体来支持中文显示。 4info.cbSize=sizeof(info); 5info.dwFontSize.Y=16;//leaveXaszero 6info.FontWeight=FW_NORMAL; 7wcscpy(info.FaceName,L"Consolas"); 8SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE),NULL,&info); 9#endif复制 以上就解决

  • 阿里云-快速搭建LNMP环境(MySQL,Nginx,PHP)

    2.安装MySQL数据库 1. 执行以下命令,下载并安装MySQL官方的YumRepository。 wgethttp://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm yum-yinstallmysql57-community-release-el7-10.noarch.rpm yum-yinstallmysql-community-server复制     2. 执行以下命令,启动MySQL数据库。 3. 执行以下命令,查看MySQL初始密码。 grep"password"/var/log/mysqld.log 复制     4. 执行以下命令,登录数据库。 mysql-uroot-p 复制 5. 执行以下命令,修改MySQL默认密码。 setglobalvalidate_password_policy=0;#修改密码安全策略为低(只校验密码长度,至少8位)。 ALTERUSER'root'@'

  • JavaScript笔记,不定期更新

    Array(6).join("a");会显示什么为什么会显示? 显示"aaaaa"。Array(6)创建拥有6个元素的数组,join("a")是在数组里,每两个数组元素之间插入的字符,六个数组共有5个空隙,即插入5个a,如下面这样: 第1元素a第2元素a第3元素a第4元素a第5元素a第6元素   123456['toString']['length'];结果是什么? 结果为1。Number.toString是一个函数,长度为1。   1587491['toString']()['length'];的结果又是什么? 结果为7,1587491['toString']返回的是函数,并没有返回结果值,再后面加上()就会把返回的函数执行。 1587491['toString']等价于vari="1587491";i.toString。 1587491['toString']()等价于vari="1587491";i.toString()   {}+'a'<{}+'b';结果是什么?为什么? {}+'a'和{}+'b'会转换成数字相加,而结果就是NaN,而NaN

  • js的浏览器判断方法

    使用navigator.userAgent来判断浏览器类型。 1、浏览器版本号函数: varbr=navigator.userAgent.toLowerCase();  varbrowserVer=(br.match(/.+(?:rv|it|ra|ie)[\/:]([\d.]+)/)||[0,'0'])[1];    2、js浏览器判断函数 functionuserBrowser(){    varbrowserName=navigator.userAgent.toLowerCase();    if(/msie/i.test(browserName)&&!/opera/.test(browserName)){      alert("IE");      return;    }elseif(/firefox/i.test(browserName)){

  • Spring Boot Mail QQ企业邮箱

    这里记录一下QQ企业邮箱发邮件问题,因为之前遇到过一种情况是本地测试没问题,结果线上出现问题 Couldn'tconnecttohost,port:smtp.qq.com,25;timeout-1 复制       要使用企业邮箱生成的授权密码.   这里只要是因为QQ邮箱默认端口是465,需要修改为SSL配置   java代码 packagecom.chenpeng.cpeducloud.service.impl; importlombok.extern.slf4j.Slf4j; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.annotation.Value; importorg.springframework.core.io.FileSystemResource; imp

  • 【转】VC调试的时候 “没有调试信息,未加载符号”

    概述调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言。不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件。这里我简要的根据自己的经验列出调试中比较常用的技巧,希望对大家有用。本文约定,在选择菜单时,通过/表示分级菜单,例如File/Open表示顶级菜单File的子菜单Open。  设置为了调试一个程序,首先必须使程序中包含调试信息。一般情况下,一个从AppWizard创建的工程中包含的DebugConfiguration自动包含调试信息,但是是不是Debug版本并不是程序包含调试信息的决定因素,程序设计者可以在任意的Configuration中增加调试信息,包括Release版本。为了增加调试信息,可以按照下述步骤进行: 打开Projectsettings对话框(可以通过快捷键ALT+F7打开,也可以通过IDE菜单Project/Settings打开) 选择C/C++页,Category中选择general,则出现一个DebugInfo下拉列表框,可供选择的调试信息方式包括:  命令行 Projectsettings 说明 无

  • day6-python之面向对象

    123

  • 企业微信-给新客户发送欢迎语(一)(通用欢迎语设置)

      企业微信可以通过在后管配置的方式实现给新客户发送欢迎语,以满足普通场景下发送给新客户欢迎语的需求,但是如果要根据不同的客户发送不同的欢迎语则无法通过这种简单配置的方式来达到目的,需要另行基于企业微信公开的API来实现。下面来说下两种欢迎语(配置通用欢迎语、基于API开发个性化话欢迎语)。 (备注:受限于本人所掌握的资源,本文中的个性化欢迎语只限于理论,并未实操,待后续有资源时再行查漏补缺) 通过配置的方式来配置通用欢迎语   (由管理员或者业务负责人统一配置,配置后,客户将在添加成员为联系人后收到该欢迎语)   1、设置欢迎语:首先你得有个企业微信,登录企业微信管理后台-->客户联系-->加客户-->[欢迎语](设置),设置你的欢迎语     欢迎语可以设置文本、图片、视频、网页、小程序(这里的小程序需要配置添加到企业微信才可以)       2、给客服生成二维码/小程序名片,散播出去以供客户添加客服:客户联系-->加客户-->[联系我],新建联系方式,生成名片   3、客户通过名片添加客服为好友,会收到设定的欢迎语,配置化的欢迎

  • 计算机产生随机数

    tips:本文摘自July新浪博客,感谢作者整理!   C语言/C++中怎样产生随机数 C语言/C++怎样产生随机数:这里要用到的是rand()函数,srand()函数,C语言/C++里没有自带的random(intnumber)函数。 (1)  如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值,范围在0至RAND_MAX间。RAND_MAX定义在stdlib.h,其值为2147483647。例如: #include<stdio.h>#include<stdlib.h>voidmain(){       for(inti=0;i<10;i+)             printf("%d\n",rand());   //printf("%d\n"

  • [SCOI2014]方伯伯的玉米田

    洛谷题目链接 动态规划: 首先,仔细看题目明确一点,如果要拔高,无论怎么拔,拔高的区间右端点一定是$n$,为什么呢? 这样做: $1、$对于区间左边,不会减小以前的最优决策 $2、$对于区间内,两两之间相对高度不会发生变化 $3、$对于区间右边,会减小它们进入最优序列的可能性 所以操作区间在右端点就可以解决第三个问题 那么考虑$dp$: 设$f[i][j]$表示前面$i$个中拔高了$j$次,最多的保留数 状态转移也非常明显:$$f[i][j]=max(f[k][l])+1$$ 显然需要一个可以快速求出二维最大值的数据结构 这里用的树状数组,直接套上模板,查询区间最大值即可 代码: #include<iostream> #include<cstdio> #include<algorithm> #defineN10007 #defineK507 #defineM6000 #definelowbit(x)x&(-x) usingnamespacestd; intn,k,maxn,ans; intval[N],tree[M][K]; voidUpd

  • 龙门金庸之独孤求败

        龙门金庸之独孤求败   原创(Original):曦笑大海(BGSea) 个人论记: 独孤一人求一败可怜天下不可得同伴神雕隐世外不忘衣钵传后人   人物简介:         独孤求败,是金庸笔下最出名却从未出场人物,这个人物的出名之处,一来在于他那极富个性的名字(据估计,多半是他成名后自己改的),二来是他那传说中无敌于天下以致于求一败而不可得的剑术,自号“剑魔”。         纵横江湖三十馀载,杀尽仇寇,败尽英雄,天下更无抗手,无可奈何,惟隐居深谷,以雕为友。此雕与独孤求败长久相处,记得了一些进退扑击的方法,后来以此与杨过过招,启发杨过领悟使重剑法门。杨过认为连当今高手也未提起过,恐怕是百多年前以上的人,且神雕既然名为神雕,那么顾名思义,能活个几百年本就不足为奇。《笑傲江湖》中,是东方不败的师傅,武功和实战能力是金庸小说中最强的人物之一,独孤求败一生境界阶段分

相关推荐

推荐阅读