BCH地址编码格式

base32编码,使用BCH码作为checksum. 复用了bech32的某些东西但有其他方面提升.
地址组成
地址所属网络的前缀
分隔符,通常是:
base32编码的payload, 代表地址目的地还包括checksum
前缀
bitcoincash 作为比特币现金主网前缀
bchtest 作为比特币现金测试网前缀
bchreg作为比特币现金regtest前缀
前缀后跟随分隔符冒号. 面向用户展示时前缀可以去掉,因为它也参与checksum计算,checksum保证了各个网络上的地址是不兼容的,甚至不需要前缀情况下也是.
payload
base32编码的流数据
0
1
2
3
4
5
6
7
+0
q
p
z
r
y
9
x
8
+8
g
f
2
t
v
d
w
0
+16
s
3
j
n
5
4
k
h
+24
c
e
6
m
u
a
7
l
payload由三部分组成:
1、一个字节的版本号,指示地址类型
2、哈希
3、40比特checksum
版本字节
最高比特位保留并且必须是0,接下来4比特指示地址类型,最后3比特指示哈希长度
Size bits
Hash size in bits
0
160
1
192
2
224
3
256
4
320
5
384
6
448
7
512
在版本域中编码哈希大小可以检查地址长度是否正确。
Type bits
Meaning
Version byte value
0
P2KH
0
1
P2SH
8
更多类型将随着新特征的添加而添加。
哈希
代表P2KH的公钥哈希和赎回脚本P2SH的哈希
checksum
40比特BCH码,确保可以最多检测到地址中的6个和每行8个的错误,结合长度检查可以提供很强大的错误识别能力。
checksum计算代码如下:
uint64_t PolyMod(const data &v) {
    uint64_t c = 1;
    for (uint8_t d : v) {
        uint8_t c0 = c >> 35;
        c = ((c & 0x07ffffffff) << 5) ^ d;
        if (c0 & 0x01) c ^= 0x98f2bc8e61;
        if (c0 & 0x02) c ^= 0x79b76d99e2;
        if (c0 & 0x04) c ^= 0xf33e5fb3c4;
        if (c0 & 0x08) c ^= 0xae2eabe2a8;
        if (c0 & 0x10) c ^= 0x1e4f43e470;
    }
    return c ^ 1;
}
计算基于如下数据(整数范围0~31):
1、前缀中每个字母的低5比特,例如:”bit…”就变成了2,9,20,…
2、用0表示分隔符,并且是5个0比特
3、5比特一组的payload,必要情况下最右边要补零凑足5比特
4、8比特0作为checksum的占位符
PolyMod返回的40比特数据分为8个5比特数据(最高位在前),然后将payload和checksum根据base32字符表来编码。
要验证base32格式化后的地址,首先通过冒号区分开前缀和payload。传到PolyMod函数的数据来源于:
1、前缀每个字符的低5比特
2、5比特0作为分隔符
3、对应数字的base32映射字符
如果PolyMod返回非0就表示地址已损坏。
下列地址可作为checksum计算的测试向量:
  • prefix:x64nx6hz
  • p:gpf8m4h7
  • bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn
  • bchtest:testnetaddress4d6njnut
  • bchreg:555555555555555555555555555555555555555555555udxmlmrz
