CI_Knight

且行善举,莫问前程。

0%

现在有很多笔记和知识管理软件,比如Notion、语雀、幕布,还有老牌服务Confluence等。这些各有优势,但是基本上都不支持私有云部署,支持私有云的也是价格昂贵。我个人还是倾向于使用私有云,笔记这种东西,迁移数据还是挺麻烦的。

我自己就用的开源Wiki软件TiddlyWiki5,部署在家里的NAS里面。

TiddlyWiki5

使用简单,功能丰富,支持插件。

安装

直接使用npm安装,使用起来就几个简单命令。

初始化

tiddlywiki mywiki –init server

运行

tiddlywiki mywiki –liste

插件

官方已经自带了很多插件了,具体可以看https://github.com/Jermolene/TiddlyWiki5/tree/master/plugins/tiddlywiki。修改配置文件tiddlywiki.info,将需要的插件写入配置文件,运行服务就可以了。

使用

使用起来非常简单,目录结构基本上都是通过tag实现,当然也可以看官方给的样例来学习如何使用。

官方样例看:https://tiddlywiki.com/

由于我们线上环境依然使用的Python 3.7,换了M1的电脑后,Python 3.7无法使用。大多软件基本上没有遇到兼容问题,唯独遇到Python 3.7有问题。大概就是3.7版本还没有兼容N1,在升级到3.8后也遇到了其他的问题。为了开发稳定还是要使用3.7版本开发。当然办法有很多,在我现在看来,成本最低就是解决3.7版本的运行问题。查阅尝试了很多方法,最靠谱的就是使用brew安装x86的Python 3.7,然后再做软连接到pyenv,如果不用pyenv,也可以做软连接到自己的喜欢的地方。

brew在M1和x86有不同的家目录,详细可以看brew介绍,接下来看如何操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Install x86 brew
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
alias ibrew=/usr/local/bin/brew

# Install Python 3.7
ibrew install [email protected]

# Add `python` executable (symlink to `python3`)
ln -s python3 "$(ibrew --prefix [email protected])"/bin/python

# Symlink x86 Python 3.7 into pyenv
ln -s "$(ibrew --prefix [email protected])" .pyenv/versions/3.7.12

# Check
pyenv local 3.7.12
python -V
# Python 3.7.12
python -c 'import _ctypes'. # works!

想要尝试其他方法,可以看我引用的链接。

参考

博客总是有一些奇怪的排版,尤其是中引文混用的时候,就像下面这样。

一般文字排版都是CSS的text-align属性控制的,当调整text-align属性时,文字会相应的使用不同的对齐方式。但上面这种是因为英文单词截断方式导致的,纯汉字或者纯英文一行不会发生这样的问题,而且换行位置正好是有连接符的,这就让我猜想应该是英文字符截断有关。直接通过chrome调试,更改连接符位置,果然会重新换到连接符的位置换行。那这时候就应该调整word-break了。

但纯的调整text-align不能达到美化的效果,会导致每行行数不一。所以调整word-break到break-all就可以了,具体的也可以根据不同浏览器适配来调整。

因为网站大多是自适应排版,除非固定post-body的宽度,才能做到比较好看的排版。也或者hexo有自动截断英文单词并且添加连接符的插件,这种插件当然我没有找到,如果有人知道可以告诉我。现在的排版已经好很多了,不会再出现非常难看的超宽字距了,况且也不能和专业排版软件比。

参考

还有一天就国庆了,现在满脑子都在想给祖国庆生。不过这样重大的节日,翻墙总是会出些问题,为了应对这样的问题,应该提前多建几个代理服务器,那我就选了一台 vultr 服务器做备用机,之前都是 vmess 协议,这次打算尝试下 trojan 的安全性。如果你在搬瓦工、digital ocean、vultr等这种云服务商搭建的 vpn,在重大节日时,大概率都会被封端口或者是 IP,而且 vmess 现在应该是可以被准确识别了,我的 vmess 代理每次都可以精准被封端口。

vultr 的美国线路要比 digital ocean 更好,而且有日本可选,新加坡基本抢不到,如果选美国最好使用美西服务器,如果电脑系统是 MacOS,可以安装 BestTrace 软件看下线路,vultr 提供了测试的 IP 地址,在他们官网可以找到。

如果是 vultr 的新用户可以网上搜下优惠码,这样你可以获得 100 美金的试用金,一个月内有效。vultr 可以使用支付宝和加密货币支付,这点还是挺厉害的。

搭建 trojan 服务器

我选的系统是 Debian 11,接下来可以直接跟着步骤操作。vultr 需要在后台设置下安全组,放开 80 和 443 就可以了。使用 trojan 需要一个域名,并且使用ssl加密。如果想了解更多,可以看p4gefau1t trojan的文档。

关闭防火墙

1
2
systemctl disable ufw.service
systemctl stop ufw.service

安装 Nginx

1
2
3
apt install tmux unzip nginx
systemctl enable nginx
systemctl start nginx

