分类 默认分类 下的文章

Docker 时,遇到 "No space left on device" 错误

在使用 Docker 时,遇到 "No space left on device" 错误,通常意味着宿主机的磁盘空间已满。以下是一些常见的原因和解决办法:

1. 清理 Docker 容器、镜像和卷

删除未使用的容器

列出所有停止的容器:

docker ps -a -f status=exited

删除所有停止的容器:

docker rm $(docker ps -a -f status=exited -q)

删除未使用的镜像

列出所有悬空(dangling)镜像:

docker images -f dangling=true

删除所有悬空镜像:

docker rmi $(docker images -f dangling=true -q)

删除未使用的卷

列出所有未使用的卷:

docker volume ls -f dangling=true

删除所有未使用的卷:

docker volume rm $(docker volume ls -f dangling=true -q)

自动清理未使用的数据

你可以使用以下命令自动清理未使用的容器、网络、镜像和卷:

docker system prune

如果你还想删除所有未使用的卷,可以使用:

docker system prune --volumes

2. 检查 Docker 的存储驱动和数据目录

检查 Docker 数据目录使用情况

Docker 通常将其数据存储在 /var/lib/docker 目录下。你可以检查该目录的磁盘使用情况:

du -sh /var/lib/docker

检查 Docker 存储驱动

Docker 使用不同的存储驱动来管理镜像和容器。可以通过以下命令查看当前使用的存储驱动:

docker info | grep 'Storage Driver'

根据存储驱动的不同,可能需要不同的清理策略。

3. 清理系统日志和临时文件

系统日志和临时文件可能会占用大量磁盘空间。

清理系统日志

在 Linux 上,可以使用以下命令清理日志:

sudo journalctl --vacuum-time=2d

这将删除超过 2 天的日志。你可以根据需要调整时间。

清理临时文件

使用以下命令清理临时文件:

