Transaction format metaverse transactions are mostly the same as Bitcoin
, Only the transaction Output is extended with attachment.
ref. https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch06.asciidoc#transactions
Transaction Exactly the same as Bitcoin
uint32_t version; uint32_t locktime; input::list inputs; output::list outputs;
0 : null version 1 : first version 2 : check output script 3 : nova special testnet transaction (only for some tx can't pass validation) 4 : nova transaction
Genesis transaction
version is recommend to 0.Coinbase transaction
version is recommend to 1.Coinstake transaction
version is recommend to 2.All the other transactions'
version are recommend to the latest version (at present 4).
NOTICE:
Do not use the transaction version to judge the transaction’s kind. For example, use version 0 to judge a transaction is a genesis transaction, or use version 1 to judge a transaction is a coinbase transaction.
If a transaction version >= 2, then the validation will check if all its outputs script pattern is standard. If has unkown script pattern, the transaction can not pass validation.
void transaction::to_data(writer& sink) const { sink.write_4_bytes_little_endian(version); sink.write_variable_uint_little_endian(inputs.size()); for (const auto& input: inputs) input.to_data(sink); sink.write_variable_uint_little_endian(outputs.size()); for (const auto& output: outputs) output.to_data(sink); sink.write_4_bytes_little_endian(locktime); }
Transaction Input Exactly the same as Bitcoin
ref. https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch06.asciidoc#transaction-inputs
hash_digest hash; // 32 bytes uint32_t index; chain::script script; uint32_t sequence;
void input::to_data(writer& sink) const { sink.write_hash(hash); sink.write_4_bytes_little_endian(index); script.to_data(sink, true); sink.write_4_bytes_little_endian(sequence); }
Transaction Output Mostly the same as Bitcoin
. Extent with an attachment data for metaverse extended functions (Asset, Cert, DID, MIT, etc).
Please see Output-attachment for more info.
uint64_t value; chain::script script; chain::attachment attachment; // Extended field
sink.write_8_bytes_little_endian(value); script.to_data(sink, true); attachment.to_data(sink);
Script Almost the same as Bitcoin
ref. https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch06.asciidoc#transaction-scripts-and-script-language
Except the following difference:
OP_CHECKATTENUATIONVERIFY has op code of 178 (newly added for Asset lock ) OP_CHECKSEQUENCEVERIFY has op code of 179 (while Bitcoin is 178 )
add pay_blackhole_address
(for Burn transaction ) add pay_key_hash_with_attenuation_model
(for Asset lock transaction )
operation::stack operations; // vector of operation struct operation { opcode code; std::vector<uint8_t> data; }
// prefix is true in signing void script::to_data(writer& sink, bool prefix) const { if (prefix) sink.write_variable_uint_little_endian(satoshi_content_size()); if ((operations.size() > 0) && (operations[0].code == opcode::raw_data)) { operations[0].to_data(sink); } else { for (const auto& op: operations) op.to_data(sink); } }
Output attachment
uint32_t version; uint32_t type; std::string todid; std::string fromdid; boost::variant< etp, etp_award, // unused asset, blockchain_message, did, asset_cert, asset_mit > attach;
1 : normal 207 : did related
0 : etp 1 : etp_award // unused 2 : asset 3 : message 4 : did 5 : asset_cert 6 : asset_mit
void attachment::to_data_t(writer& sink) const { sink.write_4_bytes_little_endian(version); sink.write_4_bytes_little_endian(type); if (version == 207) { sink.write_string(todid); sink.write_string(fromdid); } attach.to_data(sink); // visit boost::variant }
etp
attachmentEmpty. Nothing to serialize.
asset
attachment
uint32_t status; // 1 for issue, 2 for transfer boost::variant<asset_detail, asset_transfer> data;
void asset::to_data(writer& sink) const { sink.write_4_bytes_little_endian(status); data.to_data(sink); // visit boost::variant }
1. asset_detail
std::string symbol; // < 64 bytes uint64_t maximum_supply; uint8_t decimal_number; uint8_t secondaryissue_threshold; uint8_t unused2; uint8_t unused3; std::string issuer; // < 64 bytes std::string address; // < 64 bytes std::string description; // < 64 bytes
void asset_detail::to_data(writer& sink) const { sink.write_string(symbol); sink.write_8_bytes_little_endian(maximum_supply); sink.write_byte(decimal_number); sink.write_byte(secondaryissue_threshold); sink.write_byte(unused2); sink.write_byte(unused3); sink.write_string(issuer); sink.write_string(address); sink.write_string(description); }
2. asset_transfer
std::string symbol; // < 64 bytes uint64_t quantity; // = 8 bytes
void asset_transfer::to_data(writer& sink) const { sink.write_string(symbol); sink.write_8_bytes_little_endian(quantity); }
blockchain_message
attachment
std::string content; // < 253 bytes
void message::to_data(writer& sink) const { sink.write_string(content); }
did
attachment
uint32_t status; // 1 for register, 2 for transfer std::string symbol; // < 64 bytes std::string address; // < 64 bytes
void did::to_data(writer& sink) const { sink.write_4_bytes_little_endian(status); sink.write_string(symbol); sink.write_string(address); }
asset_cert
attachment
std::string symbol; // < 64 bytes std::string owner; // < 64 bytes std::string address; // < 64 bytes uint32_t cert_type; // = 4 bytes uint8_t status; // = 1 byte std::string content; // < 64 bytes
1 : issue 2 : domain 3 : naming 0x60000004 : mining 5 : witness 0x80000000 : marriage 0x80000001 : kyc
void asset_cert::to_data(writer& sink) const { sink.write_string(symbol); sink.write_string(owner); sink.write_string(address); sink.write_4_bytes_little_endian(cert_type); sink.write_byte(status); if (has_content()) { // only write in issuing *mining* asset cert sink.write_string(content); } }
asset_mit
attachment
uint8_t status. // 1 for register, 2 for transfer std::string symbol; // < 64 bytes std::string address; // < 64 bytes std::string content; // < 256 bytes
void asset_mit::to_data(writer& sink) const { sink.write_byte(status); sink.write_string(symbol); sink.write_string(address); if (is_register_status()) { // don't write in transfer case sink.write_string(content); } }
Transaction signing Exactly the same as Bitcoin
ref. https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch06.asciidoc#digital-signatures-ecdsa
Signing use RPC API First install and run a metaverse full node. ref. https://mvs.org/wallet.html and https://docs.mvs.org/docs/
ref. https://docs.mvs.org/api_v3/rawtx.html
use createrawtx
to create metaverse raw transaction
use decoderawtx
to decode raw transaction to json string
use signrawtx
to sign raw transaction
use sendrawtx
to broadcast signed transaction
You can combine the above APIs to check and verify your own implementation of creating and signing metaverse transaction.