下载 trojan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mkdir trojan
cd trojan
wget https://github.com/p4gefau1t/trojan-go/releases/download/v0.10.6/trojan-go-linux-amd64.zip
unzip -o trojan-go-linux-amd64.zip
rm trojan-go-linux-amd64.zip
cat > config.json <<EOF
{
"run_type": "server",
"local_addr": "0.0.0.0",
"local_port": 443,
"remote_addr": "127.0.0.1",
"remote_port": 80,
"password": ["your password"],
"ssl": {
"cert": "/etc/letsencrypt/live/example.com/fullchain.pem",
"key": "/etc/letsencrypt/live/example.com/privkey.pem",
"sni": "example.com"
}
}
EOF

配置文件要把域名和密码修改成自己的。

申请证书

我们使用 certbot 申请证书,也可以使用自己购买的证书。

1
2
3
4
5
apt install snapd
snap install core
snap refresh core
snap install --classic certbot
certbot certonly --nginx

运行 trojan

1
2
tmux new -s trojan-server
./trojan-go -config config.json

证书续订

1
certbot renew --dry-run

客户端

我推荐使用ClashX,是一个小猫咪的图标,有 MacOS、Windows、Android 版本,配置可以根据https://github.com/Hackl0us/SS-Rule-Snippet/blob/master/LAZY_RULES/clash.yaml自行修改,配置可以托管在服务器上,多端共用一套配置即可。iOS可以使用shadowrocket,兼容Clash的配置,可以直接添加。

参考

问题和教程都有时效性,我一般写的都很少,很多依赖于版本或者系统,当遇到问题更建议去 Stack Overflow 或者 Github issue 中搜索,也或者直接使用 Google 搜索,肯定很多人乐于写这些。不过我今天还是水了一篇文章。

版本和软件环境

1
2
3
4
System: MacOS 10.15
Python: 3.7.6
gunicorn: 19.9.0
pycoin: 0.90.20190728

问题

我在家里电脑启动一个 gunicorn 服务时,出现 worker 无法的情况,但是并没有任何保存,只有 worker 重启日志,因为没有报错,排查起来就比较麻烦了。我使用的 pipenv 启动的,软件依赖问题可能性很小。当我尝试使用 ipython 运行的时候,则会报错 Abort trap

解决

这时候会发现服务并没有抛错,而我还没办法定位哪里出现的异常,并且吞掉了错误信息。如果使用 pdb 这种工具,定位错误是很费力的。想要快速定位 Abort 位置,可以使用 PYTHONVERBOSE 环境变量。

将 PYTHONVERBOSE 设置为 3 再启动服务,会打印加载模块时的日志,闪退后最后输入的日志,就是我们要定位的地方。通过这种方式我知道是 pycoin 加载 openssl 动态链接库的时候报错了,因为使用了 pycoin 的 ecdsa 模块,并且还是用了 openssl 加速,找不到动态链接库才闪退的。

我们可以将 /usr/local/Cellar/openssl 下的动态链接库拷贝到 /usr/local/lib/ 下,并且再做软连接。

1
2
3
4
5
6
brew install openssl
cd /usr/local/Cellar/[email protected]/1.1.1i/lib
sudo cp libssl.1.1.dylib libcrypto.1.1.dylib /usr/local/lib/
cd /usr/local/lib
sudo ln -s libssl.1.1.dylib libssl.dylib
sudo ln -s libcrypto.1.1.dylib libcrypto.dylib

参考

安装flow-cli

安装 flow-cli,MacOS 需要下载最新版本的二进制文件,brew 只能安装旧版本。具体安装方法见文档 Install the Flow CLI,该文档使用版本是 v0.25.0。

生成key-pair

1
2
3
4
5
$ flow keys generate --sig-algo=ECDSA_secp256k1

Store private key safely and don't share with anyone!
Private Key 11e67f5360e61d7d92eb73e1dc48ffbd71c55c8bdf727520d11ddfa6db63554d
Public Key cd23c71391d33c23c867319258ad6cd082b0066e564e23d3fda3c4e5b9ec841eaaa07d2189965130445a4edda244720628334f6a879d80220b573d9914edcbe2

创建testnet flow地址

访问页面:Flow Testnet Faucet ,创建地址。填入生成的 public key,选择ECDSA_secp256k1签名算法和SHA3_256(和 ETH 哈希算法相同)哈希算法。

创建成功后得到地址:0x25470ac6e0585a62,也可以跳过该步骤,直接使用生成好的地址。

初始化flow配置文件

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
32
33
34
35
36
37
$ mkdir flow-example; cd flow-example
$ flow init --service-priv-key 11e67f5360e61d7d92eb73e1dc48ffbd71c55c8bdf727520d11ddfa6db63554d --service-sig-algo=ECDSA_secp256k1 --service-hash-algo=SHA3_256

Configuration initialized
Service account: 0xf8d6e0586b0a20c7

