DeFi革命:揭秘去中心化金融的核心技术与实操指南

news2024/11/24 12:24:46

目录

DeFi(去中心化金融)综述

基本特点

第一,DeFi 是无许可的金融

第二,DeFi 是无门槛的金融

第三,DeFi 是无人驾驶的金融

典型商业模式

闪电贷

MakerDAO

面临的挑战

DeFi技术要点

椭圆曲线签名 

EIP-712: Signed Typed Data

三种签名类型

编码示例

1. 交易编码

2. 消息编码

3. 结构化数据编码

签名和验证

EIP-191: Signed Data Standard

关键概念和步骤

版本字节示例

使用示例

任务实操

作业一:结构化数据(Typed Data)签名

方式1:采用 ethers.js

方式2:采用 MetaMask

作业二:实现 ERC20 Permit

安装 OpenZeppelin

编写 ERC20 Permit 合约

编写 ERC721 Permit 合约

相关链接


DeFi(去中心化金融)综述

基本特点

第一,DeFi 是无许可的金融

第二,DeFi 是无门槛的金融

第三,DeFi 是无人驾驶的金融

典型商业模式

闪电贷

"闪电贷"(Flash Loan)是一种去中心化金融(DeFi)技术,允许用户在无需提供任何抵押的情况下,短时间内借用大量资金。这种贷款通常在同一个区块链交易中完成借贷和还款,因此被称为"闪电贷"。它们主要在以太坊等区块链平台上使用,并且具有高度自动化和无需信任的特点。使用闪电贷时,用户必须确保在交易结束时能够偿还贷款本金加上利息,否则交易将失败,所有操作将回滚,就像从未发生过一样。这种贷款方式可以用于套利、杠杆交易等多种金融操作。

闪电贷通过单交易执行、原子性、智能合约保障和回滚机制确保资金安全。虽然有一定风险,但这些机制共同作用,极大地降低了资金被滥用或借款失败的可能性。用户在使用闪电贷时,选择经过审计的合约和谨慎规划交易步骤也是保障资金安全的重要因素。

MakerDAO

MakerDAO 是 DeFi 生态系统中的核心项目,的主要目标是创建并维护一个去中心化的稳定币,称为 Dai,其价值与1美元挂钩。为了实现这一目标,MakerDAO 允许用户通过抵押数字资产(如以太币)来生成 Dai。用户将他们的资产作为抵押品存入智能合约中,然后根据抵押品的价值获得一定比例的 Dai。如果抵押品的价值下降到某个阈值以下,用户需要增加抵押品或偿还部分 Dai 以避免被清算。这个过程确保了 Dai 的稳定性,使其能够维持与美元的挂钩。

面临的挑战

用户使用 DeFi 产品前,必须选择正确的主网和账户,还要在账户里预留足够的 Gas 费,理解这种操作模式需要用户具备一定的知识储备;因为操作不慎,转账导致资金丢失的事例时有发生,因为私钥泄露而资产被盗的事件也常常出现。

DeFi技术要点

椭圆曲线签名 

私匙反推公钥

私匙反推公钥,公钥无法反推私钥

EIP-712: Signed Typed Data

EIP-712 是一个标准化的以太坊提案,旨在定义一种安全、用户友好且可互操作的数据签名方法。这个标准的核心在于结构化数据的签名,它使得签名的数据更具可读性,并能防止重放攻击等潜在的安全问题。

三种签名类型

  1. 交易编码(encode(transaction: T))

    • 使用 RLP 编码(Recursive Length Prefix)对交易进行编码。
    • 这种编码方法常用于对交易进行签名。
  2. 消息编码(encode(message: B^n))

    • 这种签名方式用于签名普通消息。
    • 在哈希计算之前,消息会被前置字符串 "\x19Ethereum Signed Message:\n" 进行处理。
    • 这个前置字符串是为了确保签名的消息与普通交易数据区分开来,防止混淆。
  3. 结构化数据编码(encode(domainSeparator: B^32, message: S))

    • 用于签名结构化数据(如智能合约数据)。
    • 先编码域分隔符(domainSeparator),然后编码具体消息(message)。
    • 前缀为 "\x19\x01",表示这是结构化数据的签名。
    • 这种方式确保数据的完整性和安全性。