这些地址并不包含合理payload
错误纠正
BCH码允许错误纠正,但强烈不建议自动错误纠正,可能导致资金出现不可逆的丢失,可以作为可能的错误来提示用户。
大小写
推荐用小写来表示地址,大写形式也可以。大小写混合组成则不允许。
允许大写形式是因为地址可以使得QR使用字数码模式有效编码。
双前缀
有些场景下比如支付URL和QR码,地址通过bitcoincash:作为前缀,这种情况下地址不能有双前缀。
地址翻译示例
下面这些地址包含了给定遗留地址和对应的新格式地址
Legacy
CashAddr
1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu
bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a
1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR
bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy
16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb
bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r
3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC
bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq
3LDsS579y7sruadqu11beEJoTjdFiFCdX4
bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e
31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw
bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37
更大测试向量
这个表定义了各种payload长度各种前缀的测试向量,这些测试向量没有给出遗留地址格式是因为遗留格式仅限于160比特长度payload。
Payload Size (bytes)
Type
CashAddr
Payload (hex)
20
0
bitcoincash:qr6m7j9njldwwzlg9v7v53unlr4jkmx6eylep8ekg2
F5BF48B397DAE70BE82B3CCA4793F8EB2B6CDAC9
20
1
bchtest:pr6m7j9njldwwzlg9v7v53unlr4jkmx6eyvwc0uz5t
F5BF48B397DAE70BE82B3CCA4793F8EB2B6CDAC9
20
1
pref:pr6m7j9njldwwzlg9v7v53unlr4jkmx6ey65nvtks5
F5BF48B397DAE70BE82B3CCA4793F8EB2B6CDAC9
20
15
prefix:0r6m7j9njldwwzlg9v7v53unlr4jkmx6ey3qnjwsrf
F5BF48B397DAE70BE82B3CCA4793F8EB2B6CDAC9
24
0
bitcoincash:q9adhakpwzztepkpwp5z0dq62m6u5v5xtyj7j3h2ws4mr9g0
7ADBF6C17084BC86C1706827B41A56F5CA32865925E946EA
24
1
bchtest:p9adhakpwzztepkpwp5z0dq62m6u5v5xtyj7j3h2u94tsynr
7ADBF6C17084BC86C1706827B41A56F5CA32865925E946EA
24
1
pref:p9adhakpwzztepkpwp5z0dq62m6u5v5xtyj7j3h2khlwwk5v
7ADBF6C17084BC86C1706827B41A56F5CA32865925E946EA
24
15
prefix:09adhakpwzztepkpwp5z0dq62m6u5v5xtyj7j3h2p29kc2lp
7ADBF6C17084BC86C1706827B41A56F5CA32865925E946EA
28
0
bitcoincash:qgagf7w02x4wnz3mkwnchut2vxphjzccwxgjvvjmlsxqwkcw59jxxuz
3A84F9CF51AAE98A3BB3A78BF16A6183790B18719126325BFC0C075B
28
1
bchtest:pgagf7w02x4wnz3mkwnchut2vxphjzccwxgjvvjmlsxqwkcvs7md7wt
3A84F9CF51AAE98A3BB3A78BF16A6183790B18719126325BFC0C075B
28
1
pref:pgagf7w02x4wnz3mkwnchut2vxphjzccwxgjvvjmlsxqwkcrsr6gzkn
3A84F9CF51AAE98A3BB3A78BF16A6183790B18719126325BFC0C075B
28
15
prefix:0gagf7w02x4wnz3mkwnchut2vxphjzccwxgjvvjmlsxqwkc5djw8s9g
3A84F9CF51AAE98A3BB3A78BF16A6183790B18719126325BFC0C075B
32
0
bitcoincash:qvch8mmxy0rtfrlarg7ucrxxfzds5pamg73h7370aa87d80gyhqxq5nlegake
3173EF6623C6B48FFD1A3DCC0CC6489B0A07BB47A37F47CFEF4FE69DE825C060
32
1
bchtest:pvch8mmxy0rtfrlarg7ucrxxfzds5pamg73h7370aa87d80gyhqxq7fqng6m6
3173EF6623C6B48FFD1A3DCC0CC6489B0A07BB47A37F47CFEF4FE69DE825C060
32
1
pref:pvch8mmxy0rtfrlarg7ucrxxfzds5pamg73h7370aa87d80gyhqxq4k9m7qf9
3173EF6623C6B48FFD1A3DCC0CC6489B0A07BB47A37F47CFEF4FE69DE825C060
32
15
prefix:0vch8mmxy0rtfrlarg7ucrxxfzds5pamg73h7370aa87d80gyhqxqsh6jgp6w
3173EF6623C6B48FFD1A3DCC0CC6489B0A07BB47A37F47CFEF4FE69DE825C060
40
0
bitcoincash:qnq8zwpj8cq05n7pytfmskuk9r4gzzel8qtsvwz79zdskftrzxtar994cgutavfklv39gr3uvz
C07138323E00FA4FC122D3B85B9628EA810B3F381706385E289B0B25631197D194B5C238BEB136FB
40
1
bchtest:pnq8zwpj8cq05n7pytfmskuk9r4gzzel8qtsvwz79zdskftrzxtar994cgutavfklvmgm6ynej
C07138323E00FA4FC122D3B85B9628EA810B3F381706385E289B0B25631197D194B5C238BEB136FB
40
1
pref:pnq8zwpj8cq05n7pytfmskuk9r4gzzel8qtsvwz79zdskftrzxtar994cgutavfklv0vx5z0w3
C07138323E00FA4FC122D3B85B9628EA810B3F381706385E289B0B25631197D194B5C238BEB136FB
40
15
prefix:0nq8zwpj8cq05n7pytfmskuk9r4gzzel8qtsvwz79zdskftrzxtar994cgutavfklvwsvctzqy
C07138323E00FA4FC122D3B85B9628EA810B3F381706385E289B0B25631197D194B5C238BEB136FB
48
0
bitcoincash:qh3krj5607v3qlqh5c3wq3lrw3wnuxw0sp8dv0zugrrt5a3kj6ucysfz8kxwv2k53krr7n933jfsunqex2w82sl
E361CA9A7F99107C17A622E047E3745D3E19CF804ED63C5C40C6BA763696B98241223D8CE62AD48D863F4CB18C930E4C
48
1
bchtest:ph3krj5607v3qlqh5c3wq3lrw3wnuxw0sp8dv0zugrrt5a3kj6ucysfz8kxwv2k53krr7n933jfsunqnzf7mt6x
E361CA9A7F99107C17A622E047E3745D3E19CF804ED63C5C40C6BA763696B98241223D8CE62AD48D863F4CB18C930E4C
48
1
pref:ph3krj5607v3qlqh5c3wq3lrw3wnuxw0sp8dv0zugrrt5a3kj6ucysfz8kxwv2k53krr7n933jfsunqjntdfcwg
E361CA9A7F99107C17A622E047E3745D3E19CF804ED63C5C40C6BA763696B98241223D8CE62AD48D863F4CB18C930E4C
48
15
prefix:0h3krj5607v3qlqh5c3wq3lrw3wnuxw0sp8dv0zugrrt5a3kj6ucysfz8kxwv2k53krr7n933jfsunqakcssnmn
E361CA9A7F99107C17A622E047E3745D3E19CF804ED63C5C40C6BA763696B98241223D8CE62AD48D863F4CB18C930E4C
56
0
bitcoincash:qmvl5lzvdm6km38lgga64ek5jhdl7e3aqd9895wu04fvhlnare5937w4ywkq57juxsrhvw8ym5d8qx7sz7zz0zvcypqscw8jd03f
D9FA7C4C6EF56DC4FF423BAAE6D495DBFF663D034A72D1DC7D52CBFE7D1E6858F9D523AC0A7A5C34077638E4DD1A701BD017842789982041
56
1
bchtest:pmvl5lzvdm6km38lgga64ek5jhdl7e3aqd9895wu04fvhlnare5937w4ywkq57juxsrhvw8ym5d8qx7sz7zz0zvcypqs6kgdsg2g
D9FA7C4C6EF56DC4FF423BAAE6D495DBFF663D034A72D1DC7D52CBFE7D1E6858F9D523AC0A7A5C34077638E4DD1A701BD017842789982041
56
1
pref:pmvl5lzvdm6km38lgga64ek5jhdl7e3aqd9895wu04fvhlnare5937w4ywkq57juxsrhvw8ym5d8qx7sz7zz0zvcypqsammyqffl
D9FA7C4C6EF56DC4FF423BAAE6D495DBFF663D034A72D1DC7D52CBFE7D1E6858F9D523AC0A7A5C34077638E4DD1A701BD017842789982041
56
15
prefix:0mvl5lzvdm6km38lgga64ek5jhdl7e3aqd9895wu04fvhlnare5937w4ywkq57juxsrhvw8ym5d8qx7sz7zz0zvcypqsgjrqpnw8
D9FA7C4C6EF56DC4FF423BAAE6D495DBFF663D034A72D1DC7D52CBFE7D1E6858F9D523AC0A7A5C34077638E4DD1A701BD017842789982041
64
0
bitcoincash:qlg0x333p4238k0qrc5ej7rzfw5g8e4a4r6vvzyrcy8j3s5k0en7calvclhw46hudk5flttj6ydvjc0pv3nchp52amk97tqa5zygg96mtky5sv5w
D0F346310D5513D9E01E299978624BA883E6BDA8F4C60883C10F28C2967E67EC77ECC7EEEAEAFC6DA89FAD72D11AC961E164678B868AEEEC5F2C1DA08884175B
64
1
bchtest:plg0x333p4238k0qrc5ej7rzfw5g8e4a4r6vvzyrcy8j3s5k0en7calvclhw46hudk5flttj6ydvjc0pv3nchp52amk97tqa5zygg96mc773cwez
D0F346310D5513D9E01E299978624BA883E6BDA8F4C60883C10F28C2967E67EC77ECC7EEEAEAFC6DA89FAD72D11AC961E164678B868AEEEC5F2C1DA08884175B
64
1
pref:plg0x333p4238k0qrc5ej7rzfw5g8e4a4r6vvzyrcy8j3s5k0en7calvclhw46hudk5flttj6ydvjc0pv3nchp52amk97tqa5zygg96mg7pj3lh8
D0F346310D5513D9E01E299978624BA883E6BDA8F4C60883C10F28C2967E67EC77ECC7EEEAEAFC6DA89FAD72D11AC961E164678B868AEEEC5F2C1DA08884175B
64
15
prefix:0lg0x333p4238k0qrc5ej7rzfw5g8e4a4r6vvzyrcy8j3s5k0en7calvclhw46hudk5flttj6ydvjc0pv3nchp52amk97tqa5zygg96ms92w6845
D0F346310D5513D9E01E299978624BA883E6BDA8F4C60883C10F28C2967E67EC77ECC7EEEAEAFC6DA89FAD72D11AC961E164678B868AEEEC5F2C1DA08884175B
参考文献

