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浏览器。
The brain regulations must include hash values and require replacement or cropping modifications to the hash values. For example, it can be set as: SHA256(SHA256(index)+X(SHA512(I))+Y(RIPEMD160(Love))+Z(Keccak256(Bitcoin)))+...) Among them, X(), Y() and Z() are modifications to the hash value.
脑规则中必须包括哈希值,且需要对哈希值进行替换或裁剪修改。例如可以设置成:SHA256(SHA256(序号)+X(SHA512(I))+Y(RIPEMD160(Love)))+Z(Keccak256(Bitcoin))+...),其中X()、Y()和Z()即对哈希值的修改。
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位。
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)。
0x80(Main Net - 主网),0xef(Test Net - 测试网)
0x01 - Compressed Private Key, Empty Value - Uncompressed Private Key.
0x01代表压缩私钥,空值代表非压缩私钥.
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个字节。
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).
压缩公钥:前缀(如果y是偶数,前缀是02;如果y是奇数,前缀是03)+X坐标(32字节);未压缩公钥:前缀(04)+X坐标(32字节)+Y坐标(32字节)。
0x00 - Main Net; 0x6f - Test Net.
0x00 - 主网;0x6f - 测试网。
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个字节。
Balance Source - 余额来源
Balance - 余额(BTC)
UTXO Source - UTXO来源
Enter the sequence number or range of UTXOs used to construct transactions, separated by commas in English, for example: 1,4-10,12.>
输入用于构造交易的UTXO的序号或序号范围,用英文逗号隔开,例如:1,4-10,12
The sum of the balances of the selected UTXO(BTC)
所选UTXO的余额之和(BTC)
1. For situations where there is change, the default change address is the issuing address!
2. If the public key is filled in, the locking script is P2PK.
1.对于有找零的情况,找零地址默认是发币地址!
2.如果填的是公钥,则锁定脚本是P2PK。
Received Amount - 收币金额(BTC)
默认将交易所有输入的nSequence设置成相同值0xfffffffd(2^32 - 3 = 4294967293),既激活了RBF(Replace-By-Fee)功能,当给的手续费比较低导致交易迟迟无法被打包,可以再重新发起一笔更高收费的交易来替换掉先前广播的低手续费交易;又激活了绝对时间锁(nLockTime),可用于构建用于遗产继承的交易字符串。如果想设置成不同值,手动在JSON交易字符串中修改。
相对时间锁(nSequence)和绝对时间锁(nLockTime)的互锁关系:
(1)如果交易中的所有输入(UTXO)的nSequence都等于0xffffffff(2^32 - 1 = 4294967295):不激活nSequence,也不激活nLockTime(交易设置的nLockTime将会被忽略,即绝对时间锁无效)。
(2)如果交易中有一个或多个输入的nSequence小于0xffffffff,且大于等于0x80000000(2^31 = 2147483648):不激活nSequence,只激活nLockTime。
(3)如果交易中有一个或多个输入的nSequence小于0x80000000:激活nSequence,也激活nLockTime。
locktime生效的前提条件:交易中至少有一个输入(UTXO)的sequence < 0xffffffff(2^32 - 1 = 4294967295)。locktime = 0(表示不锁定),<5亿(表示区块绝对高度),>=5亿(表示时间,单位是秒)。交易只能在等于或大于该区块值或1970年1月1日0点+lock_time秒之后的时间点,才被网络接受。
1、交易hash(tid):(1)不包括HashType;(2)对于witness交易,不包括witnessFlag(0x0001)和witness签名部分。
2、锁定脚本:
(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格式的最后面。
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开头(p2sh)的地址,因为无法通过锁定脚本中的“赎回脚本哈希值”,来判断锁定类型,所以需要用户选择锁定脚本类型(默认是P2SH-P2WPKH,即内嵌式单签名隔离见证地址)。由于带有隔离见证和没有隔离见证的RAW格式是不一样的,所以需要提前知道是否存在隔离见证input。
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格式的最后面。
The default private key can be used to simulate signatures to confirm whether the transaction fee is reasonable. - 默认私钥可用于模拟签名,来确认手续费是否合理。
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;
Fee(手续费): sat/vB
合理手续费查询:https://bitcoinfees.net
Mainnet Broadcast URL - 主网广播地址:https://blockstream.info/tx/push
Testnet Broadcast URL -测试网广播地址:https://blockstream.info/testnet/tx/push
This only supports signing and verifying hexadecimal information. If the information you provide is not in hexadecimal, you can convert the information to be signed into hexadecimal through binary conversion or hash function before signing.
这里只支持对16进制的信息进行签名和验证。如果您提供的信息不是16进制的,可以通过进制转换或通过哈希函数将待签名信息转换成16进制信息,再进行签名。
1. Actually, it is to sign the double hash value SHA256 (hexTobytes (SHA256 (hexTobytes) to be signed). 2. For security reasons, random numbers are introduced during the signature process. When signing the same information, the signature value changes every time, but each signature value is valid.
1.实际上是对待签名的双哈希值SHA256(hexToBytes(SHA256(hexToBytes(待签名信息))))进行签名。2.为了安全,签名时引入了随机数,对同一信息进行签名时,每次签名值都发生变化,但每个签名值都是有效的。
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)。
public key: X coordinate (32 bytes)+Y coordinate (32 bytes).
公钥:X坐标(32字节)+Y坐标(32字节)。
0x + taking the last 20 bytes of pubKey Hash.
0x + 公钥哈希的后20字节。
Regard the address as a string (excluding the leading '0x') and perform a Keccak hash operation
将地址看成字符串(不包括开头的0x),并进行Keccak哈希运算
Ethereum implicitly adds checksums by introducing uppercase letters to prevent accidentally entering incorrect addresses. The rule is: (1) First, treat the address as a string (excluding the starting '0x'), and calculate the Keccak value; (2) If the value of the i-th bit of the Keccak value is ≥ 8, then the i-th bit of the address is changed to uppercase letters.
以太坊通过引入大写字母来隐含加入校验和,防止不小心输错地址。其规则是:(1)先将地址看成字符串(不包括开头的0x),并计算Keccak值;(2)如果Keccak值的第i位的值≥8,那么地址的第i位改成大写字母。