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

目录

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.mzph.cn/news/876862.shtml

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

相关文章

模拟依赖关系和 AI 是Vue.js测试的下一个前沿领域

Vue.js 是一个流行的 JavaScript 框架&#xff0c;因此&#xff0c;确保其组件按预期工作至关重要&#xff1a;有效&#xff0c;更重要的是&#xff0c;可靠。模拟依赖项是最有效的测试方法之一&#xff0c;我们将在本文中发现。 模拟依赖项的必要性 模拟依赖项是一种对测试施加…

个人定制化形象生成,FaceChain最新模型部署

FaceChain是阿里巴巴达摩院推出的一个开源的人物写真和个人数字形象的AI生成框架。 FaceChain利用了Stable Diffusion模型的文生图功能&#xff0c;并结合人像风格化LoRA模型训练及人脸相关感知理解模型&#xff0c;将输入的图片进行训练后推理输出生成个人写真图像。 FaceCh…

Live555源码阅读笔记:哈希表的实现(C++)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

算法日记day 20(中序后序遍历序列构造二叉树|最大、合并、搜索二叉树)

一、中序后序序列构造二叉树 题目&#xff1a; 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,…

使用SpringEvent解决WebUploader大文件上传解耦问题

目录 前言 一、SpringEvent涉及的相关组件 1、 事件&#xff08;Event&#xff09; 2、事件监听器 3、事件发布器 二、WebUploader大文件处理的相关事件分析 1、事件发布的时机 2、事件发布的代码 三、事件监听器及实际的业务处理 1、文件上传处理枚举 2、文件上传监…

Python+selenium web自动化测试知识点合集2

选择元素 对于百度搜索页面&#xff0c;如果我们想自动化输入“selenium”&#xff0c;怎么做呢&#xff1f; 这就是在网页中&#xff0c;操控界面元素。 web界面自动化&#xff0c;要操控元素&#xff0c;首先需要 选择 界面元素 &#xff0c;或者说 定位 界面元素 就是 先…

C++客户端Qt开发——界面优化(QSS)

1.QSS 如果通过QSS设置的样式和通过C代码设置的样式冲突&#xff0c;则QSS优先级更高 ①基本语法 选择器{属性名&#xff1a;属性值; } 例如&#xff1a; QPushButton {color: red; } 1>指定控件设置样式 #include "widget.h" #include "ui_widget.h&qu…

qt--做一个拷贝文件器

一、项目要求 使用线程完善文件拷贝器的操作 主窗口不能假死主窗口进度条必须能动改写文件大小的单位&#xff08;自适应&#xff09; 1TB1024GB 1GB1024MB 1MB1024KB 1KB1024字节 二、所需技术 1.QFileDialog 文件对话框 QFileDialog也继承了QDialog类&#xff0c;直接使用静态…

Redis缓存数据库进阶——Redis与分布式锁(6)

分布式锁简介 1. 什么是分布式锁 分布式锁是一种在分布式系统环境下&#xff0c;通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据&#xff0c;从而避免数据的不一致性。 线程锁&#xff1a; 也被称为互斥锁&#xff08;Mu…

Robot Operating System——内部审查(Introspection)Service

大纲 introspection_service检验Parameter值和类型修改内部审查&#xff08;Introspection&#xff09;功能的状态完整代码 introspection_client完整代码 测试参考资料 在ROS 2&#xff08;Robot Operating System 2&#xff09;中&#xff0c;内部审查&#xff08;Introspect…

【中项】系统集成项目管理工程师-第7章 软硬件系统集成-7.3软件集成

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

python 裁剪图片

情况&#xff1a; 有时候看视频&#xff0c;看到一个漂亮的妹子&#xff0c;按下 Alt PrintScreen 进行截图之后&#xff0c;会把整个屏幕都截图。 需要适当剪裁一下。 每次打开 PS &#xff0c; 也太慢了。 所以写个代码&#xff0c; 快速处理。 效果对比&#xff1a; 原始…

【2025留学】德国留学真的很难毕业吗?为什么大家不来德国留学?

大家好&#xff01;我是德国Viviane&#xff0c;一句话讲自己的背景&#xff1a;本科211&#xff0c;硕士在德国读的电子信息工程。 之前网上一句热梗&#xff1a;“德国留学三年将是你人生五年中最难忘的七年。”确实&#xff0c;德国大学的宽进严出机制&#xff0c;延毕、休…

OOP知识整合----集合

目录 一、定义 1、集合: ( 不限制长度&#xff0c;存多少是多少) 2、集合框架: 二、List集合中常用的方法 1、Boolean add(Object o) 2、void add(int index,Object o) 3、Boolean remove(Object o) 4、Object remove(int index) 5、int size() 6、Boolean conta…

Code Effective学习笔记--第8章防御式编程

这一章聚焦如何通过断言和Java的异常处理机制这些防御式编程的方法来提高程序的健壮性和安全性&#xff0c;这是防御式编程技术的方面。但是健壮性和安全性到了一定的程度其实是矛盾的&#xff0c;健壮性意味着对于任何的输入&#xff0c;程序都不会终止而且都能给出返回&#…

Tftp服务器环境搭建

1、什么是Tftp TFTP&#xff08;Trivial File Transfer Protocol&#xff0c;简单文件传输协议&#xff09;是一种基于UDP&#xff08;User Datagram Protocol&#xff09;的文件传输协议&#xff0c;它被设计为一个非常简单的文件传输机制&#xff0c;特别适用于那些对复杂性有…

make2exe:自动集成测试

模板Makefile&#xff0c;生成多个C/C模块的集成测试程序。

免费【2024】springboot 基于微信小程序的宠物服务中心

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

JavaDS —— 二叉搜索树、哈希表、Map 与 Set

前言 我们将学习 Map 与 Set 这两个接口下的 TreeMap 与 TreeSet &#xff0c;HashMap 与 HashSet &#xff0c;在学习这四个类使用之前&#xff0c;我们需要先学习 二叉搜索树与 哈希表的知识。 二叉搜索树 在学习二叉树的时候&#xff0c;我们就已经了解过二叉搜索树的概念…

酒店智能门锁接口pro[0922]D801 对接收银-SAAS本地化-未来之窗行业应用跨平台架构

proUSB接口函数[0922中性版]-D801 调用函数库&#xff1a; 提供Windows下的32位动态连接库proRFL.DLL&#xff0c;函数使用详细说明 //-----------------------------------------------------------------------------------// 功能&#xff1a;读DLL版本&#xff0c;不涉…