Hi3559 sdk文件结构分析一

sdk自带两种参考设计代码,一个是dv,另一个是dashcam即运动相机,两个的代码组织结构差不多,以dv为例,编译后的烧写固件存放路径为当前reference文件下的out/(chip)_(sensor)/burn/fastboot_(flash),例如hi3559平台imx385 sensor使用spi nor flash存储的固件位于out/hi3559_imx385/burn/fastboot_spinor下面。值得注意的是burn_readme.txt中的固件烧写地址和相关描述跟实际固件布局不符,建议以out/(chip)_(sensor)/burn/fastboot_(flash)/config内容为参考。

由此我们知道有两个文件系统镜像,以spi nor存储为例,rootfs.squashfs和privatefs.jffs2,很显然前者是存放不可修改的系统相关文件和应用程序,后者是可读写的配置参数及其他文件。接下来我们很想知道最终生成的文件系统镜像是从哪里来的,通过product/hi3559/rootfs/Makefile可以看到,rootfs答案分两种情况:
1、没有配置了fastboot启动模式,则来自product/hi3559/rootfs/rootfs。
2、配置fastboot启动模式,则来自product/hi3559/rootfs/minirootfs,其中在打包之前还有将product/hi3559/rootfs/mini_rootfs_priv下所有内容拷贝到前者下面的操作。
上面两种情况的最后,还会将product/hi3559/rootfs/rootfs_priv下所有内容也拷贝到各自的文件系统系统文件夹下。对于不同的参考设计,还有特定的文件系统定制动作,详情可以看rootfs_prepare目标。