编码示例

1. 交易编码

使用 RLP 编码交易数据:

const encodedTransaction = RLP_encode(transaction);
2. 消息编码

对消息进行编码,并添加前缀:

const message = "Hello, Ethereum!";
const encodedMessage = `\x19Ethereum Signed Message:\n${message.length}${message}`;
3. 结构化数据编码

结构化数据编码需要两个部分:域分隔符和消息。以下是一个结构化数据编码的示例:

const domain = {
  name: "MyDApp",
  version: "1",
  chainId: 1,
  verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
};

const types = {
  EIP712Domain: [
    { name: "name", type: "string" },
    { name: "version", type: "string" },
    { name: "chainId", type: "uint256" },
    { name: "verifyingContract", type: "address" }
  ],
  Message: [
    { name: "content", type: "string" },
    { name: "author", type: "address" }
  ]
};

const message = {
  content: "Hello, EIP-712!",
  author: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
};

// 计算域分隔符哈希
const domainSeparator = ethers.utils._TypedDataEncoder.hashDomain(domain);
// 计算消息哈希
const messageHash = ethers.utils._TypedDataEncoder.hashStruct("Message", types.Message, message);

// 最终编码
const encodedData = `\x19\x01${domainSeparator}${messageHash}`;

签名和验证

使用 EIP-712 标准进行签名和验证:

// 使用 ethers.js 进行签名
async function signTypedData() {
  const [signer] = await ethers.getSigners();
  const signature = await signer._signTypedData(domain, types, message);
  console.log("Signature:", signature);
}

// 验证签名
async function verifySignature(signature) {
  const signerAddress = ethers.utils.verifyTypedData(domain, types, message, signature);
  console.log("Signer Address:", signerAddress);
}

signTypedData();

EIP-191: Signed Data Standard

EIP-191 是一个关于签名数据的标准,用于确保签名的数据在区块链上是安全和有效的。它的目的是通过标准化签名数据的格式,防止签名数据在被哈希和验证时发生混淆或被误解。

关键概念和步骤

  1. 签名数据格式: EIP-191 定义了一个数据格式,该格式包含以下部分:

    • 0x19:一个字节的前缀,确保签名的数据不符合 RLP 编码(Recursive Length Prefix)标准,以防止误用。
    • 版本字节:表示数据的版本,以区分不同的签名格式。
    • 版本特定数据:根据版本字节的不同,可能包含额外的结构化数据。
    • 要签名的数据:实际要进行签名的数据。
  2. 前缀的选择

    • 0x19 被选择为前缀,因为在 personal_sign 方法中进行哈希之前,会预置以下字符串:
      "\x19Ethereum Signed Message:\n" + len(message)

      这确保了数据在哈希时具有唯一性和不可篡改性。

  3. 版本字节: 版本字节用于区分不同类型的数据签名:

    • 0x00:数据具有指定的验证者。
    • 0x01:结构化数据(对应 EIP-712 标准)。
    • 0x45:个人签名消息(与 personal_sign 方法兼容)。

版本字节示例

Version ByteEIPDescription
0x00191Data with intended validator
0x01712Structured data
0x45191personal_sign messages

使用示例

为了签名一个消息,假设我们使用 0x01 版本字节(结构化数据):

  1. 准备数据

    const versionByte = '0x01';
    const dataToSign = "My data to sign";
    
  2. 构建签名消息: 将数据按照 EIP-191 的格式进行构建:

    const message = `\x19Ethereum Signed Message:\n${dataToSign.length}${dataToSign}`;
    

  3. 签名消息: 使用以太坊私钥进行签名(假设使用 ethers.js 库):

    const { ethers } = require('ethers');
    const wallet = new ethers.Wallet(privateKey);
    const signature = await wallet.signMessage(message);
    

任务实操

作业一:结构化数据(Typed Data)签名

