A Beginner's Guide to Bitcoin Blockchain Development (Part 4) - Practical Multi-Signature Transactions

A Beginner's Guide to Bitcoin Blockchain Development (Part 4) - Practical Multi-Signature Transactions

This article uses the bitcoin testnet as the development test environment and combines Node.js to implement the identity registration function of the PPkPub open source project ODIN as a specific application case to illustrate how to use multi-signature transactions to embed custom data and broadcast it after signing. After being confirmed by the miner node and stored in the blockchain, it can finally be read and parsed to obtain the registration result, thus realizing a complete process from writing to reading from the blockchain.


1. Understand the definition of ODIN open identifier

As the first open source project released by the PPkPub open group, ODIN is the abbreviation of Open Data Index Name . In a broad sense, ODIN refers to an open system for identifying and exchanging data content indexes in a network environment. It complies with the URI (Uniform Resource Identifier) ​​specification and provides an extensible framework for autonomous, open, secure and reliable data content management and intellectual property management based on the digital cryptocurrency blockchain (BlockChain). It includes 4 components: identifiers, resolution systems, metadata and policies. In a narrow sense, ODIN refers to a permanent open identifier that identifies any data content object.

ODIN can be figuratively understood as the "autonomous domain name in the data age". It is a completely open and decentralized naming and identification system based on the Bitcoin blockchain and is scalable and compatible with more blockchains. Compared with traditional DNS domain names, it has more innovative features and can be well applied to emerging fields such as big data, smart devices and the Internet of Things.

With reference to the technical principles of digital cryptocurrencies such as XCP (Contract Coin) and Mastercoin, ODIN is implemented by encoding specific message data according to the Bitcoin protocol specifications, broadcasting it to the Bitcoin network as a Bitcoin transaction and storing it in the blockchain.

Each ODIN message includes the following characteristics:
(a) A Bitcoin source address (corresponding to the ODIN message generator)

(b) A Bitcoin destination address (corresponding to the target individual pointed to by the ODIN message. When the message generator and the target individual pointed to by the message are the same, this address is empty)

(c) Several 1-of-N multi-signature output Bitcoin address public keys (generated by encoding in the ODIN data packet. When actually generating a transaction, 32 bytes are extracted from the ODIN setting data in sequence, and 1 byte corresponding to the length of the string is added to the front of the 32 bytes. A total of 33 bytes correspond to a Bitcoin public key. If the number is less than 33 bytes, binary 0s are automatically appended to the end until it reaches exactly 33 bytes, corresponding to a compressed public key)

(d) There is a certain amount of Bitcoin balance in the Bitcoin source address (it is recommended to have more than 0.001 BTC to generate several valid transaction entries sent from the source address to the destination address to be embedded in the ODIN data packet. Note: Due to the characteristics of Bitcoin 1-of-N multi-signature transactions, these Bitcoin amounts will not be actually spent and will be recycled in the next ODIN message)

(e) A fixed fee for the message cost in Bitcoin (default is 0.0001 BTC), which will be paid to the Bitcoin network miner who includes this transaction data block.