sudo rm -rf /tmp/*

4. 检查和调整 Docker 的磁盘配额

如果你在使用 OverlayFS 或其他存储驱动,可以通过配置 Docker 来限制其磁盘使用。编辑 Docker 的配置文件(通常是 /etc/docker/daemon.json),添加类似以下的配置:

{
  "storage-opts": [
    "overlay2.size=20G"
  ]
}

然后重启 Docker 服务:

sudo systemctl restart docker

5. 检查并扩展磁盘空间

如果以上方法都无法解决问题,可能需要扩展宿主机的磁盘空间。以下是一些可能的操作:

  • 添加新的磁盘或扩展现有磁盘。
  • 将 Docker 数据目录移动到更大的磁盘或分区。
    1. 停止 Docker 服务:
      sudo systemctl stop docker
      
    2. 将数据目录移动到新的位置:
      sudo mv /var/lib/docker /new/path/docker
      
    3. 创建一个符号链接:
      sudo ln -s /new/path/docker /var/lib/docker
      
    4. 重启 Docker 服务:
      sudo systemctl start docker
      

通过这些步骤,你应该能够解决 "No space left on device" 错误。如果问题依然存在,请检查系统日志和 Docker 日志以获取更多信息。

emai邮件服务相关的 25、110、465、995 端口的作用 以及 SPF、DKIM 和 DMARC 电子邮件认证技术

在电子邮件系统中,不同的端口用于不同的协议和功能,具体如下:

  1. 端口 25

    • 协议:SMTP(Simple Mail Transfer Protocol)
    • 作用:用于发送电子邮件。SMTP 是用于电子邮件传输的主要协议,通过端口 25,邮件客户端可以将电子邮件发送到邮件服务器,邮件服务器之间也可以通过该端口转发电子邮件。
  2. 端口 110

    • 协议:POP3(Post Office Protocol version 3)
    • 作用:用于从邮件服务器上下载电子邮件。POP3 协议允许邮件客户端从服务器上下载邮件,并在本地阅读和管理。通过端口 110,邮件客户端可以连接到邮件服务器并检索存储在服务器上的邮件。
  3. 端口 465

    • 协议:SMTPS(SMTP Secure)或 SMTP over SSL
    • 作用:用于安全发送电子邮件。SMTPS 是 SMTP 协议的加密版本,通过 SSL/TLS 对邮件传输进行加密,从而提高安全性。端口 465 是为确保邮件传输的机密性和完整性而设定的标准端口。
  4. 端口 995

    • 协议:POP3S(POP3 Secure)或 POP3 over SSL
    • 作用:用于安全接收电子邮件。POP3S 是 POP3 协议的加密版本,通过 SSL/TLS 对邮件传输进行加密,确保邮件在下载过程中不会被截取或篡改。端口 995 是用于安全连接到邮件服务器以检索邮件的标准端口。

总结:

  • 端口 25:用于 SMTP 协议,发送电子邮件。
  • 端口 110:用于 POP3 协议,从服务器下载电子邮件。
  • 端口 465:用于加密的 SMTP 协议(SMTPS),安全发送电子邮件。
  • 端口 995:用于加密的 POP3 协议(POP3S),安全接收电子邮件。

这些端口及其对应的协议是电子邮件系统中的基础组成部分,确保电子邮件的发送、接收和安全性。

SPF、DKIM 和 DMARC 是电子邮件认证技术,用于提高电子邮件的安全性,防止电子邮件欺诈和垃圾邮件。这些技术相互配合,以验证邮件发送者的身份和邮件内容的完整性。

SPF(Sender Policy Framework)

作用

  • SPF 用于验证邮件的发送服务器是否被授权代表发送域发送电子邮件。它通过 DNS 记录定义哪些 IP 地址或主机名可以发送来自该域的电子邮件。

工作原理

  1. DNS 记录:域管理员在域的 DNS 记录中添加一个 SPF 记录,列出授权发送邮件的 IP 地址或主机名。
  2. 验证:当邮件服务器接收到来自该域的邮件时,它会检查邮件的发件人 IP 地址是否在 SPF 记录中列出的授权范围内。如果在,则验证通过;否则,验证失败。

示例

一个简单的 SPF 记录:

v=spf1 ip4:192.0.2.0/24 include:example.com -all
  • v=spf1:SPF 版本。
  • ip4:192.0.2.0/24:授权的 IP 地址范围。
  • include:example.com:包含其他域的 SPF 记录。
  • -all:严格模式,不在列表中的 IP 地址将导致验证失败。

DKIM(DomainKeys Identified Mail)

作用

  • DKIM 用于验证电子邮件的内容和发件人的身份。它通过数字签名的方式确保邮件在传输过程中没有被篡改,并验证邮件是否确实来自声明的域。

工作原理

  1. 签名:邮件服务器在发送邮件时使用域的私钥对邮件的某些部分进行签名,并在邮件头中添加一个 DKIM-Signature 字段。
  2. 验证:接收服务器使用发送域的公钥(发布在 DNS 记录中)验证邮件签名,确保邮件内容的完整性和发件人的身份。

示例

一个简单的 DKIM 记录:

default._domainkey.example.com IN TXT "v=DKIM1; k=rsa; p=公钥内容"
  • v=DKIM1:DKIM 版本。
  • k=rsa:加密算法。
  • p=公钥内容:用于验证签名的公钥。

DMARC(Domain-based Message Authentication, Reporting & Conformance)

作用

  • DMARC 用于告知接收邮件的服务器如何处理未通过 SPF 或 DKIM 验证的邮件,并提供反馈机制给发送域管理员。

工作原理

  1. 策略发布:域管理员在 DNS 中发布 DMARC 记录,指定如何处理未通过验证的邮件(如拒绝、隔离或无操作),以及接收报告的邮箱。
  2. 验证和执行:接收邮件服务器根据 DMARC 策略对邮件进行处理,并将验证结果和处理报告发送给发送域管理员。

示例

一个简单的 DMARC 记录:

_dmarc.example.com IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com"
  • v=DMARC1:DMARC 版本。
  • p=reject:策略(拒绝未通过验证的邮件)。
  • rua=mailto:dmarc-reports@example.com:发送报告的邮箱地址。

综述

  • SPF:验证发送邮件的服务器是否被授权。
  • DKIM:验证邮件内容的完整性和发件人的身份。
  • DMARC:结合 SPF 和 DKIM,制定邮件处理策略,并提供验证结果报告。

通过综合使用 SPF、DKIM 和 DMARC,可以显著提高电子邮件的安全性,减少欺诈和垃圾邮件。

修改运行中的Docker容器修改端口

在docker run创建并运行容器的时候,可以通过-p指定端口映射规则。但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改。当docker start运行容器后并没有提供一个-p选项或设置,让你修改指定端口映射规则。这时可以通过暴力手段,直接强行修改docker容器的配置文件,从而修改容器端口。

对应Linux操作系统

1、先查询出容器的Id

docker inspect [容器id] | grep Id

2、修改容器配置文件

vim /var/lib/docker/containers/[容器id]/hostconfig.json

3、重启docker

sudo systemctl restart docker

对应Mac操作系统

1、先查询出容器的Id

docker inspect [容器id] | grep Id

2、进入docker使用的Linux虚拟机

 docker run -it --privileged --pid=host [镜像名] nsenter -t 1 -m -u -n -i sh

3、修改容器配置文件

vim /var/lib/docker/containers/[容器id]/hostconfig.json

4、重启docker

sudo systemctl restart docker

如何使用Mysql正确的处理财务数据

财务数据相比于普通的互联网应用数据,对数据的一致性有更高的要求。因为涉及到用户金钱的流动,出现问题就意味金钱和声誉上的损失。在用 Mysql 处理财务数据时,我认为应该遵循以下原则:

  1. 使用 DECIMAL 数据类型存储金额。因为浮点数精度是有限的,并且无法精确的表示一些数字。应用程序也应该使用 Decimal 函数库来进行金额的加减乘除的运算,比如 Python 的 decimal 模块,C++ 的 boost Multiprecision 库。
  2. 使用事务来更新数据库。涉及到数据库多个记录更新时,事务能够做到要么全部成功,要么全部失败,这保证了数据的一致性。Mysql 使用事务需要 InnoDB 引擎。
  3. 更新数据库时使用悲观锁。更新数据前使用 SELECT …  FOR UPDATE; 来查询,这样防止并发的请求读到脏数据,导致数据错乱。虽然加锁会影响性能,但为了数据的一致性也是值得的。
  4. 记录资金变化的流水日志。不能简单的只记录用户的金额,还要记录每笔资金的来龙去脉,包括变化的大小、时间、业务、更新前金额、更新后金额、备注等,另外还有记录业务ID防止重复更新金额。这样在对账的时候才能有理有据。

下面以一个完整的示例来说明如何设计一个完备的记账系统用来记录人民币余额,这里精度只需要2位小数就可以了。

假设已经有一个用户表,每个用户有一个唯一ID。我们需要创建两张表,一张余额表,一张流水表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE `balance` (
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `user_id` int NOT NULL,
  `item` varchar(10) NOT NULL,
  `balance` decimal(20,2) NOT NULL
) ENGINE=InnoDB;
 
CREATE TABLE `history` (
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `user_id` int NOT NULL,
  `item` varchar(10) NOT NULL,
  `amount` decimal(20,2) NOT NULL,
  `befor` decimal(20,2) NOT NULL,
  `after` decimal(20,2) NOT NULL,
  `business` varchar(30) NOT NULL,
  `business_id` varchar(100) NOT NULL,
  `detail` text
) ENGINE=InnoDB;

为了加快查询速度,另外为了有效利用 InnoDB 的行级锁,我们需要给两张表加上联合索引。另外,我们需要保证流水记录中 user_id, item, business, business_id 的组合是唯一的,避免重复更新数据。

1
2
3
4
5
ALTER TABLE balance ADD INDEX `user_item_idx` (`user_id`, `item`);
 
ALTER TABLE history ADD INDEX `user_item_idx` (`user_id`, `item`);
 
ALTER TABLE history ADD UNIQUE update_unique (user_id, item, business, business_id);

假设这时候用户 ID 为 1 的用户充值了 100 元人民币,我们需要把用户的人民币余额加上 100 元,我们要如何处理呢?

这里我们还需要一个充值表用来保存用户的充值记录,同时,我们再创建一个提现表来表示用户提现记录,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `deposit` (
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `user_id` int NOT NULL,
  `item` varchar(10) NOT NULL,
  `amount` decimal(20,2) NOT NULL
) ENGINE=InnoDB;
 
CREATE TABLE `withdraw` (
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `user_id` int NOT NULL,
  `item` varchar(10) NOT NULL,
  `amount` decimal(20,2) NOT NULL
) ENGINE=InnoDB;

首先,开始一个事务,创建充值记录:

1
2
3
START TRANSACTION;
 
INSERT INTO deposit VALUES (NULL, 1, 'CNY', '100')

插入成功后,我们可以使用 MYSQL 的 API 获取到上次插入后生成的自增 ID 的值,假设这里也为 1. 然后我们需要从数据库查询当前余额。查询的时候注意要使用 FOR UPDATE 来锁住该记录,避免其它并发的请求读到脏数据。即使当前该记录不存在,在事务提交之前,其它读请求仍然被阻塞读不到数据的。

1
SELECT id, balance FROM balance where user_id = 1 and item = 'CNY' FOR UPDATE;

由于用户是新注册的,查询到的数据为空,所以我们创建新的记录:

1
INSERT INTO balance VALUES (NULL, 1, 'CNY', '100');

然后我们要在流水表中记录下这次的变更操作:

1
INSERT INTO history VALUES (NULL, NULL, 1, 'CNY', '100', '0', '100', 'deposit', '1', '');

最后提交事务:

1
COMMIT;

事务提交后,所有的数据都写入到数据库中了,中间如果有异常发生,则执行

1
ROLLBACK;

来放弃所有的变更。

假设过了一段时间用户要求提现 50 元,操作流程如下:

1
2
3
START TRANSACTION;
 
SELECT id, balance FROM balance where user_id = 1 and item = 'CNY' FOR UPDATE;

假设读出的 id 也为 1. 由于用户之前充值了 100 元还没有使用,所以余额是 100,大于 50 满足提现条件。如果不满足的话需要执行 ROLLBACK. 然后:

1
2
3
4
5
6
7
INSERT INTO withdraw VALUES (NULL, 1, 'CNY', '50');
 
UPDATE balance set balance = '50' WHERE id = 1;
 
INSERT INTO history VALUES (NULL, NULL, 1, 'CNY', '-50', '100', '50', 'withdraw', '1', '');
 
COMMIT;

这就完整的实现了整个充值和提现的流程。

当然,这里示例的充值和提现是最简化的流程,实际业务中,充值和提现往往涉及到多种状态的流转。并且在提现中,用户发起提现和实际进行转账不可能是同时进行的,中间可能会取消操作,直接扣除资金不太妥当,更妥当的做法是把待提现的资金冻结起来,冻结操作其实就是创建一个新的 item: CNY_FREEZE, 在 CNY 上扣减,然后在 CNY_FREEZE 上增加来实现。转账后再从 CNY_FREEZE 中扣除。如果取消操作则取消冻结,从 CNY_FREEZE 扣减,增加到 CNY 上面,这样整个流程在流水日志上都有体现。

https://web.archive.org/web/20170617125020/http://blog.haipo.me/?p=1266

https://zhuanlan.zhihu.com/p/143866444

投屏技术

AirPlay:应用于苹果设备,如:iPhone、iPad、Mac,使用 AirPlay 协议传输,无须其他软件辅助即可连接投屏;
DLNA:应用于 Windows 设备,一般还需要借助第三方软件完成投屏,也可应用于支持 DLNA 协议的 Android 设备,一般只能投放视频和图片;
Miracast:应用于 Android 设备,设备如果支持该功能,通常在设置中显示为 “无线显示” 或 “无线投屏”、“Miracast” 等标识。

协议
实现
项目

php strtotime相对时间-1month的使用问题

历史代码的一个问题

➜  ~ date
Tue Mar 31 17:37:20 CST 2020
➜  ~ php -r "echo date('Y-m', strtotime('-1 month'));"
2020-03                                                                                                                                                                                                        
➜  ~ php -r "echo date('Y-m', strtotime('+1 month'));"
2020-05

当前日期是2020年03月31日,直观感觉减一个月应该是输出2020-02,加一个月应该是输出2020-04。

➜  ~ cal 2 2020
   February 2020
Su Mo Tu We Th Fr Sa
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29

➜  ~ cal 3 2020
     March 2020
Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31


➜  ~ cal 4 2020
     April 2020
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

其实是程序跟人理解不同造成的:
2020年03月31日,减一个月等于 2020年02月31日,系统没有2020年02月31日,往前加就等于2020年03月02日
2020年03月31日,加一个月等于 2020年04月31日,系统没有2020年04月31日,往前加就等于2020年05月01日

#php5.3之前可以采用:

➜  ~ php -r "echo date('Y-m-d', strtotime(date('Ym01').' -1 month'));"
2020-02-01  

     

#php5.3之后可以采用:

    ➜  ~ php -r "echo date('Y-m-d', strtotime('first day of -1 month'));"
2020-02-01                                                                                                                                                                                               ➜  ~ php -r "echo date('Y-m-d', strtotime('last day of -1 month'));"
2020-02-29

团队协作的原则

原则

本文档规范作为团队的基本原则,在无法做出决定,或不知道某件事情是否该做时,可以以本文档作为参考指导。

零成本质疑

任何人、任何方案都是可以被质疑的,包括本文档,我们提倡任何人,不管能力高低,经验多寡都可以对自己不理解的事物提出质疑,被质疑者应客观沟通,以解决问题为目标,不得给质疑者形成任何心理压力。任何非恶意的疑问,质疑都是被鼓励的。

演进迭代

我们相信任何事物都可以通过演进迭代不断优化,包括本文档。这意味着我们在开始着手做某件事时,不需要一下子做到完美,可以先开始然后通过演进迭代一步步趋向目标;这也意味着,我们不应该对已经做过的事情轻易满足,而是要持续不断的思考其演进方向,迭代优化。

科学思维

我们提倡任何知识、结论都要至少经过“理论猜想”、“实验验证”、“推理预测”三个过程。不盲目接受网络、书本上的信息,更不奉为金科玉律。提出观点时,首先通过自己的理论基础提出猜想,并设计实验进行验证,根据验证过的观点做出推论和预测,并时刻以后续发展结果检验预测是否正确,观点是否完善。

等价交换

我们不允许损害他人的利益来换取自己的利益,同样我们也不提倡损伤自己的利益来满足他人的利益。我们提倡从长远时间来看,每个人的付出和收益是不断趋于等价的。

不做评价

跟做评价相比,我们更倾向讲事实讲道理,我们不说某个事情“很容易”,我们只说经过1、2、3等步骤就可以做好。我们不说一个问题“很傻”,我们只说这个问题的答案是什么以及如何得到这个答案。我们不说一个人“不负责任”,我们只说一件事原定要做到1、2、3,而现在只做到了1、3,那么我们该如何一起解决2的问题。

BTC和USDT(OMNI)转账协议分析

对照 《精通比特币》的交易章节分析转账协议

参考:
比特币脚本
在比特币上发代币的基本原理——omni协议发代币的通俗解释
官方的开发文档 Bitcoin的WIKI建议这两份英文文档

USDT只是是OMNI协议上面的一种代币,编号31,而OMNI协议是基于BTC网络保证数据真实可靠,OMNI节点保存了一份账号表,OMNI协议通过OP_RETURN来操作账号表,要修改账号表需要证明操作权限,因而一般附带了BTC转账的过程,也会产生BTC手续费。

BTC转账协议分析

--------------------
交易:a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d
raw: https://btc.com/a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d.rawhex

01 加锁数量

输出脚本:
0010a5d4e8000000 小头,八字节,转出数量 10000.00000000
19 脚本长度

76 OP_DUP
a9 OP_HASH160
14 20字节
46af3fb481837fadbb421727f9959c2d32a36829 允许解锁这笔交易的公钥对应的公钥hash
88 OP_EQUALVERIFY
ac OP_CHECKSIG

00000000 LockTime


--------------------
--------------------
交易:cca7507897abc89628f450e8b1e0c6fca4ec3f7b34cccf55f3f531c659ff4d79
raw:https://btc.com/cca7507897abc89628f450e8b1e0c6fca4ec3f7b34cccf55f3f531c659ff4d79.rawhex
01000000018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1000000008b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabbffffffff0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac00000000

--------------------
01000000 版本

--------------------
01 输入脚本数量

--------------------
解锁输入脚本一:P2PKH(Pay-to-Public-Key-Hash)

8dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1 引用的交易哈希,32字节,小头
00 引用的交易输出索引
0000008b 脚本长度139=1长度+71签名+1类型+1长度+1版本+64公钥

签名:
48 签名和签名类型的长度
30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e 签名
01 签名类型

公钥:Hash160(46af3fb481837fadbb421727f9959c2d32a36829) Address(17SkEw2md5avVNyYgj6RiXuQKNwkXaxFyQ)
41 公钥长度
04 公钥版本
2e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b7 公钥X
6426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb 公钥Y

ffffffff 序列号

--------------------
02 输出脚本数量

--------------------
加锁输出脚本一:P2PKH(Pay-to-Public-Key-Hash)
00719a8186000000 小头,八字节,转出数量 5777.00000000
19 脚本长度
76 DUP
a9 HASH160
14 PUSHDATA(20)
df1bd49a6c9e34dfa8631f2c54cf39986027501b
88 EQUALVERIFY
ac CHECKSIG

--------------------
加锁输出脚本二:P2PK(Pay-to-Public-Key)
009f0a5362000000 小头,八字节,转出数量 4223.00000000
43 脚本长度
41 PUSHDATA(65)
04 cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab3 3cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455d 版本+公钥XY
ac CHECKSIG

--------------------
00000000 LockTime

OMNI协议转账分析一

--------------------------------------------------------------------------
交易:
https://btc.com/9bc1e10acf8f166613500d8a210dc4d2be018dc47730f268b351f4cb89fda86e.rawhex
01000000016749664960e8cfa57abd3dce29e73c0b6b79626c0b6dd703309d7497da8939d0010000006b483045022100ad0ece657f9320045be9740abadf7cf8948ba9fd22c1ec3d48adf13a0753105102204d588f0cdf7f5262df3cfb3fb18635114c044e062d2f898a08c02171b390debb012103da5bac7b36d5aa38f531c6b9601e21bb598a4b6716ebed38b009a55dabde9440feffffff030000000000000000166a146f6d6e69000000000000001f0000048c27395000f52e7a00000000001976a914a25dec4d0011064ef106a983c39c7a540699f22088ac1c0200000000000017a914ebc6513b2e2aa73207663f613cd89a479e5f24d787f9480800

01 版本
00000001 解锁脚本数量

--------------------
解锁输入脚本一:
6749664960e8cfa57abd3dce29e73c0b6b79626c0b6dd703309d7497da8939d0 引用的交易哈希,32字节,小头
01 引用的交易输出索引
0000006b 脚本长度
48 签名长度72
3045022100ad0ece657f9320045be9740abadf7cf8948ba9fd22c1ec3d48adf13a0753105102204d588f0cdf7f5262df3cfb3fb18635114c044e062d2f898a08c02171b390debb01
21 公钥长度33
03da5bac7b36d5aa38f531c6b9601e21bb598a4b6716ebed38b009a55dabde9440
feffffff

03 输出脚本数量
--------------------
加锁输出脚本一:
0000000000000000 小头,八字节,转出数量 0
16 锁定脚本长度22
6a OP_RETURN 标记交易无效
14 长度20
6f6d6e69
000000000000001f 31USDT
0000048c27395000 50000.00000000
--------------------
加锁输出脚本二:
f52e7a0000000000 小头,八字节,转出数量 8007413
19 锁定脚本长度25
76 OP_DUP
a9 OP_HASH160
14 20字节
a25dec4d0011064ef106a983c39c7a540699f220 地址 1FoWyxwPXuj4C6abqwhjDWdz6D4PZgYRjA
88 OP_EQUALVERIFY
ac OP_CHECKSIG
--------------------
加锁输出脚本三:
1c02000000000000 小头,八字节,转出数量 540
17 锁定脚本长度23
a9 OP_HASH160
14 20字节
ebc6513b2e2aa73207663f613cd89a479e5f24d7
87 EQUAL
--------------------
f9480800 LockTime




--------------------------------------------------------------------------
交易:5bf6c71747fdfd725acc9216c1a2d633d8ae47d6a842c8f83e3b0c9e600410f2
https://btc.com/5bf6c71747fdfd725acc9216c1a2d633d8ae47d6a842c8f83e3b0c9e600410f2.rawhex
01000000016ea8fd89cbf451b368f23077c48d01bed2c40d218a0d501366168fcf0ae1c19b010000006a4730440220301a98b76c2e16640b152aba20b396c03ef3dbd13873b492489add044e2e9c58022048cfea2d818d4a632396795f1cec12a3e470da17b9d1ea6c8d7342411682721e012103da5bac7b36d5aa38f531c6b9601e21bb598a4b6716ebed38b009a55dabde9440feffffff030000000000000000166a146f6d6e69000000000000001f0000000ba43b7400291c7a00000000001976a914a25dec4d0011064ef106a983c39c7a540699f22088ac22020000000000001976a91404a94b25d962e443e95304d2de5a1bf957b9807a88acf9480800

输入8007413=8003147(输出一8002601+输出二546)+手续费4266 

01 版本
00000001 解锁脚本数量

--------------------
解锁输入脚本一:
6ea8fd89cbf451b368f23077c48d01bed2c40d218a0d501366168fcf0ae1c19b 引用的交易哈希,32字节,小头 9bc1e10acf8f166613500d8a210dc4d2be018dc47730f268b351f4cb89fda86e
01 引用的交易输出索引
0000006a 脚本长度
47 签名长度71
30440220301a98b76c2e16640b152aba20b396c03ef3dbd13873b492489add044e2e9c58022048cfea2d818d4a632396795f1cec12a3e470da17b9d1ea6c8d7342411682721e01
21 公钥长度33
03da5bac7b36d5aa38f531c6b9601e21bb598a4b6716ebed38b009a55dabde9440 地址 1FoWyxwPXuj4C6abqwhjDWdz6D4PZgYRjA
feffffff


03 输出脚本数量
--------------------
加锁输出脚本一:
0000000000000000 小头,八字节,转出数量 0
16 锁定脚本长度22
6a OP_RETURN 标记交易无效
14 长度20
6f6d6e69 omni的16进制表示
000000000000001f 31USDT
0000000ba43b7400 500.00000000
--------------------
加锁输出脚本二:
291c7a0000000000 小头,八字节,转出数量 8002601
19 锁定脚本长度25
76 OP_DUP
a9 OP_HASH160
14 20字节
a25dec4d0011064ef106a983c39c7a540699f220
88 OP_EQUALVERIFY
ac OP_CHECKSIG
--------------------
加锁输出脚本三:
2202000000000000 小头,八字节,转出数量 546
19 锁定脚本长度25
76 OP_DUP
a9 OP_HASH160
1404a94b25d962e443e95304d2de5a1bf957b9807a
88 OP_EQUALVERIFY
ac OP_CHECKSIG
--------------------
f9480800 LockTime

OMNI协议转账分析二

https://www.omniexplorer.info/tx/f404e033d9a8ef815db75d5056eab9f1e09d3865c53afe5ce02884bfb4247047

BTC 0.0093566(0.00100000+0.00835660)=0.0087566(875114+546)+0.0006


01000000

02 输入数量

https://btc.com/c23495f6e7ba24705d43583edd69ff25a354c18e69fd8514c07ec6f47cb995de from 1K6JtSvrHtyFmxdtGZyZEF7ydytTGqasNc
de95b97cf4c67ec01485fd698ec154a325ff69dd3e58435d7024bae7f69534c2 大头 c23495f6e7ba24705d43583edd69ff25a354c18e69fd8514c07ec6f47cb995de
00
0000006a
47
304402200a6fef16882db2f3e07356b619121d74cf0bd42872cba57430e901b4252f7c8102202edcaa90b278d568faa55a6a9c523ff0cd09e0c916e75ea7baf4690d5747789c01
21
0382df61bad93a1211ceac5c78fd273d65e405a7e148e068ced3e40bf87cf71721
ffffffff

https://btc.com/ee1673b09b0edaf7aaf8eb0bfd53a5a2757eb3e342e731bfc960b869aa0ab6b3 from 1K6JtSvrHtyFmxdtGZyZEF7ydytTGqasNc
b3b60aaa69b860c9bf31e742e3b37e75a2a553fd0bebf8aaf7da0e9bb07316ee 大头 ee1673b09b0edaf7aaf8eb0bfd53a5a2757eb3e342e731bfc960b869aa0ab6b3
02
0000006b
48
3045022100ae11d3c92a501496381aa7eaf10ef458f4aabdd3075233ae70d9d32f6b83d812022053aa4171e3d2b58465dde42d07ba4e5f74948b2cdb01a67dfdac4e4eb24b684901
21
0382df61bad93a1211ceac5c78fd273d65e405a7e148e068ced3e40bf87cf71721
ffffffff

03 输出数量

6a5a0d0000000000 875114
19
76
a9
14
c6734676a08e3c6438bd95fa62c57939c988a17b 1K6JtSvrHtyFmxdtGZyZEF7ydytTGqasNc
88
ac

0000000000000000
16
6a
14
6f6d6e69
0000000000000002
0000000000989680

2202000000000000 546
19
76
a9
14
ee692ea81da1b12d3dd8f53fd504865c9d843f52 1Njbpr7EkLA1R8ag8bjRN7oks7nv5wUn3o
88
ac

00000000

区块链学习知识模块

1.Bitcoin,Ethereum,HyperLedger Fabric的区块链相关机制与原理以及理念;
2.共识算法,主要有PoW,PoS,DPoS,PBFT,Paxos,Raft等;
3.分布式架构,包含网络编程、分布式算法、加密签名、数据存储、p2p并发;
4.HTTP/2协议,gRPC框架,protobuf的开发等;
5.NoSQL数据库的原理与使用,尤其是KV型数据库:LevelDB,RocksDB等,monogodb用到了区块链浏览器;
6.golang,C++,python等主流区块链系统开发语言;
7.钱包管理公钥私钥、代币信息获取、冷热钱包处理;
8.交易所系统(市场行情、钱包账号、交易撮合)( http://w.lianmishu.com );
9.数据采集处理( http://www.lianzhuli.com http://www.lianmishu.com http://www.0123456789.com http://www.0123456789.biz https://www.feixiaohao.com/ )
10.区块链浏览器( https://www.yitaifang.com )
11.linux操作系统,Docker容器技术的原理,部署和使用优化。

mysql innoDB使用聚族索引

https://dev.mysql.com/doc/refman/5.6/en/innodb-index-types.html
http://umumble.com/blogs/mysql/mysql-(innodb)-clustered-and-non_clustered-indexes-/
http://blog.csdn.net/jhgdike/article/details/60579883
http://blog.csdn.net/caomiao2006/article/details/52140953
http://www.cnblogs.com/xxmysql/p/5874803.html