Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaomeng79 committed Nov 26, 2024
1 parent ce32d83 commit 361ab83
Show file tree
Hide file tree
Showing 12 changed files with 265 additions and 7 deletions.
6 changes: 6 additions & 0 deletions 01语言/1go/6注意点.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ sn3:= struct {
### defer 顺序
后进先出:

### 数组和切片的区别
- 数组是一个长度固定的数据类型,其长度在定义时就已经确定,不能动态改变;切片是一个长度可变的数据类型,其长度在定义时可以为空,也可以指定一个初始长度。
- 数组的内存空间是在定义时分配的,其大小是固定的;切片的内存空间是在运行时动态分配的,其大小是可变的。
- 当数组作为函数参数时,函数操作的是数组的一个副本,不会影响原始数组;当切片作为函数参数时,函数操作的是切片的引用,会影响原始切片。
- 切片还有容量的概念,它指的是分配的内存空间。

### 私有仓库

```shell
Expand Down
3 changes: 2 additions & 1 deletion 01语言/1go/9GPM.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@

表示用于调用的上下文。你可以把它看作在一个单线程上运行代码的调度器的一个本地化版本。它是让我们从N:1调度器转到M:N调度器的重要部分。在运行时代码里,它被叫做P,即处理器(processor)。


### GMP模型
M代表一个工作线程,在M上有一个P和G,P是绑定到M上的,G是通过P的调度获取的,在某一时刻,一个M上只有一个G(g0除外)。在P上拥有一个G队列,里面是已经就绪的G,是可以被调度到线程栈上执行的协程,称为运行队列。

### 为什么需要多个P

Expand Down
12 changes: 12 additions & 0 deletions 02数据存取/1mysql/6优化.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ revoke all privileges on *.* from 'ua'@'%';
```
#### datetime、timestamp 的区别
- 时间范围
- timestamp:是 UTC 时间'1970-01-01 00:00:01' UTC - '2038-01-19 03:14:07' UTC
- datetime:1000-01-01 00:00:00.000000 ~ 9999-12-31 23:59:59.999999
- 时区
- timestamp:存储的是 UTC 时间,所以会有时区的概念,会将客户端插入的时间从当前时区转换为 UTC 再进行存储;查询时,会从 UTC 转换回客户端当前时区再进行返回.
- datetime:没有时区概念,客户端传什么时间就存什么时间,省去了转换时区的步骤.
- 字节数
- 存储的都是二进制而不是字符串
- timestamp:4 个字节
- datetime:5 个字节(有些教程会写 8 个,但官方文档目前 mysql8 中 datetime 是 5 个字节进行存储) 它们在保存小数秒时,都将使用额外的空间(1-3 个字节).
#### join优化
[参考文章](https://www.cnblogs.com/zuochanzi/p/10409752.html)
Expand Down
19 changes: 19 additions & 0 deletions 13区块链/coins/btc.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@
- [比特币开发文档](https://developer.bitcoin.org/reference/rpc/)
- [浏览器](https://btc.com/zh-CN)

## 结构解析
```go
type Transaction struct {
ID []byte //交易ID
Vin []TXInput //输入集合
Vout []TXOutput //输出集合
}
type TXInput struct {
Txid []byte //引用交易的ID
Vout int //引用交易输出的索引,第几个
Signature []byte //签名,输出方私钥签名
PubKey []byte //原始公钥信息,节点会验证签名和引用的输出公钥Hash是否相同
}
type TXOutput struct {
Value int
PubKeyHash []byte
}
```

## 地址计算过程
- 1开头的比特币地址是如何创建的:
- 根据公钥计算hash160;
Expand Down
85 changes: 84 additions & 1 deletion 13区块链/coins/eth.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
# ETH

## 账户
- 外部账户:即普通用户用私钥控制的账户.
- 合约账户:一种拥有合约代码的账户,它不属于任何人,也没有私钥与之对应。

## 账户结构
- 以太坊存储账户数据的数据结构是MPT:Merkle Patricia Tree,它是一种改进的Merkle Tree。当MPT的每个叶子结点的值确定后,计算出的Root Hash就是完全确定的。
- 以太坊就是一个状态机,每个区块通过记录一个stateRoot来表示一个新状态。如果给定某个区块的stateRoot,我们肯定能完全确定所有账户的所有余额等信息。因此,stateRoot就被称为当前的世界状态。
- 每个节点的数据被存放到LevelDB中,节点仅在内存中存储当前活动的一些账户信息。如果需要操作某个不在内存的账户,则会将其从LevelDB加载到内存。如果内存不够,也会将长期不活动的节点从内存中移除,因为将来可以通过节点的路径再次从LevelDB加载。

## 账户数据
一个以太坊账户由4部分数据构成:
- nonce:是一个递增的整数,每发送一次交易,+1,记录的就是交易次数。
- balance:记录的就是账户余额,以wei为单位,1 Ether等于1018wei。
- storageRoot:如果一个账户是合约账户,则storageRoot存储合约相关的状态数据。
- codeHash:存储合约代码的Hash。对于外部账户,这两部分数据都是空。

## 结构
```go
parentHash(上一个区块的Hash);
stateRoot(世界状态);
sha3Uncles:记录引用的叔块,叔块的目的是给予竞争失败的矿工部分奖励,避免出现较长的分叉。;
transactionRoot:记录当前区块所有交易的Root Hash
receiptsRoot:记录当前区块所有交易回执的Root Hash
logsBloom:一个Bloom Filter,用于快速查找Log;
difficulty:挖矿难度值;
number:区块高度,严格递增的整数;
timestamp:区块的时间戳(以秒为单位);
```

### 账户生成方式
- ECDSA算法生成私钥
- keccak256哈希计算公钥
- 十六进制编码
secp256k1椭圆曲线,但和比特币不同的是,以太坊采用非压缩公钥,然后直接对公钥做keccak256哈希,得到32字节的哈希值,取后20字节加上0x前缀即为地址,可以通过大小写字母实现地址的校验。


## 概念
- 智能合约: (Smart Contracts)智能合约是一段存储在以太坊区块链上的代码,它可以自动执行协议的条款。例如,你可以创建一个智能合约来管理众筹活动,当筹款达到目标时,合约会自动将资金转给项目方。
- 以太币 (ETH): 以太坊的原生货币称为以太币(Ether,简称 ETH)。ETH 是用于支付以太坊网络上的交易费用和计算服务的代币。用户需要支付 ETH 来执行智能合约和转账。
Expand Down Expand Up @@ -55,4 +91,51 @@ ETH2.0 按照 epoch 出块,每一个 epoch 有 32 slot,每一个 slot 可以
- eth_gasPrice:获取签名需要的参数 Gas
- 返回值即为签名里面需要的 gasPrice
- eth_sendRawTransaction:发送交易到区块链网络
- 返回值为交易 Hash
- 返回值为交易 Hash

## Gas(汽油)
- [gas追踪](https://etherscan.io/gastracker)
- [ethgasstation](https://ethgasstation.info/)
- 为了保证合约代码的可靠执行(不要永远执行),以太坊给每一个虚拟机指令都标记了一个Gas基本费用,称为gasUsed。
- 消耗CPU比消耗存储便宜,简单计算比复杂计算便宜,读取比写入便宜。
- 因为有if等判断逻辑,不能准确预估gas费,一笔交易,先给出gasPrice和gasLimit,如果执行完成后有剩余,剩余的退还,如果执行过程中消耗殆尽,那么交易执行失败,但已执行的Gas不会退。
- Gas Limit: 在创建这个交易时,允许交易消耗的最大的gas数值,如果交易在实际执行中,所消耗的gas大于了这个值,则交易直接失败,不生效,但是手续费还是需要扣除。单纯的eth转账交易,gas消耗固定为21000。
- Gas Used by Transaction: 交易中真实使用的gas值。在合约中,成功的交易大部分这个数值会小于Gas Limit。
-
- Gas Price是全网用户竞价产生的,它时刻在波动。如果交易少,Gas Price将下降,如果交易多,网络拥堵,则Gas Price将上升。以太坊的Gas价格可以在Etherscan跟踪。

## 转账交易
- Transaction Hash: 0xb940...4ad7,这是交易Hash,即交易的唯一标识;
- Status: Success,表示交易成功;
- From: 0x0FFf...bBc4,交易的发送方;
- To: 0x5b2a...5a46,交易的接收方;
- Value: 1.6912 Ether,交易发送的Ether;
- Gas Price: 82 Gwei,Gas的价格;
- Gas Limit: 21,000,转账交易恰好消耗21000Gas,因此总是21000;
- Usage by Txn: 21,000 (100%),消耗的Gas占比,这里恰好全部消耗完;
- Nonce:0,发送方的nonce,0表示第1笔交易,可避免重放攻击;
- Input Data: 0x,因为是转账交易,没有输入数据,因此为空。

## 合约交易
是指一个外部账号调用某个合约的某个public函数
- From: 0x2329...BA3a,交易的发起方,该地址一定是外部账户;
- To: 0x7a25...488D,交易的接收方,这里地址是一个合约地址;
- Value: 4.5 Ether,即向合约发送4.5 Ether;
- Gas Limit: 152,533,这是交易发起前设定的最大Gas;
- Usage by Txn: 125,290 (82.14%),这是交易实际消耗的Gas;
- Input Data: 0x7ff36ab5...,这是交易的输入数据,其中包含了调用哪个函数,以及传递的参数,解码后可知调用函数是swapExactETHForTokens。


## 交易所提币流程
- 获取热钱包地址和热钱包私钥
- 获取热钱包余额
- 获取gasPrice
- 获取待处理提币条目
- 判断热钱包余额是否足够提币
- 获取热钱包nonce
- 创建提币交易
- 将创建的交易插入待发送队列
- 更改提币条目状态为已生成提币交易



2 changes: 2 additions & 0 deletions 13区块链/coins/polygon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Polygon

96 changes: 96 additions & 0 deletions 13区块链/contract/eth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# ETH

## 合约执行流程
- 当一个合约编写完成并成功编译后,我们就可以把它部署到以太坊上。合约部署后将自动获得一个地址,通过该地址即可访问合约。
-`contract`看作一个类,部署就相当于一个实例化。
- 构造函数在部署合约时就会立刻执行,且仅执行一次。合约部署后就无法调用构造函数。
- 任何外部账户都可以发起对合约的函数调用。如果调用只读方法,因为不改变合约状态,所以任何时刻都可以调用,且不需要签名,也不需要消耗Gas。但如果调用写入方法,就需要签名提交一个交易,并消耗一定的Gas。

## 验证
- 最常用的require()可以断言一个条件,如果断言失败,将抛出错误并中断执行。
- 以太坊合约具备类似数据库事务的特点,如果中途执行失败,则整个合约的状态保持不变。
- 合约如果执行失败,其状态不会发生任何变化,也不会有任何事件发生,仅仅是调用方白白消耗了一定的Gas。
- 检查都必须在合约的函数内部完成。

## 部署
- 测试地址:faucet.egorfine.com或faucet.dimensions.network获取一些测试网的Ether。

## 调用合约
- 页面的JavaScript代码无法直接访问以太坊网络的P2P节点,只能间接通过MetaMask钱包访问;
- 钱包之所以能访问以太坊网络的节点,是因为它们内置了某些公共节点的域名信息;
- 如果用户的浏览器没有安装MetaMask钱包,则页面无法通过钱包读取合约或写入合约。

## Dapp架构如下:

┌───────┐ ┌─────────┐ ┌───────┐
│Wallet │◀────│Web Page │────▶│Server │
└───────┘ └─────────┘ └───────┘
│ │
read│write │read
│ │
┌ ─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─ ┐
▼ ▼
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│Node │────────│Node │────────│Node │
│ └─────┘ └─────┘ └─────┘ │
│ │ │
│ │ ┌─────┐ │ ┌─────┐ │ │
└────│Node │───┴───│Node │────┘
│ └─────┘ └─────┘ │
Ethereum Blockchain
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
为Dapp搭建后端服务器时要严格遵循以下规范:
- 后端服务器只读取合约,不存储任何私钥,因此无法写入合约,保证了安全性;
- 后端服务器要读取合约,就必须连接到P2P节点,要么选择公共的节点服务(例如Infura),要么自己搭建一个以太坊节点(维护的工作量较大);
- 后端服务器应该通过合约产生的日志(即合约运行时触发的event)监听合约的状态变化,而不是定期扫描。监听日志需要通过P2P节点创建Filter并获取Filter返回的日志;
- 后端服务器应该将从日志获取的数据做聚合、缓存,以便前端页面能快速展示相关数据。
因此,设计Dapp时,既要考虑将关键业务逻辑写入合约,又要考虑日志输出有足够的信息让后端服务器能聚合历史数据。前端、后端和合约三方开发必须紧密配合。

## 托管后端服务
- [graph](https://thegraph.com/zh/)
The Graph可以让我们部署一个Graph查询服务,如何定义表结构以及如何更新则由我们提供一个预编译的WASM。整个配置、WASM代码以及查询服务都托管在The Graph中,无需自己搭建服务器,非常方便。

因此,使用Graph的一个完整的DApp架构如下:

┌───────┐
┌───────────│ DApp │───────────┐
│ └───────┘ │
│ read/write query │
│ contract data │
▼ ▼
┌───────┐ ┌───────┐
│Wallet │ │ Graph │
└───────┘ └───────┘
│ ▲
│ sign index │
│ broadcast data │
│ │
│ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ ┌────┐ ┌────┐ ┌────┐ │ │
└──┼▶│Node│ │Node│ ... │Node│───┘
└────┘ └────┘ └────┘ │
│ Ethereum
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

## 安全性
- 加减导致的溢出
- 从Solidity 0.8版本开始,编译器默认就会检查运算溢出,因此,不要使用早期的Solidity编译即可避免溢出问题。
- 条件不满足必须抛出异常回滚交易
- 重入攻击
- 防止重入攻击的方法是一定要在校验通过后立刻更新数据,不要在校验-更新中插入任何可能执行外部代码的逻辑。
-
```solidity
// 先回调再更新的方式会导致重入攻击,即如果callback()调用了外部合约,外部合约回调transfer(),会导致重复转账
function transfer(address recipient, uint256 amount) public returns (bool) {
require(recipient != address(0), "ERC20: transfer to the zero address");
uint256 senderBalance = balanceOf[msg.sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
// 此处调用另一个回调:
callback(msg.sender);
// 更新转账后的额度:
balanceOf[msg.sender] = senderBalance - amount;
balanceOf[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}
```
20 changes: 20 additions & 0 deletions 13区块链/contract/闪兑.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 闪兑

## 概念
- (闪电兑换)不同于交易平台订单撮合模式,它是通过智能合约实现的去中心化币币兑换系统。
- 可以把闪兑理解成一个 24 小时无人值守的 ATM 机,用户通过简单的操作,就可以实现不同 Token 间的兑换操作。

## 闪兑功能实现原理
- 柜台报价模式
- 首先向柜台进行询价,柜台会提供一个有竞争力的价格(不同 Token 间的汇率)。如果用户接受了柜台的报价,就可以快速交易,从而完成不同 Token 的兑换操作。
- 闪兑服务商要接入多个市商来提升 Token 的市场流动性。
- 用户和市商之间交易的 Token 不需要充值到闪兑服务商进行代管,交易中支出和收入的 Token 都由智能合约直接结算到用户的钱包中。
- 用户确认订单价格后,发起下单动作,在下单过程中对该订单进行签名,签名后的订单会发送到智能合约,智能合约检查用户和市商双方的 Token 余额,并验证双方签名信息,当所有条件满足后,智能合约就会完成用户和市商之间的 Token 兑换。

## 闪兑的优势
- 在钱包即可完成。
- 交易价格所见即所得,不会出现无法成交的情况。
- 交易对更多,交易更方便。



18 changes: 18 additions & 0 deletions 13区块链/交易所钱包.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 交易所钱包

## 热钱包
- 系统由用户充值钱包、归集钱包、提现钱包、手续费钱包等组成
- 用户充值钱包:用户需要向交易所进行代币充值 ,需要为每一名用户分配一个地址,用于充值代币,其私钥保存在服务端以供后续资金归集时签名。
- 归集钱包:资产分散在各用户充值钱包中不方便管理,因此当充值钱包达到一定规模时需要进行资金归集,将资金统一归集至归集钱包。
- 大量资金统一管理在一个钱包中是存在比较大的安全风险,所以需要对归集钱包中的资产进行分配并转移。
- 提现钱包:为了方便用户提现和资金安全,一般会将20%资金转移到一个提现钱包(也可能是几个钱包),这个钱包专门用于客户提币使用。
- 手续费钱包:归集资金、转移资金、用户提现这几个操作均需要交易费,当其他钱包ETH不足抵扣交易费时,由该钱包转入一定的ETH作为交易费。

## 冷钱包系统
- 冷钱包系统一般包含系统冷钱包和BOSS钱包组成。
- 系统冷钱包:一般会将20%~30%的资金会转移至系统冷钱包,当提现钱包资金不够时才会在系统冷钱包进行划转。
- BOSS钱包:一般50%以上资金会转移至boss钱包,由公司一个或多个老板控制。

## 钱包系统业务流程
- 注册—— 生成充值地址
- 当用户注册账户,需要对应创建一个钱包,为用户分配一个单独的充值地址,私钥由保存在服务端以用于资金归集。
3 changes: 2 additions & 1 deletion 13区块链/钱包.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
- 持有者通过将其加密货币锁定在特定的区块链网络中,从而获得奖励。
- ETH2.0 质押产品 LSD 开发的复杂度是比较高的 ,但是对于钱包接入来说,只需要对接 LSD 合约就行。
- Solana 和 Tezos 质押在钱包开发中也比较简单,其他链的开发也和他们大同小异。
-




## 币种钱包
Expand Down
2 changes: 1 addition & 1 deletion 17基础设施/0目录.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[介绍LTM](http://www.guanggoo.com/t/29956)

## 工具
- [opencensus](https://opencensus.io) metrics tracing
- [opentelemetry](https://opentelemetry.io/) metrics tracing
- [istio](https://istio.io)
- [telemetry](https://github.com/open-telemetry/opentelemetry-go)

Expand Down
Loading

0 comments on commit 361ab83

Please sign in to comment.