(f) a Bitcoin change address (the same as the Bitcoin source address in the first item above, used to recover the excess amount of the Bitcoin input transaction after generating several transaction entries that meet the requirements of embedding the ODIN data packet to the sender's account in accordance with the Bitcoin transaction protocol)

The above feature (c) is the key to the implementation of the technology. The ODIN data block will be embedded in the multi-signature output data block of the Bitcoin transaction, which is a 1-of-N output. The first public key of each data block is fixed to the sender, so the output currency value can be redeemed and recycled. The address space storing the second to Nth public keys is used to store the encoded ODIN message data. For detailed description of Bitcoin multi-signature transactions, please refer to the Bitcoin protocol specification.
Note: N is recommended not to exceed 10. For ODIN data blocks that cannot be accommodated by one 1-of-10 multi-signature output, they can be expanded and stored in the second, third, and other multi-signature output records.

The format of each ODIN information data block is defined in byte order as follows:

Bytes 1-32: Prefix feature identifier, 32-byte ASCII string "P2P is future! ppkpub.org->ppk:0" (excluding double quotes on both sides)

Byte 33: Message type, 1 byte.

The 34th byte to the end of the message is different message data distinguished by message type. For details, see the definition in the specific ODIN message type.

Note: For easy identification, each ODIN message is prefixed with a 32-byte ASCII string "P2P is future! ppkpub.org->ppk:0" (without the quotation marks on both sides). This string is very long, so it is impossible to confuse ODIN-specific transactions with other Bitcoin transactions.
2. Example analysis of registering ODIN logo on blockchain

The following is the specific message definition for "newly registered ODIN identifier" in the ODIN protocol:
——————————————————————————————————
Newly registered ODIN logo

Bitcoin source address: corresponds to the ODIN identifier registrant Bitcoin destination address: corresponds to the ODIN identifier owner

The format of the message data block is defined in byte order as follows:
Bytes 1-32: Prefix feature identifier, 32-byte ASCII string "P2P is future! ppkpub.org->ppk:0" (excluding double quotes on both sides)
Byte 33: Message type, 1 byte, value is ASCII character R
Byte 34: Message body data format, 1 byte.
Value definition: ASCII character,
T means "UTF-8 encoded text string",
G means "binary data compressed by the gzip algorithm, which needs to be decompressed to obtain the original text string encoded in UTF-8"
Bytes 35-36: Byte length of the message body data, 2 bytes of unsigned short integer binary data, with a value range of 0-65535.
The message body data from the 37th byte to the end of the specified length of the message body is stored in bytes. The original message text needs to be obtained according to the data format of the 34th byte. It is a UTF-8 encoded JSON format string corresponding to a JSON object data, as described below:
{
"title":"Description: Individual name string",
"email":"Description: Individual public EMAIL, optional",
"auth":"Description: Configure permissions, see the comment below for value definitions",
"ap_list":["Description: URL array of several data access points AP, at least one must be filled in",...,"xxxx"],
"catalog":"Description: Data source type, optional reserved fields, to be supplemented"
}

Note: Configuration permission value description: ASCII character 0, 1 or 2
0 means "either the registrant or the owner can modify the owner's related information",
1 means "only the registrant can modify the owner's related information",
2 means "The registrant and the owner must confirm together before the owner's related information can be modified".

——————————————————————————————————

Assume that there is the following example of ODIN identification registration information:
{"title":"PPk-ODIN-sample","email":"[email protected]","auth":"2","ap_list":["http://ppkpub.org/AP/"]}

Then, according to the above message definition, it can be assembled into a Bitcoin transaction record to be broadcast to the Bitcoin network for effectiveness. The original data of the corresponding transaction is as follows (the original binary data is output in hexadecimal ASCII code format by byte for easy analysis):
01000000032237b858f1a697cc2d26a451bd3fd3ef1944eb53f579b4fac38e5ecb5c0fc42c010000006b483045022100da55
a2d9f97695db12aecc0113662437957a6d4f17064ff49602ddc39904c31302201e81eae0c84f25019485ae4a2ce9b67c0e84
85599df87ab876b469e3cbbd24100121022e9f31292873eee495ca9744fc410343ff373622cca60d3a4c926e58716114b9ff
ffffff2ef89686bebf72bd31b8f27780223f7b5f448d0110b6fdda19595a073f42a301000000006b483045022100d49360fa
6bd45b92a068127db31c9cfd93af87543799968a5b076c2fea151f9b0220647900f5fc763f5a3eed13d382e13a3bddd15646
867b56f1be9d2629b2ccb4360121022e9f31292873eee495ca9744fc410343ff373622cca60d3a4c926e58716114b9ffffff
ffd704b1c1977cd50be182134b18fafaa16db1e917dfe4f93bcab1584aabf323d4010000006b483045022100fb88f75cae8a
ccfe969cd89afbca677ff78a4914f5f506d6e5d481baf484e9f2022039f560414ec5a778a19565f7fe9e51b6acf7b841b4ba
2188785a5bb6051d7d510121022e9f31292873eee495ca9744fc410343ff373622cca60d3a4c926e58716114b9ffffffff03
7d160000000000001976a91451a09d25106715f09a14cac6367c3f4f2408590d88ac7d16000000000000cf5121022e9f3129
2873eee495ca9744fc410343ff373622cca60d3a4c926e58716114b9212050325020697320667574757265212070706b7075
622e6f72672d3e70706b3a302120525400657b227469746c65223a2250506b2d4f44494e2d73616d706c65222c222120656d
61696c223a2270706b70756240676d61696c2e636f6d222c22617574682221203a2232222c2261705f6c697374223a5b2268
7474703a2f2f70706b7075622e6f210972672f41502f225d7d000000000000000000000000000000000000000000000056ae
e6cac223000000001976a914391ef5239da2a3904cda1fd995fb7c4377487ea988ac00000000
The above message can be decomposed into fields according to the protocol rules as follows:

01000000 // Version number, UINT32

03 // Number of Tx inputs, variable length INT. 0×03 = 3 inputs.

/*** Next is the first group of Input Tx ***/
2237b858f1a697cc2d26a451bd3fd3ef1944eb53f579b4fac38e5ecb5c0fc42c // Hash value of Tx transaction, fixed at 32 bytes
01000000 // The consumed Tx is located at the 0th forward transaction output, UINT32, fixed 4 bytes
6b // Next is the length of the corresponding signature data, 0x6b = 107 bytes.
// This 107-byte signature contains two parts: private key signature + public key.
// When the value here is 00, it means the original transaction has not been signed yet
48 // The data length corresponding to the private key signature, 0×48 = 72 bytes
3045022100da55a2d9f97695db12aecc0113662437957a6d4f17064ff49602ddc39904c31302201e
81eae0c84f25019485ae4a2ce9b67c0e8485599df87ab876b469e3cbbd241001 //Private key signature content
21 // Corresponding public key data length, 0×21 = 33 bytes
022e9f31292873eee495ca9744fc410343ff373622cca60d3a4c926e58716114b9 //Corresponding public key data
ffffffff // Serial number, UINT32, fixed 4 bytes. This field is a transaction replacement function that is currently not used, and is set to 0xFFFFFFFF by default

/*** The second group of Input Tx. Same as above, omitting the decomposition***/
2ef89686bebf72bd31b8f27780223f7b5f448d0110b6fdda19595a073f42a301000000006b483045
022100d49360fa6bd45b92a068127db31c9cfd93af87543799968a5b076c2fea151f9b0220647900
f5fc763f5a3eed13d382e13a3bddd15646867b56f1be9d2629b2ccb4360121022e9f31292873eee4
95ca9744fc410343ff373622cca60d3a4c926e58716114b9ffffffff

/*** The third group of Input Tx. Same as above, omitting the decomposition***/
d704b1c1977cd50be182134b18fafaa16db1e917dfe4f93bcab1584aabf323d4010000006b483045
022100fb88f75cae8accfe969cd89afbca677ff78a4914f5f506d6e5d481baf484e9f2022039f560
414ec5a778a19565f7fe9e51b6acf7b841b4ba2188785a5bb6051d7d510121022e9f31292873eee4
95ca9744fc410343ff373622cca60d3a4c926e58716114b9ffffffff
03 // Tx output transaction quantity, variable length INT type. 0×03=3 outputs.

/*** The first group of output ***/
7d16000000000000 //Amount of bitcoins output, UINT64, 8 bytes. The byte order needs to be flipped to get 0x000000000000167d = 5757 satoshi = 0.00005757 BTC
19 // Output description script byte count, 0×19 = 25 bytes, consisting of some operation codes and values
76 //Script start operation 0×76 represents OP_DUP (copy the top element of the stack)
a9 //Address type 0xa9 represents OP_HASH160 (the top item of the stack is hashed twice, first with SHA-256 and then with RIPEMD-160)
14 //Address length 0×14 = 20 bytes
51a09d25106715f09a14cac6367c3f4f2408590d //HASH160 value corresponding to the ODIN identifier owner address, 20 bytes
88 //0×88 represents OP_EQUALVERIFY (run the script's binary arithmetic and condition, if the result is 0, then run OP_VERIFY)
ac //Oxac stands for OP_CHECKSIG (the signature used in the transaction must be a valid signature of the hash value and public key, if true, it returns 1)

/*** The second group of output ***/
7d16000000000000 //Amount of bitcoins output, UINT64, 8 bytes. The byte order needs to be flipped.
cf // Output description script byte count, 0xcf = 207 bytes, consisting of some opcodes and values
51 //Ox51 represents OP_1 (push script code 1 into the stack)
21 //The data length of the first public key pushed into the stack, 0×21 = 33 bytes. Corresponding to the public key of the registrant address identified by ODIN
022e9f31292873eee495ca9744fc410343ff373622cca60d3a4c926e58716114b9
21 //The data length of the second public key pushed into the stack. The ODIN identification message content is embedded starting from the second public key
2050325020697320667574757265212070706b7075622e6f72672d3e70706b3a30
21 //The data length of the third public key pushed into the stack
20525400657b227469746c65223a2250506b2d4f44494e2d73616d706c65222c22
21 //The data length of the fourth public key pushed into the stack
20656d61696c223a2270706b70756240676d61696c2e636f6d222c226175746822
21 //The data length of the fifth public key pushed into the stack
203a2232222c2261705f6c697374223a5b22687474703a2f2f70706b7075622e6f
21 //The data length of the sixth public key pushed into the stack
0972672f41502f225d7d0000000000000000000000000000000000000000000000
56 //Ox56 represents OP_6 (pushing script code 6 onto the stack). Together with the previous 0×51, it represents 1of6 multi-signature
ae //Oxae represents OP_CHECKMULTISIG (perform multi-signature verification)

/*** The third group of output ***/
e6cac22300000000 //Amount of bitcoins output, UINT64, 8 bytes. The byte order needs to be flipped.
19 // Output description script byte count, 0×19 = 25 bytes, consisting of some operation codes and values
76 //Script start operation 0×76 represents OP_DUP (copy the top element of the stack)
a9 //Address type 0xa9 represents OP_HASH160 (the top item of the stack is hashed twice, first with SHA-256 and then with RIPEMD-160)
14 //Address length 0×14 = 20 bytes
391ef5239da2a3904cda1fd995fb7c4377487ea9 // Corresponding HASH160 value, 20 bytes
88 //0×88 represents OP_EQUALVERIFY (run the script's binary arithmetic and condition, if the result is 0, then run OP_VERIFY)
ac //Oxac stands for OP_CHECKSIG (the signature used in the transaction must be a valid signature of the hash value and public key, if true, it returns 1)

00000000 // Lock time, UINT32, fixed 4 bytes

Combined with the ODIN protocol definition content described above, the corresponding ODIN identification registration message can be restored and parsed through the blue area in the above transaction data.

3. Run the sample program

The sample program consists of two parts:
1. OdinMonitorTestnet.js:
Monitor changes in blockchain data related to the Bitcoin test network Testnet and parse out the newly registered ODIN logo.
The source code can be downloaded from here: http://ppkpub.org/sample/OdinMonitorTestnet.js

2. OdinRegisterTestnet.js:
Register a new ODIN identity on the Bitcoin testnet.
The source code can be downloaded from here: http://ppkpub.org/sample/OdinRegisterTestnet.js

Download the sample code above and save it to a test environment where Node.js is installed (the saved files are named OdinRegisterTestnet.js and OdinMonitorTestnet.js).
Regarding how to install the Node.js test environment, if necessary, you can refer to the instructions in "Bitcoin Blockchain Development from Beginner to Advanced Guide 1" for installation (http://www.8btc.com/blockchain_develope_lesson_1).

Before running the above sample program, please make sure that the Docker runtime environment of the Bitcoin test network (bitcoin-testnet) has been installed. If it has not been installed, you can refer to the instructions in the "Bitcoin Blockchain Development Guide from Beginners to Advanced 2" to install it (http://www.8btc.com/ppkpub_blockchain_develope_lesson_2).

Open a new text terminal window in the Node.js development and testing environment, and enter the following command in the command line to start the monitoring sample program:
node OdinMonitorTestnet.js

Then open a new text terminal window and enter the following command in the command line to run the registration sample program:
node OdinRegisterTestnet.js

After running the registration sample program, enter "make generate BLOCKS=6" in the command line of the Docker runtime environment of the Bitcoin test network (bitcoin-testnet) to simulate the generation of new block records. The newly generated transaction records will be effectively confirmed and stored in the blockchain. At this time, the monitoring program's running interface will prompt that the new ODIN identifier registration record has been parsed (as shown in the figure below).


<<:  Let’s talk about comics: Who is the man behind the blockchain?

>>:  Ethereum co-founder Taylor Gerring: Hard forks can make the network more resilient

Recommend

What is the fate of a man with a crooked mouth?

In physiognomy, we can also analyze a person'...

How men can analyze their fortune by palmistry

It is said that a man cannot be poor. If a man ha...

About Filecoin's four major implementations

Unlike most blockchain projects that only have on...

Why do people say that beautiful women have protruding ears?

Many people may think that most beautiful women h...

What kind of boys have lustful faces?

Everyone has physiological needs, but some people...

What is your persistence in life?

What is your persistence in life? Everyone is per...

What will be the impact of spots on the servant palace?

From the perspective of physiognomy, no matter wh...

What does Lu Cun in the Husband and Wife Palace represent?

In ancient times, the Palace of Marriage was also...

BTC Fear and Greed Index shows great anxiety. Can it create a new trend in July?

From the surge to $60,000 at the beginning of the...

What fortunes are good for women with thick and large earlobes?

Sometimes, we can see the development of our fort...

What does a mole next to the mouth mean for men and women?

The mouth is the most important part of a person....