通过rootfs_prepare目标还可以看到,上面两种情况下的文件夹最开始都来自于/osdrv/pub/linux下面两个压缩文件(minirootfs.tgz和rootfs.tgz),它们经过解压到现在路径后还加入了一些删减操作以及拷贝参考设计相关编译结果拷贝进去的动作,说白了就是再标准文件系统基础上加入参考设计相关的文件。

privatefs的文件夹则来源于product/hi3559/rootfs/privatefs,这个文件夹很简单只有一个null空文件,这个文件夹实际上也是编译时用脚本生成的,看一看privatefs_prepare目标就知道了,用户可以在这里添加自己产品需要的文件进去。

通过简单grep可以找到主程序文件就是:product/hi3559/init_master/hi_product_init_main.c

未完待续…

建立Hi3559 开发环境须知

操作系统:CentOS7.4 minimal
SDK版本:Hi3559V100R003C02SPC009

建立开发环境步骤在此不表,文档《Hi3559V100/Hi3556V100 SDK安装使用说明.pdf》已经介绍很详细了,只是它针对的平台是ubuntu14.04 64bit server,不过我要把它安装到centos系统上,并且是最小系统,很多软件包都没有,当然基本的C/C++开发工具(gcc/g++/make/autoconf/gdb)还是有的。既然在最小系统上编译这么庞大的软件代码难免会遇到各种各样问题,这种心理准备我是有的,本着兵来将挡水来土掩的心态处之即可。这两天实际操作过程中果不其然遇到了动态库找不到情况,还好通过yum解决了,具体问题不表,现将解决方法介绍如下:
1、下载安装bc、ncurse开发包、glibc-static包:
yum install bc ncurses-devel glibc-static -y
2、替换默认的3.82版本make为3.81,由于yum无法降级make,只能下载源码编译然后替换/usr/bin/make。