方式1:采用 ethers.js
  1. 安装 ethers.js

    npm install ethers
  2. 编写签名代码

    const { ethers } = require("ethers");
    
    // 定义域
    const domain = {
      name: "MyDApp",
      version: "1",
      chainId: 1,
      verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
    };
    
    // 定义数据结构
    const types = {
      EIP712Domain: [
        { name: "name", type: "string" },
        { name: "version", type: "string" },
        { name: "chainId", type: "uint256" },
        { name: "verifyingContract", type: "address" }
      ],
      Message: [
        { name: "content", type: "string" },
        { name: "author", type: "address" }
      ]
    };
    
    const message = {
      content: "Hello, EIP-712!",
      author: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
    };
    
    async function signTypedData() {
      const privateKey = "YOUR_PRIVATE_KEY";
      const wallet = new ethers.Wallet(privateKey);
      const signature = await wallet._signTypedData(domain, types, message);
      console.log("Signature:", signature);
    }
    
    signTypedData();
    

  3. 智能合约验证

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
    
    contract VerifySignature {
        using ECDSA for bytes32;
    
        struct Message {
            string content;
            address author;
        }
    
        bytes32 private constant MESSAGE_TYPEHASH = keccak256("Message(string content,address author)");
    
        bytes32 private constant DOMAIN_SEPARATOR = keccak256(abi.encode(
            keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
            keccak256(bytes("MyDApp")),
            keccak256(bytes("1")),
            1,
            0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC
        ));
    
        function hashMessage(Message memory message) public pure returns (bytes32) {
            return keccak256(abi.encode(
                MESSAGE_TYPEHASH,
                keccak256(bytes(message.content)),
                message.author
            ));
        }
    
        function verify(Message memory message, bytes memory signature) public view returns (address) {
            bytes32 digest = keccak256(abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                hashMessage(message)
            ));
            return digest.recover(signature);
        }
    }
    

方式2:采用 MetaMask
  1. 安装 MetaMask

    • 在浏览器中安装 MetaMask 插件,并创建账户。
  2. 编写前端代码

    <!DOCTYPE html>
    <html>
    <head>
        <title>MetaMask Typed Data Signing</title>
        <script src="https://cdn.jsdelivr.net/npm/ethers/dist/ethers.min.js"></script>
    </head>
    <body>
        <button id="sign">Sign Typed Data</button>
        <script>
            const domain = {
                name: "MyDApp",
                version: "1",
                chainId: 1,
                verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
            };
    
            const types = {
                EIP712Domain: [
                    { name: "name", type: "string" },
                    { name: "version", type: "string" },
                    { name: "chainId", type: "uint256" },
                    { name: "verifyingContract", type: "address" }
                ],
                Message: [
                    { name: "content", type: "string" },
                    { name: "author", type: "address" }
                ]
            };
    
            const message = {
                content: "Hello, EIP-712!",
                author: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
            };
    
            document.getElementById('sign').onclick = async function() {
                if (typeof window.ethereum !== 'undefined') {
                    await ethereum.request({ method: 'eth_requestAccounts' });
                    const provider = new ethers.providers.Web3Provider(window.ethereum);
                    const signer = provider.getSigner();
                    const signature = await signer._signTypedData(domain, types, message);
                    console.log("Signature:", signature);
                } else {
                    console.log("MetaMask is not installed");
                }
            };
        </script>
    </body>
    </html>
    

作业二:实现 ERC20 Permit

安装 OpenZeppelin
npm install @openzeppelin/contracts
编写 ERC20 Permit 合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract MyTokenWithPermit is ERC20Permit {
    constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {
        _mint(msg.sender, 1000000 * 10 ** decimals());
    }
}
编写 ERC721 Permit 合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract MyTokenWithPermit is ERC20Permit {
    constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {
        _mint(msg.sender, 1000000 * 10 ** decimals());
    }
}

相关链接

  • Ethers.js SignTypedData
  • MetaMask SignTypedData V4

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

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

相关文章