Start emulator by running: 'flow emulator'
Reset configuration using: 'flow init --reset'

$ cat flow.json
{
"emulators": {
"default": {
"port": 3569,
"serviceAccount": "emulator-account"
}
},
"contracts": {},
"networks": {
"emulator": "127.0.0.1:3569",
"mainnet": "access.mainnet.nodes.onflow.org:9000",
"testnet": "access.devnet.nodes.onflow.org:9000"
},
"accounts": {
"emulator-account": {
"address": "f8d6e0586b0a20c7",
"key": {
"type": "hex",
"index": 0,
"signatureAlgorithm": "ECDSA_secp256k1",
"hashAlgorithm": "SHA3_256",
"privateKey": "11e67f5360e61d7d92eb73e1dc48ffbd71c55c8bdf727520d11ddfa6db63554d"
}
}
},
"deployments": {}
}

我们将配置里的地址 f8d6e0586b0a20c7 修改为 25470ac6e0585a62。

创建交易并签名广播

在构造 flow 的交易时,我们需要先使用 Cadence 语言编写执行脚本,代码如下:

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
32
$ cat > tx.cdc <<EOF
import FungibleToken from 0x9a0766d93b6608b7
import FlowToken from 0x7e60df042a9c0868

transaction(amount: UFix64, to: Address) {

// The Vault resource that holds the tokens that are being transferred
let sentVault: @FungibleToken.Vault

prepare(signer: AuthAccount) {

// Get a reference to the signer's stored vault
let vaultRef = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault)
?? panic("Could not borrow reference to the owner's Vault!")

// Withdraw tokens from the signer's stored vault
self.sentVault <- vaultRef.withdraw(amount: amount)
}

execute {

// Get a reference to the recipient's Receiver
let receiverRef = getAccount(to)
.getCapability(/public/flowTokenReceiver)
.borrow<&{FungibleToken.Receiver}>()
?? panic("Could not borrow receiver reference to the recipient's Vault")

// Deposit the withdrawn tokens in the recipient's receiver
receiverRef.deposit(from: <-self.sentVault)
}
}
EOF

在 testnet 网络上,FlowToken 的合约地址是 0x7e60df042a9c0868。如果使用主网或者是 emulator,需要替换成对应的合约地址,具体查询:Flow Core Contracts

我们 cdc 代码中定义了 transaction 方法,并且包含两个参数 amount 和 to,我们构造交易时,也要传入对应参数。

我们使用 flow-cli 来构造交易,可以将 flow 发送到 0x72aeca95731d54e5(必须是一个真实创建的地址)。

1
2
3
4
5
6
7
8
9
10
$ flow transactions build ./tx.cdc \
--authorizer emulator-account \
--proposer emulator-account \
--payer emulator-account \
--args-json '[{"type": "UFix64", "value": "1.0"}, {"type": "Address", "value": "0x72aeca95731d54e5"}]' \
--network testnet \
--filter payload \
--save built.rlp

result saved to: built.rlp

我们只保存 payload,我们的接下来对 payload 进行签名,生成签名后的哈希。

1
2
3
4
$ flow transactions sign ./built.rlp --signer emulator-account \
--filter payload --save signed.rlp

result saved to: signed.rlp

广播签名后的交易。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
$ flow transactions send-signed --network testnet ./signed.rlp

Sending transaction with ID: 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7

Status ✅ SEALED
ID 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7
Payer 25470ac6e0585a62
Authorizers [25470ac6e0585a62]

Proposal Key:
Address 25470ac6e0585a62
Index 0
Sequence 0

No Payload Signatures

Envelope Signature 0: 25470ac6e0585a62
Signatures (minimized, use --include signatures)

Events:
Index 0
Type A.7e60df042a9c0868.FlowToken.TokensWithdrawn
Tx ID 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7
Values
- amount (UFix64): 1.00000000
- from (Address?): 0x25470ac6e0585a62

Index 1
Type A.7e60df042a9c0868.FlowToken.TokensDeposited
Tx ID 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7
Values
- amount (UFix64): 1.00000000
- to (Address?): 0x72aeca95731d54e5

Index 2
Type A.7e60df042a9c0868.FlowToken.TokensWithdrawn
Tx ID 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7
Values
- amount (UFix64): 0.00010000
- from (Address?): 0x25470ac6e0585a62

Index 3
Type A.7e60df042a9c0868.FlowToken.TokensDeposited
Tx ID 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7
Values
- amount (UFix64): 0.00010000
- to (Address?): 0x912d5440f7e3769e

Index 4
Type A.912d5440f7e3769e.FlowFees.TokensDeposited
Tx ID 8a979bd7d0278bada8b9cf57611608a5ba258090ecdddaaa83e2e5d04fe53af7
Values
- amount (UFix64): 0.00010000


Code (hidden, use --include code)

Payload (hidden, use --include payload)

广播后如果 Status 为 SEALED 则发送成功。