Home - 首页     Blog - 博客     Brain Wallet - 脑钱包

I think JavaScript conforms to the spirit of open source and is very suitable for developing Bitcoin related applications. JavaScript has good portability and does not require the installation of specialized development software. It can be developed and debugged with a browser. This webpage code (right-click to view the source code) is very suitable for beginners to understand the basic principles of Bitcoin from a code level. Simply save this webpage to run it offline and use it as a brain wallet or cold wallet. It is recommended to use Chrome browser.


我认为JavaScript符合开源精神,很适合用于开发比特币相关应用。JavaScript可移植性好,无需安装专门的开发软件,有个浏览器即可进行开发调试。本网页代码(右键查看源代码)很适合初学者从代码层面理解比特币的基本原理。只需要保存本网页即可脱机运行,可当做脑钱包或冷钱包使用,建议用Chrome浏览器。

Brain Entropy - 脑熵
【Source - 源】

The brain regulations must include hash values and require replacement or cropping modifications to the hash values. For example, it can be set as: BrainPassword1+X(SHA256(BrainPassword2))+Y(SHA256(SHA256(BrainPassword3))+… Among them, X() and Y() are modifications to the hash value.


脑规则中必须包括哈希值,且需要对哈希值进行替换或裁剪修改。例如可以设置成:脑口令1+X(SHA256(脑口令2))+Y(SHA256(SHA256(脑口令3)))+...,其中X()、Y()即对哈希值的修改。





【Entropy - 熵】



【Mnemonic - 助记词】


【Mnemonic Entropy - 助记词熵】

Entropy of mnemonic words: The entropy of 12 mnemonic words is taken from the first 32 bits of 【Entropy】, and the entropy of 24 mnemonic words is taken from the first 64 bits of 【Entropy】.


助记词熵:12个助记词的熵取自【熵】的前32位,24个助记词的熵取自【熵】的前64位。


English Mnemonic Words - 英文助记词

Chinese Mnemonic Words - 中文助记词

Private Key - 私钥
【Private Key - 私钥】

Almost all 64 bit hex strings can be used as private keys. The range of values for legitimate private keys is (0,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)


几乎所有的64位16进制字符串都可以作为私钥。合法私钥的取值范围(0,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)。





【Private Key Version - 私钥版本号】

0x80(Main Net - 主网),0xef(Test Net - 测试网)



【Compressed Private Key Flag - 压缩私钥标识位】

0x01 - Compressed Private Key, Empty Value - Uncompressed Private Key.


0x01代表压缩私钥,空值代表非压缩私钥.








【Private Key Checksum - 私钥校验码】

Add the version number prefix and compression flag suffix to the private key, and then perform SHA256 twice (before SHA256 each time, the hexadecimal string needs to be converted to 256 bytes, rather than directly hashing the hexadecimal string twice), taking the first 4 bytes.


私钥加上版本号前缀和压缩标志位后缀,再进行两次SHA256后(每次在SHA256之前,需要先将16进制字符串转换成256进制即字节形式,而不是直接对16进制字符串进行两次哈希),取头部4个字节。






【Base58Check encoded private key - Base58Check编码私钥】


Public Key - 公钥

压缩公钥:前缀(如果y是偶数,前缀是02;如果y是奇数,前缀是03)+X坐标(32字节);未压缩公钥:前缀(04)+X坐标(32字节)+Y坐标(32字节)。


Compressed public key: Prefix (if y is even, prefix is 02; if y is odd, prefix is 03)+X coordinate (32 bytes); Uncompressed public key: Prefix (04)+X coordinate (32 bytes)+Y coordinate (32 bytes).




Address - 地址


【Address(Public Key Hash) - 地址(公钥哈希)】


【Address Version - 地址版本号】

0x00 - Main Net; 0x6f - Test Net.


0x00 - 主网;0x6f - 测试网。








【Address Checksum - 地址校验码】

Add the version number prefix to the address, and then perform SHA256 twice (before SHA256 each time, the hexadecimal string needs to be converted to 256 bytes, rather than directly hashing the hexadecimal string twice), taking the first 4 bytes.


地址加上版本号前缀,再进行两次SHA256后(每次在SHA256之前,需要先将16进制字符串转换成256进制即字节形式,而不是直接对16进制字符串进行两次哈希),取头部4个字节。






【Base58Check Encoded Address - Base58Check编码地址】


构造交易并签名
【网络类型】


【发币地址】

余额来源

余额(BTC)



UTXO来源


输入用于构造交易的UTXO的序号或序号范围,用英文逗号隔开,例如:1,4-10,12

所选UTXO的余额之和(BTC)



【收币地址】

1、对于有找零的情况,找零地址默认是发币地址!


2、如果填的是公钥,则锁定脚本是P2PK。

收币金额(BTC)


【矿工手续费(BTC)】


【绝对时间锁】

=0(表示不锁定),<5亿(表示区块绝对高度),>=5亿(表示时间,单位是秒)。交易只能在等于或大于该区块值或1970年1月1日0点+lock_time秒之后的时间点,才被网络接受。




【JSON交易串】

1、交易hash(tid):(1)不包括HashType;(2)对于witness交易,不包括witnessFlag(0x0001)和witness签名部分。


2、sequence:相对时间锁(详细说明见BIP-0068),通常设为最大值0xffffffff(十进制4294967295)。要想启用locktime,输入中至少一个input的sequence要小于2^31(即最高位为0)。


3、锁定脚本:


(1)P2PK:OPCODE_LEN pubKey OP_CHECKSIG(0xac);


(2)P2PKH:OP_DUP(0x76) OP_HASH160(0xa9) OPCODE_LEN pubKeyHash OP_EQUALVERIFY(0x88) OP_CHECKSIG(0xac);


(3)P2MS(M-N多重签名):OP_M OPCODE_LEN pubKey_1 OPCODE_LEN pubKey_2 … OPCODE_LEN pubKey_N OP_N OP_CHECKMULTISIG(0xae);


(4)P2SH:OP_HASH160(0xa9) OPCODE_LEN redeemScriptHash OP_EQUAL(0x87);


——用P2SH可以实现各类交易,其redeemScript与各类交易的锁定脚本相同,解锁脚本均以redeemScript结尾。


(4.1)P2SH-P2PK的redeemScript:OPCODE_LEN pubKey OP_CHECKSIG(0xac);


(4.2)P2SH-P2PKH的redeemScript:OP_DUP(0x76) OP_HASH160(0xa9) OPCODE_LEN pubKeyHash OP_EQUALVERIFY(0x88) OP_CHECKSIG(0xac);


(4.3)P2SH-P2MS(M-N多重签名)的redeemScript:OP_M OPCODE_LEN pubKey_1 OPCODE_LEN pubKey_2 … OPCODE_LEN pubKey_N OP_N OP_CHECKMULTISIG(0xae);


(4.4)P2SH-P2WPKH的redeemScript:VER(0x00) OPCODE_LEN(0x14) pubKeyHash;


(4.5)P2SH-P2WSH的redeemScript:VER(0x00) OPCODE_LEN(0x20) P2WSHredeemScriptHash;


——P2WSHredeemScriptHash是P2WSHredeemScript的sha256值,而不是hash160值。


(5)P2WPKH:VER(0x00) OPCODE_LEN(0x14) pubKeyHash。


(6)P2WSH:VER(0x00) OPCODE_LEN(0x20) redeemScriptHash。


4、锁定脚本中的OPCODE_LEN在JSON格式中未体现,但在Raw格式中有体现。


5、P2WPKH锁定脚本中的前导“0”,是隔离见证程序的版本号,可以按OP_0(0x00)解析。


6、OP_EQUALVERIFY = OP_EQUAL + OP_VERIFY,其中OP_EQUAL会把判断结果(true:1或false:0)推入栈,OP_VERIFY弹出栈中的结果,进行判断后,不再推入栈。P2PKH使用OP_EQUALVERIFY,目的是弹出true(1),接着执行OP_CHECKSIG;P2SH使用OP_EQUAL,是因为P2SH是分两个阶段执行的,执行第二阶段(执行反序列的redeem_script)前,需要判断第一阶段的执行结果。


7、由于隔离见证签名时,需要用到input金额,所以把金额附加到了JSON格式的最后面。




【签名哈希类型(SIGHASH flags)】

1、签名哈希类型(4bytes):


(1)ALL(1):这是默认的签名类型,对交易的所有输入和输出签名;


(2)NONE(2):只对交易的所有输入签名,不对输出签名,同时将非签名所在输入的sequence置为0;


(3)SINGLE(3):对交易的所有输入签名,只对与签名所在输入具有相同索引值的输出签名,同时将非签名所在输入的sequence置为0;


(4)ANYONECANPAY(128,即0x80):输入只保留签名所在输入,属于可选属性(默认不使用),该属性不单独使用;


(5)ALL | ANYONECANPAY(129,即0x81):ALL与ANYONECANPAY的组合;


(6)NONE | ANYONECANPAY(130,即0x82):NONE与ANYONECANPAY的组合;


(7)SINGLE | ANYONECANPAY(131,即0x83):SINGLE与ANYONECANPAY的组合。


2、SIGHASH flags(4bytes)转换成小端编码后(0x01000000等),附加到Raw交易串的最后面,一起被签名。


3、每个输入在其解锁脚本中包含一个签名。因此,包含多个输入的交易可以拥有具有不同SIGHASH标志的多个签名,这些标志在每个输入中承诺交易的不同部分。



【3开头地址的锁定脚本类型】

对于发币地址是3开头(p2sh)的地址,因为无法通过锁定脚本中的“赎回脚本哈希值”,来判断锁定类型,所以需要用户选择锁定脚本类型(默认是P2SH-P2WPKH,即内嵌式单签名隔离见证地址)。由于带有隔离见证和没有隔离见证的RAW格式是不一样的,所以需要提前知道是否存在隔离见证input。




【Raw交易串(待签名)】

1、序列化顺序:version:4bytes(小端编码); witnessFlag:4bytes(marker:0x00,flag:0x01)(大端编码); tx_in_count:varint(大); tx_hash:32bytes(小); index:4bytes(小); script_length:varint(大); script:string(大); squence:4bytes(小); tx_out_count:varint(大); value:8bytes(小); script_length:varint(大); script:string(大); witness:string(大); locktime:4bytes(小); hashtype:4bytes(小)


(1)对于非隔离见证交易,witnessFlag和witness都不存在;


(2)witness序列化顺序;stack_items_num:varint; item_1_length:varint; item_1:string; item_2_length:varint; item_2:string; … item_n_length:varint; item_n:string;


——每个input对应一个witness item,对于非隔离见证input,只有stack_item_num,且为0x00。


2、下面的Raw交易串是由上面的JSON全量转换得到,包含了签名需要的全部信息,但不能直接用来签。


(2.1)非隔离见证交易,用于签名的序列化规则:


(1)ALL(1):在签名某个input之前,需要将其他input的script置空,script_length为0。


(2)NONE(2):input部分:在签名某个input之前,需要将其他input的script置空,script_length为0,sequence置为0;output部分:将output置空,tx_out_length为0。


(3)SINGLE(3):input部分:在签名某个input之前,需要将其他input的script置空,script_length为0,sequence置为0;output部分:低于与签名相同index的output被置空,即value置为-1(等价置为0xffffffffffffffff,因为其与-1互为补码),script置空,script_length置为0;高于与签名相同index的output被删除。特殊情况:当input数量大于output数量时,对于“多余”的input,直接对0x0000000000000000000000000000000000000000000000000000000000000001签名。


(4)与ANYONECANPAY组合使用:input部分:只保留需要签名的input,即tx_in_length值为1;output部分:与上面相同。


(2.2)隔离见证交易(WitnessV0),用于签名的序列化规则:


(2.2.1)ALL(1):


(1)nVersion of the transaction (4-byte little endian)


(2)hashPrevouts (32-byte hash)


(3)hashSequence (32-byte hash)


(4)outpoint (32-byte hash + 4-byte little endian)


(5)scriptCode of the input (serialized as scripts inside CTxOuts)


(6)value of the output spent by this input (8-byte little endian)


(7)nSequence of the input (4-byte little endian)


(8)hashOutputs (32-byte hash)


(9)nLocktime of the transaction (4-byte little endian)


(10)sighash type of the signature (4-byte little endian)


【非常重要】对于P2WPKH和P2SH-P2WPKH,scriptCode填充的是脚本长度+P2PKH;对于P2WSH和P2SH-P2WSH,scriptCode填充的是脚本长度+隔离见证脚本。


(2.2.2)与ANYONECANPAY组合使用:hashPrevouts置为0000000000000000000000000000000000000000000000000000000000000000


(2.2.3)与ANYONECANPAY组合使用、NONE或者SINGLE:hashSequence置为0000000000000000000000000000000000000000000000000000000000000000


(2.2.4)(NONE)或者(SINGLE且output高于签名所在index):hashOutputs置为0000000000000000000000000000000000000000000000000000000000000000


3、待签名的Raw交易串中已包含SIGHASH flag。


4、由于隔离见证签名时,需要用到input金额,所以把金额附加到了RAW格式的最后面。




【发币私钥】


【Raw交易串(已签名)】

1、签名信息串后面会附带上“签名哈希类型”(占1个字节)。


2、签名格式:


(1)P2PK:OPCODE_LEN Signature;


(2)P2PKH:OPCODE_LEN Signature OPCODE_LEN pubKey;


(3)P2MS(M-N多重签名):OP_0 OPCODE_LEN Signature_1 OPCODE_LEN Signature_2 … OPCODE_LEN Signature_M OPCODE_LEN redeemScript;


(4)P2SH:


——用P2SH可以实现各类交易,其redeemScript与各类交易的锁定脚本相同,解锁脚本是各类交易的解锁脚本+redeemScript。


(4.1)P2SH-P2PK:OPCODE_LEN Signature OPCODE_LEN redeemScript;


——其中redeemScript:OPCODE_LEN pubKey OP_CHECKSIG(0xac);


(4.2)P2SH-P2PKH:OPCODE_LEN Signature OPCODE_LEN pubKey OPCODE_LEN redeemScript;


——其中redeemScript:OP_DUP(0x76) OP_HASH160(0xa9) OPCODE_LEN pubKeyHash OP_EQUALVERIFY(0x88) OP_CHECKSIG(0xac);


(4.3)P2SH-P2MS(M-N多重签名):OP_0 OPCODE_LEN Signature_1 OPCODE_LEN Signature_2 … OPCODE_LEN Signature_M OPCODE_LEN redeemScript;


——这里多出的OP_0是由于OP_CHECKMULTISIG的bug导致的,实际要弹出的参数数量比想要弹出的多1个;


——其中redeemScript:OP_M OPCODE_LEN pubKey_1 OPCODE_LEN pubKey_2 … OPCODE_LEN pubKey_N OP_N OP_CHECKMULTISIG(0xae);


(4.4)P2SH-P2WPKH:OPCODE_LEN redeemScript;


——其中redeemScript:VER(0x00) OPCODE_LEN(0x14) pubKeyHash;


——witness:stack_item_num(varint:0x02) signature_length(varint) Signature pubkey_length(varint:0x21) pubKey;


(4.5)P2SH-P2WSH:OPCODE_LEN redeemScript;


——其中redeemScript:VER(0x00) OPCODE_LEN(0x20) P2WSHredeemScriptHash;


——P2SH-P2WSH-P2MS的P2WSHredeemScript:OP_M OPCODE_LEN pubKey_1 OPCODE_LEN pubKey_2 … OPCODE_LEN pubKey_N OP_N OP_CHECKMULTISIG(0xae);


——P2SH-P2WSH-P2MS的witness:stack_item_num(varint:1+M+1) OP_0 signature_1_length(varint) signature_1 signature_2_length(varint) Signature_2 … signature_M_length(varint) Signature_M P2WSHredeemScript_length(varint) P2WSHredeemScript;


(5)P2WPKH:空(script_length:0x00,在raw中体现);


——witness:stack_item_num(varint:0x02) signature_length(varint) Signature pubkey_length(varint:0x21) pubKey;


(6)P2WSH:空(script_length:0x00,在raw中体现);


——P2WSH-P2MS的witness:stack_item_num(varint:1+M+1) OP_0 signature_1_length(varint) signature_1 signature_2_length(varint) Signature_2 … signature_M_length(varint) Signature_M P2WSHredeemScript_length(varint) P2WSHredeemScript;




【广播交易】

主网广播地址:https://blockstream.info/tx/push


测试网广播地址:https://blockstream.info/testnet/tx/push

验证签名
【信息】

这里只支持对16进制的信息进行签名和验证。如果您提供的信息不是16进制的,可以通过进制转换或通过哈希函数将待签名信息转换成16进制信息,再进行签名。




【WIF格式私钥】


【签名】

1.实际上是对待签名的双哈希值SHA256(hexToBytes(SHA256(hexToBytes(待签名信息))))进行签名。


2.为了安全,签名时引入了随机数,对同一信息进行签名时,每次签名值都发生变化,但每个签名值都是有效的。





【公钥】


【验证签名】