IS-LM模型的公式与应用解析

IS-LM模型的公式与应用解析 IS-LM模型的核心作用 IS-LM模型是宏观经济学中的一个重要工具&#xff0c;用于分析财政政策和货币政策对经济的影响。IS曲线代表商品市场均衡&#xff0c;LM曲线代表货币市场均衡。两条曲线的交点表示商品市场和货币市场同时达到均衡时的利率和收入…

MySQL笔记3——高级数据查询语句DQL

多表联查 多表联查可以通过连接运算实现&#xff0c;即将多张表通过主外键关系关联在一起进行查询。下图提供了多表联查 时用到的数据库表之间的关系。 等值查询和非等值查询 非等值查询&#xff1a;SELECT * FROM 表1&#xff0c;表2 等值查询&#xff1a;SELECT * FROM 表…

DDR3布线时候的经验总结

摆放BGA下面的滤波电容的时候注意不要让两个电容的电源和地对着头放&#xff0c;手工焊接时候容易短路 阻抗层必须是实心铜皮覆盖&#xff1a; &#xff08;3&#xff09;阻抗线一定要有阻抗参考层&#xff0c;一般以相邻的接地或电源层做参考层&#xff08;如顶层阻抗线&…

人工智能技术的分析与探讨

《人工智能技术的分析与探讨》 摘要&#xff1a; 本文深入探讨了人工智能技术在多个领域的应用&#xff0c;包括智能感知、智能语音、智能问答、智能机器人、智能制造、智能医疗等。详细阐述了这些技术在当前的应用现状和主要场景&#xff0c;展示了一些典型的应用案例&#…

放大电路总结

补充: 只有直流移动时才有Rbe动态等效电阻 从RsUs看进去,实际上不管接了什么东西都能够看成是一个Ri(输入电阻) Ri Ui/Ii Rb//Rbe Ui/Us Ri/(RiRs) Aus (Uo/Ui)*(Ui/Us) Au *Ri/(RiRs) 当前面是一个电压源的信号 我们就需要输入电阻更大 Ro--->输出电阻--->将…

学习C语言第十四天(指针练习)

1.第一题C 2.第二题C 3.第三题 00345 short类型解引用一次访问两个字节 4.第四题 6&#xff0c;12 5.第五题C 6.第六题 下面代码结果是0x11223300 7.第七题 int main() {int a 0;int n 0;scanf("%d %d",&a,&n);int i 0;int k 0;int sum 0;for (i 0;…

创维汽车滁州永通体验中心开业仪式暨超充车型区域上市会圆满成功

2024年7月20日&#xff0c;创维汽车滁州永通体验中心盛大开业&#xff0c;当日&#xff0c;创维汽车市场部经理周世鹏、安徽大区总监王大明等领导参加本次开业盛典&#xff0c;共同见证创维汽车滁州永通体验中心成功落地。 2021年&#xff0c;新能源乘用车高速发展&#xff0c;…

安装CUDA Cudnn Pytorch(GPU版本)步骤

一.先看自己的电脑NVIDIA 支持CUDA版本是多少&#xff1f; 1.打开NVIDIA控制面板 2.点击帮助---系统信息--组件 我的支持CUDA11.6 二.再看支持Pytorch的CUDA版本 三.打开CUDA官网 下载CUDA 11.6 下载好后&#xff0c;安装 选择 自定义 然后安装位置 &#xff08;先去F盘…

MySQL可重复读的隔离机制下是否彻底解决了幻读?

答案&#xff1a;没有彻底解决。 一、什么是幻读&#xff1f; 当同一个查询在不同时间产生不同的结果集时&#xff0c;事务中就会出现幻读问题。 幻读关注的是记录数量的不同。 不可重复读关注的是记录内容的不同。 二、快照读和当前读 InnoDB引擎的默认隔离级别是可重复读&…

vue3 命令运行窗口暴露网络地址,以及修改端口号

一般情况下这里的地址是隐藏的 这里加上 --host 可以暴露网络地址&#xff0c;再加上--port --8080 就可以将端口号修改为8080&#xff08;修改后边的数字就可以修改为你想要的端口号&#xff09;