这里要特别说明一下第二步操作原因,如果不做这个降级处理,在执行osdrv/tools/pc/mkimage_tool/fastboot下Makefile时报错:Makefile:517: *** mixed implicit and normal rules. Stop.具体代码片段:
platform.mk \
%: %_config
$(MAKE)

根据以往经验,这一定时make工具版本太新或太旧造成的,具体是哪个最近版本才支持就只能通过二分判断法来找寻答案了,结果升级到最新的4.2不行,试着降级到3.80也不行,最后降级到3.81才解析通过,看来海思编写编译脚本的高手对3.81版make规则运用很娴熟,问题是为什么这个规则的出现前无古人后无来者呢?

编译安卓版Hi3798M固件

1、准备工作参见《Android解决方案-开发指南.pdf》文档。
2、解压HiSTBAndroidV600R001C00SPC060压缩文件到一个文件夹,本文用android取名指代。
3、解压HiSTBAndroidV600R001C00SPC062压缩文件,并把解压后的文件拷贝覆盖到android下面,然后执行clean.sh脚本。
4、解压HiSTBAndroidV600R001C00SPC063压缩文件,并把解压后的文件拷贝覆盖到android下面,然后执行clean.sh脚本。
5、进入android文件夹,执行:
source build/envsetup.sh
lunch Hi3798MV100-eng
make bigfish 2>&1 | tee bigfish.log
进入漫长的编译过程。

编译过程会遇到如下三个问题:
1、内核刚开始编译时提示几个新配置选择后退出,解决办法是:将device/hisilicon/bigfish/sdk/source/kernel/linux-3.10.y/arch/arm/configs/hi3798mv100_android_defconfig中添加:
CONFIG_ARM_HAS_SG_CHAIN=y
# CONFIG_MTD_NAND_HIFMC100_NAND is not set
# CONFIG_MTD_SPINAND_HIFMC100 is not set
然后重新make

2、recovery内核岗开始编译时提示几个新配置选择后退出,解决办法是:将device/hisilicon/bigfish/sdk/source/kernel/linux-3.10.y/arch/arm/configs/hi3798mv100_android_recovery_defconfig拷贝到out/target/product/Hi3798MV100/obj/RECOVERY_OBJ/.config,即:
cp device/hisilicon/bigfish/sdk/source/kernel/linux-3.10.y/arch/arm/configs/hi3798mv100_android_recovery_defconfig out/target/product/Hi3798MV100/obj/RECOVERY_OBJ/.config
然后重新make

3、编译链接libwebviewchromium.so动态库时长时间停滞不动甚至退出编译,这是内存不够用的表现,解决办法是添加交换分区:
export SWAPFILE=/mnt/swapfile
dd if=/dev/zero of=$SWAPFILE bs=1024 count=4194304
mkswap $SWAPFILE
chmod 600 $SWAPFILE
swapon $SWAPFILE
立即生效,不用重新make

设置Centos7 时区

查看时间及时区:
timedatectl

列举所有时区:
timedatectl list-timezones

设置时区:
timedatectl set-timezone Asia/Hong_Kong

也可将/etc/localtime 文件链接到/usr/share/zoneinfo下面的指定时区文件达到设置时区目的,如:
ln -s /usr/share/zoneinfo/Asia/Hong_Kong /etc/localtime

配置nginx 地址rewrite

折腾博客时发现点开所有博客链接都是404 错误,很明显是rewrite 问题。解决办法是在nginx 配置文件中顶层location 下添加如下重写规则:
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
然后重启nginx 服务即可。