pytorch-训练自定义数据集实战

目录 1. 步骤2. 加载数据2.1 继承Dataset2.1.1 生成name2label2.1.2 生成image path, label的文件2.1.3 __len__2.1.3 __getitem__2.1.4 数据切分为train、val、test 3. 建立模型4. 训练和测试4. 完整代码 1. 步骤 加载数据创建模型训练和测试迁移学习 2. 加载数据 这里以宝…

打造创新项目:从理念到市场的成功之路

打造创新项目&#xff1a;从理念到市场的成功之路 前言为何创新&#xff1f;如何创新&#xff1f;创新的意义 一、深入市场&#xff0c;洞察行业脉搏二、精准定位&#xff0c;锁定目标市场三、全面评估&#xff0c;确保项目可行性四、创新引领&#xff0c;打造独特卖点五、开放…

二叉树_堆(下卷)

前言 接前面两篇的内容&#xff0c;接着往下讲二叉树_堆相关的内容。 正文 那么&#xff0c;回到冒泡排序与堆排序的比较。 我们知道冒泡排序的时间复杂度为 O ( N 2 ) O(N^2) O(N2)&#xff0c;这个效率是不太好的。 那么&#xff0c;我们的堆排序的时间复杂度如何呢&…

Linux:进程概述(什么是进程、进程控制块PCB、并发与并行、进程的状态、进程的相关命令)

进程概述 (1)What&#xff08;什么是进程&#xff09; 程序&#xff1a;磁盘上的可执行文件&#xff0c;它占用磁盘、是一个静态概念 进程&#xff1a;程序执行之后的状态&#xff0c;占用CPU和内存&#xff0c;是一个动态概念&#xff1b;每一个进程都有一个对应的进程控制块…

云计算复习--分布式存储系统

分布式存储 分布式存储系统是一种将数据分散在多个独立节点上&#xff0c;并通过网络进行数据传输和访问的存储系统 分布式存储的特点&#xff1a;可扩展性、高可用性、容错性、高性能等。分布式存储系统能够水平扩展存储容量和性能&#xff0c;提供持续可用的数据存储服务&am…

【在开发小程序的时候如何排查问题】

在开发小程序的时候如何排查问题 在最近开发小程序的时候&#xff0c;经常出现本地在浏览器中调试没有问题&#xff0c;但是一发布到预发环境就出现各种个样的问题 手机兼用性问题 有时候会出现苹果&#x1f34e;手机键盘弹出&#xff0c;导致ui界面高度出现异常边界问题&#…

for循环打印1~10之间数字

对于for循环之前了解不够的同学可以看之前的我写的介绍 我们这里直接上代码 #include<stdio.h> int main() {int i 0;for (i 1; i < 11; i){printf("%d\n", i);}return 0; }

0724_驱动1 字符设备驱动内部实现

一、字符设备驱动内部实现工作原理 二、分布实现字符设备驱动API接口 分配对象&#xff1a; #include <linux/cdev.h> struct cdev *cdev_alloc(void) 函数功能&#xff1a;分配对象struct cdev *结构体指针 参数&#xff1a;无 返回值&#xff1a;成功返回struct cdev *…

人工智能类——计算机科学与技术

计算机科学与技术是一个非常大的门类。目前计算机科学与技术类招生的专业主要有计算机科学与技术、软件工程、网络工程、信息安全、物联网工程等&#xff0c;后面的几个专业是计算机科学与技术的重要分支&#xff0c;而这个门类的其他分支并没有单列出来一个本科专业&#xff0…

实战|EDU挖掘记录-某学校sql注入挖掘记录

本文来源无问社区&#xff0c;更多实战内容&#xff0c;渗透思路尽在无问社区http://www.wwlib.cn/index.php/artread/artid/9755.html 某大学的办公系统&#xff0c;学号是我从官网下载的优秀人员名单找到的&#xff0c;初始密码为姓名首字母加身份证后六位&#xff0c;我是社…